.. _using:

========================================================
:mod:`!importlib.metadata` -- Accessing package metadata
========================================================

.. module:: importlib.metadata
   :synopsis: Accessing package metadata

.. versionadded:: 3.8
.. versionchanged:: 3.10
   ``importlib.metadata`` is no longer provisional.

**Source code:** :source:`Lib/importlib/metadata/__init__.py`

``importlib.metadata`` is a library that provides access to
the metadata of an installed `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package>`_,
such as its entry points
or its top-level names (`Import Package <https://packaging.python.org/en/latest/glossary/#term-Import-Package>`_\s, modules, if any).
Built in part on Python's import system, this library
intends to replace similar functionality in the `entry point
API`_ and `metadata API`_ of ``pkg_resources``. Along with
:mod:`importlib.resources`,
this package can eliminate the need to use the older and less efficient
``pkg_resources`` package.

``importlib.metadata`` operates on third-party *distribution packages*
installed into Python's ``site-packages`` directory via tools such as
:pypi:`pip`.
Specifically, it works with distributions with discoverable
``dist-info`` or ``egg-info`` directories,
and metadata defined by the `Core metadata specifications <https://packaging.python.org/en/latest/specifications/core-metadata/#core-metadata>`_.

.. important::

   These are *not* necessarily equivalent to or correspond 1:1 with
   the top-level *import package* names
   that can be imported inside Python code.
   One *distribution package* can contain multiple *import packages*
   (and single modules),
   and one top-level *import package*
   may map to multiple *distribution packages*
   if it is a namespace package.
   You can use :ref:`packages_distributions() <package-distributions>`
   to get a mapping between them.

By default, distribution metadata can live on the file system
or in zip archives on
:data:`sys.path`. Through an extension mechanism, the metadata can live almost
anywhere.


.. seealso::

   https://importlib-metadata.readthedocs.io/
      The documentation for ``importlib_metadata``, which supplies a
      backport of ``importlib.metadata``.
      This includes an `API reference
      <https://importlib-metadata.readthedocs.io/en/latest/api.html>`__
      for this module's classes and functions,
      as well as a `migration guide
      <https://importlib-metadata.readthedocs.io/en/latest/migration.html>`__
      for existing users of ``pkg_resources``.


Overview
========

Let's say you wanted to get the version string for a
`Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package>`_ you've installed
using ``pip``. We start by creating a virtual environment and installing
something into it:

.. code-block:: shell-session

    $ python -m venv example
    $ source example/bin/activate
    (example) $ python -m pip install wheel

You can get the version string for ``wheel`` by running the following:

.. code-block:: pycon

    (example) $ python
    >>> from importlib.metadata import version  # doctest: +SKIP
    >>> version('wheel')  # doctest: +SKIP
    '0.32.3'

You can also get a collection of entry points selectable by properties of the EntryPoint (typically 'group' or 'name'), such as
``console_scripts``, ``distutils.commands`` and others. Each group contains a
collection of :ref:`EntryPoint <entry-points>` objects.

