docs: improve API documentation
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
d436a4a906
commit
8d945293aa
|
@ -7,7 +7,6 @@ __pycache__
|
|||
*.pyo
|
||||
|
||||
docs/_build
|
||||
docs/api
|
||||
dist
|
||||
venv
|
||||
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
.. SPDX-FileCopyrightText: 2024 Anna <cyber@sysrq.in>
|
||||
.. SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
repology\_client.constants
|
||||
==========================
|
||||
|
||||
.. automodule:: repology_client.constants
|
||||
:members:
|
|
@ -0,0 +1,17 @@
|
|||
.. SPDX-FileCopyrightText: 2024 Anna <cyber@sysrq.in>
|
||||
.. SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
repology\_client.exceptions
|
||||
===========================
|
||||
|
||||
repology\_client.exceptions
|
||||
---------------------------
|
||||
|
||||
.. automodule:: repology_client.exceptions
|
||||
:members:
|
||||
|
||||
repology\_client.exceptions.resolve
|
||||
-----------------------------------
|
||||
|
||||
.. automodule:: repology_client.exceptions.resolve
|
||||
:members:
|
|
@ -0,0 +1,33 @@
|
|||
.. SPDX-FileCopyrightText: 2024 Anna <cyber@sysrq.in>
|
||||
.. SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
repology\_client
|
||||
================
|
||||
|
||||
repology\_client
|
||||
----------------
|
||||
|
||||
.. automodule:: repology_client
|
||||
|
||||
.. rubric:: High-level Functions
|
||||
|
||||
.. autofunction:: get_packages
|
||||
.. autofunction:: get_projects
|
||||
.. autofunction:: resolve_package
|
||||
|
||||
.. rubric:: Low-level Functions
|
||||
|
||||
.. autofunction:: api
|
||||
|
||||
repology\_client.exp
|
||||
--------------------
|
||||
|
||||
.. autodata:: exp
|
||||
|
||||
.. rubric:: High-level Functions
|
||||
|
||||
.. autofunction:: distromap
|
||||
|
||||
.. rubric:: Low-level Functions
|
||||
|
||||
.. autofunction:: api
|
|
@ -0,0 +1,8 @@
|
|||
.. SPDX-FileCopyrightText: 2024 Anna <cyber@sysrq.in>
|
||||
.. SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
repology\_client.types
|
||||
======================
|
||||
|
||||
.. automodule:: repology_client.types
|
||||
:members:
|
|
@ -0,0 +1,8 @@
|
|||
.. SPDX-FileCopyrightText: 2024 Anna <cyber@sysrq.in>
|
||||
.. SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
repology\_client.utils
|
||||
======================
|
||||
|
||||
.. automodule:: repology_client.utils
|
||||
:members:
|
14
docs/conf.py
14
docs/conf.py
|
@ -49,17 +49,17 @@ intersphinx_mapping = {
|
|||
'aiohttp': ('https://docs.aiohttp.org/en/stable', None),
|
||||
}
|
||||
|
||||
autodoc_default_flags = [
|
||||
'members',
|
||||
'show-inheritance',
|
||||
'inherited-members',
|
||||
'undoc-members',
|
||||
]
|
||||
autosummary_generate = False
|
||||
autodoc_default_options = {
|
||||
'show-inheritance': True,
|
||||
'undoc-members': True,
|
||||
'member-order': 'bysource',
|
||||
}
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
|
||||
|
||||
html_theme = 'aiohttp_theme'
|
||||
html_theme = 'alabaster'
|
||||
html_permalinks_icon = '#'
|
||||
html_theme_options = {
|
||||
'description': 'Asynchronous Python wrapper for Repology API',
|
||||
|
|
|
@ -15,7 +15,7 @@ Prerequisites
|
|||
The following dependencies are used by this library:
|
||||
|
||||
* :external+aiohttp:doc:`aiohttp <index>`
|
||||
* `pydantic`_
|
||||
* `pydantic`_ (with direct use of pydantic-core)
|
||||
|
||||
.. _pydantic: https://pydantic.dev/
|
||||
|
||||
|
|
|
@ -6,6 +6,9 @@ API Reference
|
|||
|
||||
.. autosummary::
|
||||
:toctree: api
|
||||
:recursive:
|
||||
|
||||
repology_client
|
||||
repology_client.constants
|
||||
repology_client.exceptions
|
||||
repology_client.types
|
||||
repology_client.utils
|
||||
|
|
|
@ -8,7 +8,10 @@ Release Notes
|
|||
-----
|
||||
|
||||
* **New**: :py:func:`repology_client.exp.distromap` function for
|
||||
``/api/experimental/distromap`` endpoint
|
||||
``/api/experimental/distromap`` endpoint.
|
||||
* Parse JSON with possibly faster Pydantic parser, since we already use this
|
||||
library.
|
||||
* Improve API documentation and switch to Alabaster HTML theme.
|
||||
|
||||
0.1.0
|
||||
-----
|
||||
|
|
|
@ -40,7 +40,7 @@ test = [
|
|||
"pytest-recording",
|
||||
]
|
||||
docs = [
|
||||
"aiohttp-theme",
|
||||
"alabaster",
|
||||
"sphinx",
|
||||
"sphinx-prompt",
|
||||
]
|
||||
|
|
|
@ -18,7 +18,9 @@ from repology_client._client.experimental import (
|
|||
distromap,
|
||||
)
|
||||
|
||||
#: Asynchronous wrapper for experimental endpoints of Repology API.
|
||||
exp = SimpleNamespace()
|
||||
|
||||
exp.api = api_exp
|
||||
exp.distromap = distromap
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ async def _call(location: str, params: dict | None = None, *,
|
|||
|
||||
:param location: URL location
|
||||
:param params: URL query string parameters
|
||||
:param session: :external+aiohttp:py:module:`aiohttp` client session
|
||||
:param session: :external+aiohttp:py:mod:`aiohttp` client session
|
||||
|
||||
:raises repology_client.exceptions.EmptyResponse: on empty response
|
||||
:raises aiohttp.ClientResponseError: on HTTP errors
|
||||
|
@ -49,7 +49,7 @@ async def _json_api(base_url: str, endpoint: str | None = None,
|
|||
:param base: base API URL
|
||||
:param endpoint: API endpoint
|
||||
:param params: URL query string parameters
|
||||
:param session: :external+aiohttp:py:module:`aiohttp` client session
|
||||
:param session: :external+aiohttp:py:mod:`aiohttp` client session
|
||||
|
||||
:raises repology_client.exceptions.EmptyResponse: on empty response
|
||||
:raises aiohttp.ClientResponseError: on HTTP errors
|
||||
|
|
|
@ -22,11 +22,11 @@ async def api(endpoint: str, params: dict | None = None, *,
|
|||
|
||||
:param endpoint: API endpoint (example: ``/distromap``)
|
||||
:param params: URL query string parameters
|
||||
:param session: :external+aiohttp:py:module:`aiohttp` client session
|
||||
:param session: :external+aiohttp:py:mod:`aiohttp` client session
|
||||
|
||||
:raises repology_client.exceptions.EmptyResponse: on empty response
|
||||
:raises repology_client.exceptions.InvalidInput: on invalid endpoint
|
||||
parameter
|
||||
parameter
|
||||
:raises aiohttp.ClientResponseError: on HTTP errors
|
||||
:raises json.JSONDecodeError: on JSON decode failure
|
||||
|
||||
|
@ -44,11 +44,11 @@ async def distromap(fromrepo: str, torepo: str, *,
|
|||
|
||||
:param fromrepo: first repository
|
||||
:param torepo: second repository
|
||||
:param session: :external+aiohttp:py:module:`aiohttp` client session
|
||||
:param session: :external+aiohttp:py:mod:`aiohttp` client session
|
||||
|
||||
:raises repology_client.exceptions.EmptyResponse: on empty response
|
||||
:raises repology_client.exceptions.InvalidInput: if repositories are no
|
||||
different or one of them is an empty string
|
||||
different or one of them is an empty string
|
||||
:raises aiohttp.ClientResponseError: on HTTP errors
|
||||
|
||||
:returns: decoded API response
|
||||
|
|
|
@ -31,18 +31,20 @@ async def resolve_package(repo: str, name: str,
|
|||
name into ``/api/v1/project/<project>`` project information.
|
||||
|
||||
If you disable autoresolve, ambigous package names will raise the
|
||||
:py:class:`MultipleProjectsFound` exception. It will however contain all
|
||||
matching project names, so you can continue.
|
||||
:py:class:`repology_client.exceptions.resolve.MultipleProjectsFound`
|
||||
exception. It will however contain all matching project names, so you can
|
||||
continue.
|
||||
|
||||
:param repo: repository name on Repology
|
||||
:param name: package name in the repository
|
||||
:param name_type: which name is used, "source" or "binary"
|
||||
:param autoresolve: enable automatic ambiguity resolution
|
||||
:param session: :external+aiohttp:py:mod:`aiohttp` client session
|
||||
|
||||
:raises repology_client.exceptions.resolve.MultipleProjectsFound: on
|
||||
ambigous package names when automatic resolution is disabled
|
||||
ambigous package names when automatic resolution is disabled
|
||||
:raises repology_client.exceptions.resolve.ProjectNotFound: on failed
|
||||
resolve resulting in the "404 Not Found" HTTP error
|
||||
resolve resulting in the "404 Not Found" HTTP error
|
||||
:raises aiohttp.ClientResponseError: on HTTP errors (except 404)
|
||||
:raises ValueError: on JSON decode failure
|
||||
|
||||
|
|
|
@ -30,11 +30,11 @@ async def api(endpoint: str, params: dict | None = None, *,
|
|||
|
||||
:param endpoint: API endpoint (example: ``/projects``)
|
||||
:param params: URL query string parameters
|
||||
:param session: :external+aiohttp:py:module:`aiohttp` client session
|
||||
:param session: :external+aiohttp:py:mod:`aiohttp` client session
|
||||
|
||||
:raises repology_client.exceptions.EmptyResponse: on empty response
|
||||
:raises repology_client.exceptions.InvalidInput: on invalid endpoint
|
||||
parameter
|
||||
parameter
|
||||
:raises aiohttp.ClientResponseError: on HTTP errors
|
||||
:raises ValueError: on JSON decode failure
|
||||
|
||||
|
@ -51,11 +51,11 @@ async def get_packages(project: str, *,
|
|||
single project.
|
||||
|
||||
:param project: project name on Repology
|
||||
:param session: :external+aiohttp:py:module:`aiohttp` client session
|
||||
:param session: :external+aiohttp:py:mod:`aiohttp` client session
|
||||
|
||||
:raises repology_client.exceptions.EmptyResponse: on empty response
|
||||
:raises repology_client.exceptions.InvalidInput: if ``project`` is an empty
|
||||
string
|
||||
string
|
||||
:raises aiohttp.ClientResponseError: on HTTP errors
|
||||
|
||||
:returns: set of packages
|
||||
|
@ -81,7 +81,7 @@ async def get_projects(start: str = "", end: str = "", count: int = 200, *,
|
|||
:param start: name of the first project to start with
|
||||
:param end: name of the last project to end with
|
||||
:param count: maximum number of projects to fetch
|
||||
:param session: :external+aiohttp:py:module:`aiohttp` client session
|
||||
:param session: :external+aiohttp:py:mod:`aiohttp` client session
|
||||
|
||||
:raises repology_client.exceptions.EmptyResponse: on empty response
|
||||
:raises aiohttp.ClientResponseError: on HTTP errors
|
||||
|
|
|
@ -6,29 +6,29 @@ Hardcoded constants for rapidly-changing Repology API. What could possibly go
|
|||
wrong?
|
||||
"""
|
||||
|
||||
# Library package name.
|
||||
#: Library package name.
|
||||
PACKAGE = "repology-client"
|
||||
|
||||
# Library version.
|
||||
#: Library version.
|
||||
VERSION = "0.1.0"
|
||||
|
||||
# Library homepage.
|
||||
#: Library homepage.
|
||||
HOMEPAGE = "https://repology-client.sysrq.in"
|
||||
|
||||
# Library's User-agent header
|
||||
#: Library's User-agent header
|
||||
USER_AGENT = f"Mozilla/5.0 (compatible; {PACKAGE}/{VERSION}; +{HOMEPAGE})"
|
||||
|
||||
# Base URL for API v1 requests.
|
||||
#: Base URL for API v1 requests.
|
||||
API_V1_URL = "https://repology.org/api/v1"
|
||||
|
||||
# Base URL for Experimental API requests.
|
||||
#: Base URL for Experimental API requests.
|
||||
API_EXP_URL = "https://repology.org/api/experimental"
|
||||
|
||||
# Base URL for the "Project by package name" tool.
|
||||
#: Base URL for the "Project by package name" tool.
|
||||
TOOL_PROJECT_BY_URL = "https://repology.org/tools/project-by"
|
||||
|
||||
# Maximum number of projects API can return.
|
||||
#: Maximum number of projects API can return.
|
||||
MAX_PROJECTS = 200
|
||||
|
||||
# Number of projects, starting from which you should use bulk export instead.
|
||||
#: Number of projects, starting from which you should use bulk export instead.
|
||||
HARD_LIMIT = 5_000
|
||||
|
|
|
@ -20,7 +20,14 @@ class PackageResolveException(RepologyException):
|
|||
if message is None:
|
||||
message = f"Exception occured while resolving {pkg!s}"
|
||||
super().__init__(message)
|
||||
self.pkg = pkg
|
||||
self._pkg = pkg
|
||||
|
||||
@property
|
||||
def pkg(self) -> _ResolvePkg:
|
||||
"""
|
||||
Underlying :py:class:`repology_client.types._ResolvePkg` object.
|
||||
"""
|
||||
return self._pkg
|
||||
|
||||
|
||||
class ProjectNotFound(PackageResolveException):
|
||||
|
@ -39,11 +46,18 @@ class MultipleProjectsFound(PackageResolveException):
|
|||
Raised if Repology was requested to get project by package name without
|
||||
automatic ambiguity resolution and responded with multiple results.
|
||||
|
||||
Instances of this exception contain all package names returned by Repology.
|
||||
Instances of this exception contain all project names returned by Repology.
|
||||
"""
|
||||
|
||||
def __init__(self, pkg: _ResolvePkg, names: Iterable[str]):
|
||||
message = f"Multiple projects found for {pkg!s}"
|
||||
super().__init__(pkg, message)
|
||||
|
||||
self.names = tuple(names)
|
||||
self._names = tuple(names)
|
||||
|
||||
@property
|
||||
def names(self) -> tuple[str, ...]:
|
||||
"""
|
||||
Project names returned by Repology.
|
||||
"""
|
||||
return self._names
|
||||
|
|
|
@ -10,6 +10,8 @@ from pydantic.dataclasses import dataclass
|
|||
|
||||
_DistromapPackages = tuple[str, ...]
|
||||
_DistromapGroups = tuple[_DistromapPackages, _DistromapPackages]
|
||||
|
||||
#: Intermapping of packages between two repositories.
|
||||
Distromap = tuple[_DistromapGroups, ...]
|
||||
|
||||
|
||||
|
|
|
@ -17,10 +17,11 @@ from repology_client.constants import USER_AGENT
|
|||
|
||||
class limit():
|
||||
"""
|
||||
Based on `this StackOverflow answer
|
||||
<https://stackoverflow.com/questions/35196974/aiohttp-set-maximum-number-of-requests-per-second/62503115>`_.
|
||||
Decorator to set a limit on requests per second.
|
||||
|
||||
Set a limit on requests per second.
|
||||
Based on `this StackOverflow answer`__.
|
||||
|
||||
__ https://stackoverflow.com/a/62503115/4257264
|
||||
"""
|
||||
|
||||
def __init__(self, calls: int, period: float):
|
||||
|
@ -63,7 +64,7 @@ async def ensure_session(
|
|||
"""
|
||||
Create a new client session, if necessary, and close it on exit.
|
||||
|
||||
:param session: :external+aiohttp:py:module:`aiohttp` client session
|
||||
:param session: :external+aiohttp:py:mod:`aiohttp` client session
|
||||
"""
|
||||
|
||||
keep_session = True
|
||||
|
|
Loading…
Reference in New Issue