nvchecker/docs/plugin.rst
lilydjwg 4033c0b9ba fix a typo in the docs
[skip ci]
2021-06-08 15:11:20 +08:00

97 lines
3.4 KiB
ReStructuredText

How to develop a source plugin for nvchecker
============================================
.. contents::
:local:
Source plugins enable nvchecker to discover software version strings in
additional ways.
Where to put the plugins
------------------------
They are Python modules put in any directories named ``nvchecker_source`` in
``sys.path``. This is called namespace packages introduced by `PEP 420 <https:
//www.python.org/dev/peps/pep-0420/>`_. For local use,
``~/.local/lib/pythonX.Y/site-packages/nvchecker_source`` is a good place, or
you can define the ``PYTHONPATH`` environment variable and put nvchecker source
plugins there inside a ``nvchecker_source`` directory.
Plugins are referenced by their names in the configuration file (``source = "xxx"``).
If multiple plugins have the same name, the first one in ``sys.path`` will be used.
How to write a simple plugin
----------------------------
For simple situations, you need to define an async function with the following signature::
async def get_version(
name: str, conf: Entry, *,
cache: AsyncCache, keymanager: KeyManager,
**kwargs,
) -> VersionResult:
...
Those types are imported from :mod:`nvchecker.api`.
``name`` is the table keys in the configuration file, and ``conf`` is a dict of
the content of that table. You should not modify this dict.
``cache`` is an :class:`AsyncCache <nvchecker.api.AsyncCache>` object that
caches results for you. Every plugin has its own ``cache`` object so that cache
keys won't conflict.
``keymanager`` is a :class:`KeyManager <nvchecker.api.KeyManager>` object that
you can call :meth:`.get_key(name) <nvchecker.api.KeyManager.get_key>` to get
the key (token) from the keyfile.
There may be additional keyword arguments in the future so ``**kwargs`` should be used.
If you want to send an HTTP request, it's preferred to use :meth:
`cache.get_json <nvchecker.api.AsyncCache.get_json>` or the :data:
`nvchecker.api.session` object. It will use the auto-selected HTTP backend and
handle the ``proxy`` option automatically.
For details about these objects, see :mod:`the API documentation <nvchecker.api>`,
or take existing source plugins as examples.
How to write a more powerful plugin
-----------------------------------
You may want more control in your source plugin, e.g. to do batch requests. To
do this, you provide a class instead::
class Worker(BaseWorker):
async def run(self) -> None:
...
You will have the following in the attributes::
token_q: Queue[bool],
result_q: Queue[RawResult],
tasks: List[Tuple[str, Entry]],
keymanager: KeyManager,
You are expected to process :attr:`tasks <nvchecker.api.BaseWorker.tasks>` and
put results in :attr:`result_q <nvchecker.api.BaseWorker.result_q>`. See
``nvchecker_source/none.py`` for the simplest example, and
``nvchecker_source/aur.py`` for a complete, batching example.
For details about these objects, see :mod:`the API documentation <nvchecker.api>`.
You can also receive a configuration section from the configuration as
``__config__.source.SOURCE_NAME``, where ``SOURCE_NAME`` is what your plugin is
called. This can be used to specify a mirror site for your plugin to use, e.g.
the ``npm`` plugin accepts the following config::
[__config__.source.npm]
registry = "https://registry.npm.taobao.org"
When such a configuration exists for your plugin, you need to define a function
named ``configure`` to receive it::
def configure(config):
'''use the "config" dict in some way'''
...