You can get the :ref:`metadata for a distribution <metadata>`::

    >>> list(metadata('wheel'))  # doctest: +SKIP
    ['Metadata-Version', 'Name', 'Version', 'Summary', 'Home-page', 'Author', 'Author-email', 'Maintainer', 'Maintainer-email', 'License', 'Project-URL', 'Project-URL', 'Project-URL', 'Keywords', 'Platform', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Requires-Python', 'Provides-Extra', 'Requires-Dist', 'Requires-Dist']

You can also get a :ref:`distribution's version number <version>`, list its
:ref:`constituent files <files>`, and get a list of the distribution's
:ref:`requirements`.


.. exception:: PackageNotFoundError

   Subclass of :class:`ModuleNotFoundError` raised by several functions in this
   module when queried for a distribution package which is not installed in the
   current Python environment.


Functional API
==============

This package provides the following functionality via its public API.


.. _entry-points:

Entry points
------------

.. function:: entry_points(**select_params)

   Returns a :class:`EntryPoints` instance describing entry points for the
   current environment. Any given keyword parameters are passed to the
   :meth:`!select` method for comparison to the attributes of
   the individual entry point definitions.

   Note: to query for entry points based on :attr:`!EntryPoint.dist` attribute,
   use :meth:`Distribution.entry_points` instead (as different :class:`Distribution`
   instances do not currently compare equal, even if they have the same attributes)

.. class:: EntryPoints

   Details of a collection of installed entry points.

   Also provides a ``.groups`` attribute that reports all identified entry
   point groups, and a ``.names`` attribute that reports all identified entry
   point names.

.. class:: EntryPoint

   Details of an installed entry point.

   Each :class:`!EntryPoint` instance has ``.name``, ``.group``, and ``.value``
   attributes and a ``.load()`` method to resolve the value. There are also
   ``.module``, ``.attr``, and ``.extras`` attributes for getting the
   components of the ``.value`` attribute, and ``.dist`` for obtaining
   information regarding the distribution package that provides the entry point.

Query all entry points::

    >>> eps = entry_points()  # doctest: +SKIP

The :func:`!entry_points` function returns a :class:`!EntryPoints` object,
a collection of all :class:`!EntryPoint` objects with ``names`` and ``groups``
attributes for convenience::

    >>> sorted(eps.groups)  # doctest: +SKIP
    ['console_scripts', 'distutils.commands', 'distutils.setup_keywords', 'egg_info.writers', 'setuptools.installation']

:class:`!EntryPoints` has a :meth:`!select` method to select entry points
matching specific properties. Select entry points in the
``console_scripts`` group::

    >>> scripts = eps.select(group='console_scripts')  # doctest: +SKIP

Equivalently, since :func:`!entry_points` passes keyword arguments
through to select::

    >>> scripts = entry_points(group='console_scripts')  # doctest: +SKIP

Pick out a specific script named "wheel" (found in the wheel project)::

    >>> 'wheel' in scripts.names  # doctest: +SKIP
    True
    >>> wheel = scripts['wheel']  # doctest: +SKIP

Equivalently, query for that entry point during selection::

    >>> (wheel,) = entry_points(group='console_scripts', name='wheel')  # doctest: +SKIP
    >>> (wheel,) = entry_points().select(group='console_scripts', name='wheel')  # doctest: +SKIP

Inspect the resolved entry point::

    >>> wheel  # doctest: +SKIP
    EntryPoint(name='wheel', value='wheel.cli:main', group='console_scripts')
    >>> wheel.module  # doctest: +SKIP
    'wheel.cli'
    >>> wheel.attr  # doctest: +SKIP
    'main'
    >>> wheel.extras  # doctest: +SKIP
    []
    >>> main = wheel.load()  # doctest: +SKIP
    >>> main  # doctest: +SKIP
    <function main at 0x103528488>

The ``group`` and ``name`` are arbitrary values defined by the package author
and usually a client will wish to resolve all entry points for a particular
group. Read `the setuptools docs
<https://setuptools.pypa.io/en/latest/userguide/entry_point.html>`_
for more information on entry points, their definition, and usage.

.. versionchanged:: 3.12
   The "selectable" entry points were introduced in ``importlib_metadata``
   3.6 and Python 3.10. Prior to those changes, ``entry_points`` accepted
   no parameters and always returned a dictionary of entry points, keyed
   by group. With ``importlib_metadata`` 5.0 and Python 3.12,
   ``entry_points`` always returns an ``EntryPoints`` object. See
   :pypi:`backports.entry_points_selectable`
   for compatibility options.

.. versionchanged:: 3.13
   ``EntryPoint`` objects no longer present a tuple-like interface
   (:meth:`~object.__getitem__`).

.. _metadata:

Distribution metadata
---------------------

.. function:: metadata(distribution_name)

   Return the distribution metadata corresponding to the named
   distribution package as a :class:`PackageMetadata` instance.

   Raises :exc:`PackageNotFoundError` if the named distribution
   package is not installed in the current Python environment.

.. class:: PackageMetadata

   A concrete implementation of the
   `PackageMetadata protocol <https://importlib-metadata.readthedocs.io/en/latest/api.html#importlib_metadata.PackageMetadata>`_.

   In addition to providing the defined protocol methods and attributes, subscripting
   the instance is equivalent to calling the :meth:`!get` method.

Every `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package>`_
includes some metadata, which you can extract using the :func:`!metadata` function::

    >>> wheel_metadata = metadata('wheel')  # doctest: +SKIP

The keys of the returned data structure name the metadata keywords, and
the values are returned unparsed from the distribution metadata::

    >>> wheel_metadata['Requires-Python']  # doctest: +SKIP
    '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'

:class:`PackageMetadata` also presents a :attr:`!json` attribute that returns
all the metadata in a JSON-compatible form per :PEP:`566`::

    >>> wheel_metadata.json['requires_python']
    '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'

The full set of available metadata is not described here.
See the PyPA `Core metadata specification <https://packaging.python.org/en/latest/specifications/core-metadata/#core-metadata>`_ for additional details.

.. versionchanged:: 3.10
   The ``Description`` is now included in the metadata when presented
   through the payload. Line continuation characters have been removed.

   The ``json`` attribute was added.


.. _version:

Distribution versions
---------------------

.. function:: version(distribution_name)

   Return the installed distribution package
   `version <https://packaging.python.org/en/latest/specifications/core-metadata/#version>`__
   for the named distribution package.

   Raises :exc:`PackageNotFoundError` if the named distribution
   package is not installed in the current Python environment.

The :func:`!version` function is the quickest way to get a
`Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package>`_'s version
number, as a string::

    >>> version('wheel')  # doctest: +SKIP
    '0.32.3'


.. _files:

Distribution files
------------------

.. function:: files(distribution_name)

   Return the full set of files contained within the named
   distribution package as :class:`PackagePath` instances.

   Raises :exc:`PackageNotFoundError` if the named distribution
   package is not installed in the current Python environment.

   Returns :const:`None` if the distribution is found but the installation
   database records reporting the files associated with the distribution package
   are missing.

.. class:: PackagePath

    A :class:`pathlib.PurePath` derived object with additional ``dist``,
    ``size``, and ``hash`` properties corresponding to the distribution
    package's installation metadata for that file, also:

    .. method:: locate()

       If possible, return the concrete :class:`SimplePath` allowing to access data,
       or raise a :exc:`NotImplementedError` otherwise.

.. class:: SimplePath

    A protocol representing a minimal subset of :class:`pathlib.Path` that allows to
    check if it ``exists()``, to traverse using ``joinpath()`` and ``parent``,
    and to retrieve data using ``read_text()`` and ``read_bytes()``.

The :func:`!files` function takes a
`Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package>`_
name and returns all of the files installed by this distribution. For example::

    >>> util = [p for p in files('wheel') if 'util.py' in str(p)][0]  # doctest: +SKIP
    >>> util  # doctest: +SKIP
    PackagePath('wheel/util.py')
    >>> util.size  # doctest: +SKIP
    859
    >>> util.dist  # doctest: +SKIP
    <importlib.metadata._hooks.PathDistribution object at 0x101e0cef0>
    >>> util.hash  # doctest: +SKIP
    <FileHash mode: sha256 value: bYkw5oMccfazVCoYQwKkkemoVyMAFoR34mmKBx8R1NI>

Once you have the file, you can also read its contents::

    >>> print(util.read_text())  # doctest: +SKIP
    import base64
    import sys
    ...
    def as_bytes(s):
        if isinstance(s, text_type):
            return s.encode('utf-8')
        return s

You can also use the :meth:`!locate` method to get the absolute
path to the file::

    >>> util.locate()  # doctest: +SKIP
    PosixPath('/home/gustav/example/lib/site-packages/wheel/util.py')

In the case where the metadata file listing files
(``RECORD`` or ``SOURCES.txt``) is missing, :func:`!files` will
return :const:`None`. The caller may wish to wrap calls to
:func:`!files` in `always_iterable
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.always_iterable>`_
or otherwise guard against this condition if the target
distribution is not known to have the metadata present.

.. _requirements:

Distribution requirements
-------------------------

.. function:: requires(distribution_name)

   Return the declared dependency specifiers for the named
   distribution package.

   Raises :exc:`PackageNotFoundError` if the named distribution
   package is not installed in the current Python environment.

To get the full set of requirements for a `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package>`_,
use the :func:`!requires`
function::

    >>> requires('wheel')  # doctest: +SKIP
    ["pytest (>=3.0.0) ; extra == 'test'", "pytest-cov ; extra == 'test'"]


.. _package-distributions:
.. _import-distribution-package-mapping:

Mapping import to distribution packages
---------------------------------------

.. function:: packages_distributions()

   Return a mapping from the top level module and import package
   names found via :data:`sys.meta_path` to the names of the distribution
   packages (if any) that provide the corresponding files.

   To allow for namespace packages (which may have members provided by
   multiple distribution packages), each top level import name maps to a
   list of distribution names rather than mapping directly to a single name.

A convenience method to resolve the `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package>`_
name (or names, in the case of a namespace package)
that provide each importable top-level
Python module or `Import Package <https://packaging.python.org/en/latest/glossary/#term-Import-Package>`_::

    >>> packages_distributions()
    {'importlib_metadata': ['importlib-metadata'], 'yaml': ['PyYAML'], 'jaraco': ['jaraco.classes', 'jaraco.functools'], ...}

Some editable installs, `do not supply top-level names
<https://github.com/pypa/packaging-problems/issues/609>`_, and thus this
function is not reliable with such installs.

.. versionadded:: 3.10

.. _distributions:

Distributions
=============

While the module level API described above is the most common and convenient usage,
all that information is accessible from the :class:`Distribution` class.
:class:`!Distribution` is an abstract object that represents the metadata for
a Python `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package>`_.
Get the concrete :class:`!Distribution` subclass instance for an installed
distribution package by calling the :func:`distribution` function::

    >>> from importlib.metadata import distribution  # doctest: +SKIP
    >>> dist = distribution('wheel')  # doctest: +SKIP
    >>> type(dist)  # doctest: +SKIP
    <class 'importlib.metadata.PathDistribution'>

.. function:: distribution(distribution_name)

   Return a :class:`Distribution` instance describing the named
   distribution package.

   Raises :exc:`PackageNotFoundError` if the named distribution
   package is not installed in the current Python environment.

Thus, an alternative way to get e.g. the version number is through the
:attr:`Distribution.version` attribute::

    >>> dist.version  # doctest: +SKIP
    '0.32.3'

The same applies for :func:`entry_points` and :func:`files`.

.. class:: Distribution

   Details of an installed distribution package.

   Note: different :class:`!Distribution` instances do not currently compare
   equal, even if they relate to the same installed distribution and
   accordingly have the same attributes.

   .. staticmethod:: at(path)
   .. classmethod:: from_name(name)

      Return a :class:`!Distribution` instance at the given path or
      with the given name.

   .. classmethod:: discover(*, context=None, **kwargs)

      Returns an iterable of :class:`!Distribution` instances for all packages
      (see distribution-discovery_).

      The optional argument *context* is a :class:`DistributionFinder.Context`
      instance, used to modify the search for distributions. Alternatively,
      *kwargs* may contain keyword arguments for constructing a new
      :class:`!DistributionFinder.Context`.

   .. attribute:: metadata
      :type: PackageMetadata

      There are all kinds of additional metadata available on :class:`!Distribution`
      instances as a :class:`PackageMetadata` instance::

          >>> dist.metadata['Requires-Python']  # doctest: +SKIP
          '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
          >>> dist.metadata['License']  # doctest: +SKIP
          'MIT'

      The full set of available metadata is not described here.
      See the PyPA `Core metadata specification <https://packaging.python.org/en/latest/specifications/core-metadata/#core-metadata>`_ for additional details.

   .. attribute:: name
      :type: str
   .. attribute:: requires
      :type: list[str]
   .. attribute:: version
      :type: str

      A few metadata fields are also available as shortcut properties.

      .. versionadded:: 3.10

         The ``name`` shortcut was added.

   .. attribute:: origin

      For editable packages, an ``origin`` property may present :pep:`610`
      metadata (for non-editable packages, ``origin`` is :const:`None`)::

         >>> dist.origin.url
         'file:///path/to/wheel-0.32.3.editable-py3-none-any.whl'

      The ``origin`` object follows the `Direct URL Data Structure
      <https://packaging.python.org/en/latest/specifications/direct-url-data-structure/>`_.

      .. versionadded:: 3.13

   .. attribute:: entry_points
      :type: EntryPoints

      The entry points provided by this distribution package.

   .. attribute:: files
      :type: list[PackagePath] | None

      All files contained in this distribution package.
      Like :func:`files`, this returns :const:`None` if there are no records.

   The following two abstract methods need to be implemented when implementing-custom-providers_:

   .. method:: locate_file(path)

      Like :meth:`!PackagePath.locate`, return a :class:`SimplePath` for the given path.
      Takes a :class:`os.PathLike` or a :class:`str`.

   .. method:: read_text(filename)

      A shortcut for ``distribution.locate_file(filename).read_text()``.

.. _distribution-discovery:

Distribution Discovery
======================

By default, this package provides built-in support for discovery of metadata
for file system and zip file `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package>`_\s.
This metadata finder search defaults to ``sys.path``, but varies slightly in how it interprets those values from how other import machinery does. In particular:

- ``importlib.metadata`` does not honor :class:`bytes` objects on ``sys.path``.
- ``importlib.metadata`` will incidentally honor :py:class:`pathlib.Path` objects on ``sys.path`` even though such values will be ignored for imports.

.. class:: DistributionFinder

   A :class:`~importlib.abc.MetaPathFinder` subclass capable of discovering
   installed distributions.

   Custom providers should implement this interface in order to
   supply metadata.

    .. class:: Context(**kwargs)

       A :class:`!Context` gives a custom provider a means to
       solicit additional details from the callers of distribution discovery
       functions like :func:`distributions` or :meth:`Distribution.discover`
       beyond :attr:`!.name` and :attr:`!.path` when searching
       for distributions.

       For example, a provider could expose suites of packages in either a
       "public" or "private" ``realm``. A caller of distribution discovery
       functions may wish to query only for distributions in a particular realm
       and could call ``distributions(realm="private")`` to signal to the
       custom provider to only include distributions from that
       realm.

       Each :class:`!DistributionFinder` must expect any parameters and should
       attempt to honor the canonical parameters defined below when
       appropriate.

       See the section on :ref:`implementing-custom-providers` for more details.

       .. attribute:: name

          Specific name for which a distribution finder should match.

          A :attr:`!.name` of ``None`` matches all distributions.

       .. attribute:: path

          A property providing the sequence of directory paths that a
          distribution finder should search.

          Typically refers to Python installed package paths such as
          "site-packages" directories and defaults to :attr:`sys.path`.


.. function:: distributions(**kwargs)

   Returns an iterable of :class:`Distribution` instances for all packages.

   The *kwargs* argument may contain either a keyword argument ``context``, a
   :class:`DistributionFinder.Context` instance, or pass keyword arguments for
   constructing a new :class:`!DistributionFinder.Context`. The
   :class:`!DistributionFinder.Context` is used to modify the search for
   distributions.

.. _implementing-custom-providers:

Implementing Custom Providers
=============================

``importlib.metadata`` address two API surfaces, one for *consumers*
and another for *providers*. Most users are consumers, consuming
metadata provided by the packages. There are other use-cases, however,
where users wish to expose metadata through some other mechanism,
such as alongside a custom importer. Such a use case calls for a
*custom provider*.

Because `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package>`_ metadata
is not available through :data:`sys.path` searches, or
package loaders directly,
the metadata for a distribution is found through import
system :ref:`finders <finders-and-loaders>`. To find a distribution package's metadata,
``importlib.metadata`` queries the list of :term:`meta path finders <meta path finder>` on
:data:`sys.meta_path`.

The implementation has hooks integrated into the ``PathFinder``,
serving metadata for distribution packages found on the file system.

The abstract class :py:class:`importlib.abc.MetaPathFinder` defines the
interface expected of finders by Python's import system.
``importlib.metadata`` extends this protocol by looking for an optional
``find_distributions`` callable on the finders from
:data:`sys.meta_path` and presents this extended interface as the
:class:`DistributionFinder` abstract base class, which defines this abstract
method::

    @abc.abstractmethod
    def find_distributions(context=DistributionFinder.Context()) -> Iterable[Distribution]:
        """Return an iterable of all Distribution instances capable of
        loading the metadata for packages for the indicated ``context``.
        """

The :class:`DistributionFinder.Context` object provides
:attr:`~DistributionFinder.Context.path` and
:attr:`~DistributionFinder.Context.name` properties indicating the path to
search and name to match and may supply other relevant context sought by the
consumer.

In practice, to support finding distribution package
metadata in locations other than the file system, subclass
:class:`!Distribution` and implement the abstract methods. Then from
a custom finder, return instances of this derived :class:`!Distribution` in the
``find_distributions()`` method.

Example
-------

Imagine a custom finder that loads Python modules from a database::

    class DatabaseImporter(importlib.abc.MetaPathFinder):
        def __init__(self, db):
            self.db = db

        def find_spec(self, fullname, target=None) -> ModuleSpec:
            return self.db.spec_from_name(fullname)

    sys.meta_path.append(DatabaseImporter(connect_db(...)))

That importer now presumably provides importable modules from a
database, but it provides no metadata or entry points. For this
custom importer to provide metadata, it would also need to implement
:class:`DistributionFinder`::

    from importlib.metadata import DistributionFinder

    class DatabaseImporter(DistributionFinder):
        ...

        def find_distributions(self, context=DistributionFinder.Context()):
            query = dict(name=context.name) if context.name else {}
            for dist_record in self.db.query_distributions(query):
                yield DatabaseDistribution(dist_record)

In this way, ``query_distributions`` would return records for
each distribution served by the database matching the query. For
example, if ``requests-1.0`` is in the database, ``find_distributions``
would yield a ``DatabaseDistribution`` for ``Context(name='requests')``
or ``Context(name=None)``.

For the sake of simplicity, this example ignores ``context.path``\. The
``path`` attribute defaults to ``sys.path`` and is the set of import paths to
be considered in the search. A ``DatabaseImporter`` could potentially function
without any concern for a search path. Assuming the importer does no
partitioning, the "path" would be irrelevant. In order to illustrate the
purpose of ``path``, the example would need to illustrate a more complex
``DatabaseImporter`` whose behavior varied depending on
``sys.path``/``PYTHONPATH``. In that case, the ``find_distributions`` should
honor the ``context.path`` and only yield ``Distribution``\ s pertinent to that
path.

``DatabaseDistribution``, then, would look something like::

    class DatabaseDistribution(importlib.metadata.Distribution):
        def __init__(self, record):
            self.record = record

        def read_text(self, filename):
            """
            Read a file like "METADATA" for the current distribution.
            """
            if filename == "METADATA":
                return f"""Name: {self.record.name}
    Version: {self.record.version}
    """
            if filename == "entry_points.txt":
                return "\n".join(
                  f"""[{ep.group}]\n{ep.name}={ep.value}"""
                  for ep in self.record.entry_points)

        def locate_file(self, path):
            raise RuntimeError("This distribution has no file system")

This basic implementation should provide metadata and entry points for
packages served by the ``DatabaseImporter``, assuming that the
``record`` supplies suitable ``.name``, ``.version``, and
``.entry_points`` attributes.

The ``DatabaseDistribution`` may also provide other metadata files, like
``RECORD`` (required for :attr:`!Distribution.files`) or override the
implementation of :attr:`!Distribution.files`. See the source for more inspiration.


.. _`entry point API`: https://setuptools.readthedocs.io/en/latest/pkg_resources.html#entry-points
.. _`metadata API`: https://setuptools.readthedocs.io/en/latest/pkg_resources.html#metadata-api
