docs: переход на MkDocs + mkdocstrings для HTML документации

Рефакторинг:
- OtherAPI упразднён — все методы перемещены в KworkClient
- Методы client.get_wants(), get_kworks_status() и др. теперь напрямую в клиенте
- Удалён property client.other

Документация:
- MkDocs + mkdocstrings + Material theme для HTML сайта
- Навигация, поиск, форматирование кода
- docs/index.md — quick start guide
- docs/api/*.md — API reference с автогенерацией из docstrings
- Pre-commit hook для автогенерации HTML

Зависимости:
- Добавлены: mkdocs, mkdocs-material, mkdocstrings, mkdocstrings-python
- Убран pydoc-markdown (не нужен)

Команды:
- mkdocs build — сборка HTML
- mkdocs serve — локальный просмотр
This commit is contained in:
root 2026-03-23 04:35:58 +00:00
parent bdd44dd990
commit 127e5927bc
14 changed files with 642 additions and 244 deletions

3
.gitignore vendored
View File

@ -1,2 +1,5 @@
site/ site/
api_reference.md api_reference.md
__pycache__/
*.pyc
site/

46
WIP.md
View File

@ -43,35 +43,49 @@
## 📝 Заметки ## 📝 Заметки
### Автогенерация документации (2026-03-23 04:28) ### Автогенерация документации (2026-03-23 04:35)
**Инструмент:** pydoc-markdown **Инструмент:** MkDocs + mkdocstrings + Material theme
**Структура:** **Структура:**
``` ```
docs/ docs/
├── api_reference.md # Auto-generated from docstrings ├── index.md # Quick start guide
├── api-reference.md # API overview
├── api/
│ ├── client.md # KworkClient documentation
│ ├── models.md # Pydantic models
│ └── errors.md # Exception classes
└── examples.md # Usage examples
site/ # Generated HTML (не коммитим)
├── index.html
├── api-reference/
└── ...
``` ```
**Конфигурация:** **Конфигурация:**
- `pydoc-markdown.yml` — конфигурация генерации - `mkdocs.yml` — MkDocs конфигурация
- Pre-commit hook — автогенерация при коммите - Pre-commit hook — автогенерация HTML при коммите
**Покрытие документацией:** **Покрытие документацией:**
- `KworkClient` — класс, __init__, login(), все API группы - `KworkClient` — класс, аутентификация, все методы
- `CatalogAPI` — get_list(), get_details(), get_details_extra() - `CatalogAPI`каталог кворков
- `ProjectsAPI` — get_list(), get_payer_orders(), get_worker_orders() - `ProjectsAPI`биржа проектов
- `UserAPI` — get_info(), get_reviews(), get_favorite_kworks() - `UserAPI`пользовательские данные
- `ReferenceAPI`все методы (cities, countries, features, badges...) - `ReferenceAPI`справочники
- `NotificationsAPI`все методы (list, fetch, dialogs...) - `NotificationsAPI`уведомления
- `OtherAPI` — все методы (wants, settings, offline...) - `client.get_*()` — настройки и предпочтения (бывший OtherAPI)
- `models.py` — все 20+ моделей - `models.py` — все модели
- `errors.py` — все 7 исключений - `errors.py` — все исключения
**Команды:** **Команды:**
```bash ```bash
# Ручная генерация # Сборка HTML документации
pydoc-markdown > docs/api_reference.md mkdocs build
# Локальный просмотр
mkdocs serve
``` ```
### Аудит эндпоинтов (2026-03-23 03:08) ### Аудит эндпоинтов (2026-03-23 03:08)

9
docs/api-reference.md Normal file
View File

@ -0,0 +1,9 @@
# API Reference
Complete API documentation for Kwork API client.
## Modules
- [Client](api/client.md) — Main client class and API groups
- [Models](api/models.md) — Pydantic models for API responses
- [Errors](api/errors.md) — Exception classes

3
docs/api/client.md Normal file
View File

@ -0,0 +1,3 @@
# Client API
::: kwork_api.client.KworkClient

5
docs/api/errors.md Normal file
View File

@ -0,0 +1,5 @@
# Errors
Exception classes for API errors.
::: kwork_api.errors

5
docs/api/models.md Normal file
View File

@ -0,0 +1,5 @@
# Models
Pydantic models for API responses.
::: kwork_api.models

97
docs/index.md Normal file
View File

@ -0,0 +1,97 @@
# Kwork API — Python Client
Unofficial Python client for Kwork.ru API.
## Installation
```bash
pip install kwork-api
```
Or with UV:
```bash
uv add kwork-api
```
## Quick Start
### Login with credentials
```python
from kwork_api import KworkClient
# Authenticate
client = await KworkClient.login("username", "password")
# Get catalog
catalog = await client.catalog.get_list(page=1)
# Get projects
projects = await client.projects.get_list(page=1)
# Close when done
await client.close()
```
### Using context manager
```python
async with await KworkClient.login("username", "password") as client:
catalog = await client.catalog.get_list(page=1)
# Client automatically closes
```
### Restore from token
```python
# Save token after login
token = client._token
# Later, restore session
client = KworkClient(token=token)
user_info = await client.user.get_info()
```
## API Overview
### Catalog API
- `client.catalog.get_list()` — Get kworks catalog
- `client.catalog.get_details(kwork_id)` — Get kwork details
### Projects API
- `client.projects.get_list()` — Get freelance projects
- `client.projects.get_payer_orders()` — Your orders as customer
- `client.projects.get_worker_orders()` — Your orders as performer
### User API
- `client.user.get_info()` — Get user profile
- `client.user.get_reviews()` — Get user reviews
- `client.user.get_favorite_kworks()` — Get favorite kworks
### Settings & Preferences
- `client.get_wants()` — User preferences
- `client.get_kworks_status()` — Kworks status
- `client.update_settings()` — Update settings
- `client.go_offline()` — Set offline status
See [API Reference](api-reference.md) for full documentation.
## Error Handling
```python
from kwork_api import KworkError, KworkAuthError, KworkApiError
try:
await client.catalog.get_list()
except KworkAuthError:
print("Invalid credentials")
except KworkApiError as e:
print(f"API error: {e.status_code}")
except KworkError as e:
print(f"General error: {e.message}")
```

79
mkdocs.yml Normal file
View File

@ -0,0 +1,79 @@
site_name: Kwork API
site_description: Unofficial Python client for Kwork.ru API
site_url: https://github.com/claw/kwork-api
repo_name: claw/kwork-api
repo_url: https://github.com/claw/kwork-api
theme:
name: material
features:
- navigation.tabs
- navigation.sections
- toc.integrate
- search.suggest
- search.highlight
palette:
- scheme: default
toggle:
icon: material/toggle-switch-off-outline
name: Switch to dark mode
- scheme: slate
toggle:
icon: material/toggle-switch
name: Switch to light mode
plugins:
- search
- mkdocstrings:
handlers:
python:
paths: [src]
options:
docstring_style: google
show_source: true
show_root_heading: true
show_category_heading: true
merge_init_into_class: true
separate_signature: true
signature_crossrefs: true
filters:
- "!^_"
- "^__init__"
markdown_extensions:
- admonition
- attr_list
- def_list
- footnotes
- toc:
permalink: true
- pymdownx.arithmatex:
generic: true
- pymdownx.betterem:
smart_enable: all
- pymdownx.caret
- pymdownx.details
- pymdownx.inlinehilite
- pymdownx.keys
- pymdownx.magiclink:
repo_url_shorthand: true
user: claw
repo: kwork-api
- pymdownx.mark
- pymdownx.smartsymbols
- pymdownx.superfences
- pymdownx.tabbed:
alternate_style: true
- pymdownx.tasklist:
custom_checkbox: true
- pymdownx.tilde
nav:
- Home: index.md
- API Reference:
- Overview: api-reference.md
- Client: api/client.md
- Models: api/models.md
- Errors: api/errors.md
- Examples: examples.md

View File

@ -55,6 +55,10 @@ dev = [
"respx>=0.20.0", "respx>=0.20.0",
"ruff>=0.3.0", "ruff>=0.3.0",
"pydoc-markdown>=4.8.2", "pydoc-markdown>=4.8.2",
"mkdocs>=1.6.1",
"mkdocs-material>=9.7.6",
"mkdocstrings>=1.0.3",
"mkdocstrings-python>=2.0.3",
] ]
[tool.pytest.ini_options] [tool.pytest.ini_options]

View File

@ -907,32 +907,7 @@ class KworkClient:
data = await self.client._request("POST", "/blockedDialogList") data = await self.client._request("POST", "/blockedDialogList")
return [Dialog.model_validate(d) for d in data.get("dialogs", [])] return [Dialog.model_validate(d) for d in data.get("dialogs", [])]
# ========== Other Endpoints ========== # ========== User Settings & Preferences ==========
class OtherAPI:
"""
Прочее API.
Вспомогательные эндпоинты которые не вошли в другие категории:
- Пользовательские настройки и предпочтения (wants)
- Статусы кворков и заказов
- Персональные предложения (offers)
- Настройки профиля
- Статус онлайн/оффлайн
Example:
# Пользовательские предпочтения
wants = await client.other.get_wants()
# Статус кворков
status = await client.other.get_kworks_status()
# Установить статус оффлайн
await client.other.go_offline()
"""
def __init__(self, client: "KworkClient"):
self.client = client
async def get_wants(self) -> dict[str, Any]: async def get_wants(self) -> dict[str, Any]:
""" """
@ -947,10 +922,10 @@ class KworkClient:
Словарь с настройками предпочтений. Словарь с настройками предпочтений.
Example: Example:
wants = await client.other.get_wants() wants = await client.get_wants()
print(wants) print(wants)
""" """
return await self.client._request("POST", "/myWants") return await self._request("POST", "/myWants")
async def get_wants_status(self) -> dict[str, Any]: async def get_wants_status(self) -> dict[str, Any]:
""" """
@ -959,7 +934,7 @@ class KworkClient:
Returns: Returns:
Статус wants с метаданными. Статус wants с метаданными.
""" """
return await self.client._request("POST", "/wantsStatusList") return await self._request("POST", "/wantsStatusList")
async def get_kworks_status(self) -> dict[str, Any]: async def get_kworks_status(self) -> dict[str, Any]:
""" """
@ -972,10 +947,10 @@ class KworkClient:
Словарь со статусами кворков. Словарь со статусами кворков.
Example: Example:
status = await client.other.get_kworks_status() status = await client.get_kworks_status()
print(status) print(status)
""" """
return await self.client._request("POST", "/kworksStatusList") return await self._request("POST", "/kworksStatusList")
async def get_offers(self) -> dict[str, Any]: async def get_offers(self) -> dict[str, Any]:
""" """
@ -984,7 +959,7 @@ class KworkClient:
Returns: Returns:
Список персональных предложений от Kwork. Список персональных предложений от Kwork.
""" """
return await self.client._request("POST", "/offers") return await self._request("POST", "/offers")
async def get_exchange_info(self) -> dict[str, Any]: async def get_exchange_info(self) -> dict[str, Any]:
""" """
@ -993,7 +968,7 @@ class KworkClient:
Returns: Returns:
Информация о курсах валют и обмене. Информация о курсах валют и обмене.
""" """
return await self.client._request("POST", "/exchangeInfo") return await self._request("POST", "/exchangeInfo")
async def get_channel(self) -> dict[str, Any]: async def get_channel(self) -> dict[str, Any]:
""" """
@ -1002,7 +977,7 @@ class KworkClient:
Returns: Returns:
Данные канала (если есть). Данные канала (если есть).
""" """
return await self.client._request("POST", "/getChannel") return await self._request("POST", "/getChannel")
async def get_in_app_notification(self) -> dict[str, Any]: async def get_in_app_notification(self) -> dict[str, Any]:
""" """
@ -1011,7 +986,7 @@ class KworkClient:
Returns: Returns:
Данные in-app уведомления. Данные in-app уведомления.
""" """
return await self.client._request("POST", "/getInAppNotification") return await self._request("POST", "/getInAppNotification")
async def get_security_user_data(self) -> dict[str, Any]: async def get_security_user_data(self) -> dict[str, Any]:
""" """
@ -1020,7 +995,7 @@ class KworkClient:
Returns: Returns:
Информация о безопасности аккаунта. Информация о безопасности аккаунта.
""" """
return await self.client._request("POST", "/getSecurityUserData") return await self._request("POST", "/getSecurityUserData")
async def is_dialog_allow(self, user_id: int) -> bool: async def is_dialog_allow(self, user_id: int) -> bool:
""" """
@ -1033,11 +1008,11 @@ class KworkClient:
True если диалог разрешён, False иначе. True если диалог разрешён, False иначе.
Example: Example:
allowed = await client.other.is_dialog_allow(12345) allowed = await client.is_dialog_allow(12345)
if allowed: if allowed:
print("Можно написать сообщение") print("Можно написать сообщение")
""" """
data = await self.client._request( data = await self._request(
"POST", "POST",
"/isDialogAllow", "/isDialogAllow",
json={"user_id": user_id}, json={"user_id": user_id},
@ -1055,10 +1030,10 @@ class KworkClient:
Список просмотренных кворков. Список просмотренных кворков.
Example: Example:
viewed = await client.other.get_viewed_kworks() viewed = await client.get_viewed_kworks()
print(f"Просмотрено: {len(viewed)} кворков") print(f"Просмотрено: {len(viewed)} кворков")
""" """
data = await self.client._request("POST", "/viewedCatalogKworks") data = await self._request("POST", "/viewedCatalogKworks")
return [Kwork.model_validate(k) for k in data.get("kworks", [])] return [Kwork.model_validate(k) for k in data.get("kworks", [])]
async def get_favorite_categories(self) -> list[int]: async def get_favorite_categories(self) -> list[int]:
@ -1069,10 +1044,10 @@ class KworkClient:
Список ID категорий, добавленных в избранное. Список ID категорий, добавленных в избранное.
Example: Example:
cats = await client.other.get_favorite_categories() cats = await client.get_favorite_categories()
print(f"Избранные категории: {cats}") print(f"Избранные категории: {cats}")
""" """
data = await self.client._request("POST", "/favoriteCategories") data = await self._request("POST", "/favoriteCategories")
return data.get("categories", []) return data.get("categories", [])
async def update_settings(self, settings: dict[str, Any]) -> dict[str, Any]: async def update_settings(self, settings: dict[str, Any]) -> dict[str, Any]:
@ -1087,12 +1062,12 @@ class KworkClient:
Ответ API с подтверждением обновления. Ответ API с подтверждением обновления.
Example: Example:
await client.other.update_settings({ await client.update_settings({
"email_notifications": True, "email_notifications": True,
"language": "ru" "language": "ru"
}) })
""" """
return await self.client._request("POST", "/updateSettings", json=settings) return await self._request("POST", "/updateSettings", json=settings)
async def go_offline(self) -> dict[str, Any]: async def go_offline(self) -> dict[str, Any]:
""" """
@ -1104,9 +1079,9 @@ class KworkClient:
Подтверждение изменения статуса. Подтверждение изменения статуса.
Example: Example:
await client.other.go_offline() await client.go_offline()
""" """
return await self.client._request("POST", "/offline") return await self._request("POST", "/offline")
async def get_actor(self) -> dict[str, Any]: async def get_actor(self) -> dict[str, Any]:
""" """
@ -1115,66 +1090,31 @@ class KworkClient:
Returns: Returns:
Данные актёра/пользователя. Данные актёра/пользователя.
""" """
return await self.client._request("POST", "/actor") return await self._request("POST", "/actor")
# ========== API Property Accessors ========== # ========== API Property Accessors ==========
@property @property
def catalog(self) -> CatalogAPI: def catalog(self) -> CatalogAPI:
""" """API каталога кворков."""
API каталога кворков.
Returns:
CatalogAPI для работы с каталогом.
"""
return self.CatalogAPI(self) return self.CatalogAPI(self)
@property @property
def projects(self) -> ProjectsAPI: def projects(self) -> ProjectsAPI:
""" """API биржи проектов."""
API биржи проектов.
Returns:
ProjectsAPI для работы с проектами.
"""
return self.ProjectsAPI(self) return self.ProjectsAPI(self)
@property @property
def user(self) -> UserAPI: def user(self) -> UserAPI:
""" """Пользовательское API."""
Пользовательское API.
Returns:
UserAPI для работы с профилем.
"""
return self.UserAPI(self) return self.UserAPI(self)
@property @property
def reference(self) -> ReferenceAPI: def reference(self) -> ReferenceAPI:
""" """Справочное API."""
Справочное API.
Returns:
ReferenceAPI для справочных данных.
"""
return self.ReferenceAPI(self) return self.ReferenceAPI(self)
@property @property
def notifications(self) -> NotificationsAPI: def notifications(self) -> NotificationsAPI:
""" """API уведомлений."""
API уведомлений.
Returns:
NotificationsAPI для уведомлений и сообщений.
"""
return self.NotificationsAPI(self) return self.NotificationsAPI(self)
@property
def other(self) -> OtherAPI:
"""
Прочее API.
Returns:
OtherAPI для вспомогательных эндпоинтов.
"""
return self.OtherAPI(self)

239
uv.lock generated
View File

@ -25,6 +25,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl", hash = "sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c", size = 113592, upload-time = "2026-01-06T11:45:19.497Z" }, { url = "https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl", hash = "sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c", size = 113592, upload-time = "2026-01-06T11:45:19.497Z" },
] ]
[[package]]
name = "babel"
version = "2.18.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/7d/b2/51899539b6ceeeb420d40ed3cd4b7a40519404f9baf3d4ac99dc413a834b/babel-2.18.0.tar.gz", hash = "sha256:b80b99a14bd085fcacfa15c9165f651fbb3406e66cc603abf11c5750937c992d", size = 9959554, upload-time = "2026-02-01T12:30:56.078Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl", hash = "sha256:e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35", size = 10196845, upload-time = "2026-02-01T12:30:53.445Z" },
]
[[package]] [[package]]
name = "backports-asyncio-runner" name = "backports-asyncio-runner"
version = "1.2.0" version = "1.2.0"
@ -34,6 +43,20 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/a0/59/76ab57e3fe74484f48a53f8e337171b4a2349e506eabe136d7e01d059086/backports_asyncio_runner-1.2.0-py3-none-any.whl", hash = "sha256:0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5", size = 12313, upload-time = "2025-07-02T02:27:14.263Z" }, { url = "https://files.pythonhosted.org/packages/a0/59/76ab57e3fe74484f48a53f8e337171b4a2349e506eabe136d7e01d059086/backports_asyncio_runner-1.2.0-py3-none-any.whl", hash = "sha256:0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5", size = 12313, upload-time = "2025-07-02T02:27:14.263Z" },
] ]
[[package]]
name = "backrefs"
version = "6.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/4e/a6/e325ec73b638d3ede4421b5445d4a0b8b219481826cc079d510100af356c/backrefs-6.2.tar.gz", hash = "sha256:f44ff4d48808b243b6c0cdc6231e22195c32f77046018141556c66f8bab72a49", size = 7012303, upload-time = "2026-02-16T19:10:15.828Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/1b/39/3765df263e08a4df37f4f43cb5aa3c6c17a4bdd42ecfe841e04c26037171/backrefs-6.2-py310-none-any.whl", hash = "sha256:0fdc7b012420b6b144410342caeb8adc54c6866cf12064abc9bb211302e496f8", size = 381075, upload-time = "2026-02-16T19:10:04.322Z" },
{ url = "https://files.pythonhosted.org/packages/0f/f0/35240571e1b67ffb19dafb29ab34150b6f59f93f717b041082cdb1bfceb1/backrefs-6.2-py311-none-any.whl", hash = "sha256:08aa7fae530c6b2361d7bdcbda1a7c454e330cc9dbcd03f5c23205e430e5c3be", size = 392874, upload-time = "2026-02-16T19:10:06.314Z" },
{ url = "https://files.pythonhosted.org/packages/e3/63/77e8c9745b4d227cce9f5e0a6f68041278c5f9b18588b35905f5f19c1beb/backrefs-6.2-py312-none-any.whl", hash = "sha256:c3f4b9cb2af8cda0d87ab4f57800b57b95428488477be164dd2b47be54db0c90", size = 398787, upload-time = "2026-02-16T19:10:08.274Z" },
{ url = "https://files.pythonhosted.org/packages/c5/71/c754b1737ad99102e03fa3235acb6cb6d3ac9d6f596cbc3e5f236705abd8/backrefs-6.2-py313-none-any.whl", hash = "sha256:12df81596ab511f783b7d87c043ce26bc5b0288cf3bb03610fe76b8189282b2b", size = 400747, upload-time = "2026-02-16T19:10:09.791Z" },
{ url = "https://files.pythonhosted.org/packages/af/75/be12ba31a6eb20dccef2320cd8ccb3f7d9013b68ba4c70156259fee9e409/backrefs-6.2-py314-none-any.whl", hash = "sha256:e5f805ae09819caa1aa0623b4a83790e7028604aa2b8c73ba602c4454e665de7", size = 412602, upload-time = "2026-02-16T19:10:12.317Z" },
{ url = "https://files.pythonhosted.org/packages/21/f8/d02f650c47d05034dcd6f9c8cf94f39598b7a89c00ecda0ecb2911bc27e9/backrefs-6.2-py39-none-any.whl", hash = "sha256:664e33cd88c6840b7625b826ecf2555f32d491800900f5a541f772c485f7cda7", size = 381077, upload-time = "2026-02-16T19:10:13.74Z" },
]
[[package]] [[package]]
name = "black" name = "black"
version = "23.12.1" version = "23.12.1"
@ -415,6 +438,26 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" },
] ]
[[package]]
name = "ghp-import"
version = "2.1.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "python-dateutil" },
]
sdist = { url = "https://files.pythonhosted.org/packages/d9/29/d40217cbe2f6b1359e00c6c307bb3fc876ba74068cbab3dde77f03ca0dc4/ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343", size = 10943, upload-time = "2022-05-02T15:47:16.11Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619", size = 11034, upload-time = "2022-05-02T15:47:14.552Z" },
]
[[package]]
name = "griffelib"
version = "2.0.0"
source = { registry = "https://pypi.org/simple" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/4d/51/c936033e16d12b627ea334aaaaf42229c37620d0f15593456ab69ab48161/griffelib-2.0.0-py3-none-any.whl", hash = "sha256:01284878c966508b6d6f1dbff9b6fa607bc062d8261c5c7253cb285b06422a7f", size = 142004, upload-time = "2026-02-09T19:09:40.561Z" },
]
[[package]] [[package]]
name = "h11" name = "h11"
version = "0.16.0" version = "0.16.0"
@ -539,6 +582,10 @@ dev = [
[package.dev-dependencies] [package.dev-dependencies]
dev = [ dev = [
{ name = "mkdocs" },
{ name = "mkdocs-material" },
{ name = "mkdocstrings" },
{ name = "mkdocstrings-python" },
{ name = "pydoc-markdown" }, { name = "pydoc-markdown" },
{ name = "pytest" }, { name = "pytest" },
{ name = "pytest-asyncio" }, { name = "pytest-asyncio" },
@ -562,6 +609,10 @@ provides-extras = ["dev"]
[package.metadata.requires-dev] [package.metadata.requires-dev]
dev = [ dev = [
{ name = "mkdocs", specifier = ">=1.6.1" },
{ name = "mkdocs-material", specifier = ">=9.7.6" },
{ name = "mkdocstrings", specifier = ">=1.0.3" },
{ name = "mkdocstrings-python", specifier = ">=2.0.3" },
{ name = "pydoc-markdown", specifier = ">=4.8.2" }, { name = "pydoc-markdown", specifier = ">=4.8.2" },
{ name = "pytest", specifier = ">=8.0.0" }, { name = "pytest", specifier = ">=8.0.0" },
{ name = "pytest-asyncio", specifier = ">=0.23.0" }, { name = "pytest-asyncio", specifier = ">=0.23.0" },
@ -570,6 +621,15 @@ dev = [
{ name = "ruff", specifier = ">=0.3.0" }, { name = "ruff", specifier = ">=0.3.0" },
] ]
[[package]]
name = "markdown"
version = "3.10.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/2b/f4/69fa6ed85ae003c2378ffa8f6d2e3234662abd02c10d216c0ba96081a238/markdown-3.10.2.tar.gz", hash = "sha256:994d51325d25ad8aa7ce4ebaec003febcce822c3f8c911e3b17c52f7f589f950", size = 368805, upload-time = "2026-02-09T14:57:26.942Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl", hash = "sha256:e91464b71ae3ee7afd3017d9f358ef0baf158fd9a298db92f1d4761133824c36", size = 108180, upload-time = "2026-02-09T14:57:25.787Z" },
]
[[package]] [[package]]
name = "markupsafe" name = "markupsafe"
version = "3.0.3" version = "3.0.3"
@ -655,6 +715,130 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" },
] ]
[[package]]
name = "mergedeep"
version = "1.3.4"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/3a/41/580bb4006e3ed0361b8151a01d324fb03f420815446c7def45d02f74c270/mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8", size = 4661, upload-time = "2021-02-05T18:55:30.623Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307", size = 6354, upload-time = "2021-02-05T18:55:29.583Z" },
]
[[package]]
name = "mkdocs"
version = "1.6.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "click" },
{ name = "colorama", marker = "sys_platform == 'win32'" },
{ name = "ghp-import" },
{ name = "jinja2" },
{ name = "markdown" },
{ name = "markupsafe" },
{ name = "mergedeep" },
{ name = "mkdocs-get-deps" },
{ name = "packaging" },
{ name = "pathspec" },
{ name = "pyyaml" },
{ name = "pyyaml-env-tag" },
{ name = "watchdog" },
]
sdist = { url = "https://files.pythonhosted.org/packages/bc/c6/bbd4f061bd16b378247f12953ffcb04786a618ce5e904b8c5a01a0309061/mkdocs-1.6.1.tar.gz", hash = "sha256:7b432f01d928c084353ab39c57282f29f92136665bdd6abf7c1ec8d822ef86f2", size = 3889159, upload-time = "2024-08-30T12:24:06.899Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl", hash = "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e", size = 3864451, upload-time = "2024-08-30T12:24:05.054Z" },
]
[[package]]
name = "mkdocs-autorefs"
version = "1.4.4"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "markdown" },
{ name = "markupsafe" },
{ name = "mkdocs" },
]
sdist = { url = "https://files.pythonhosted.org/packages/52/c0/f641843de3f612a6b48253f39244165acff36657a91cc903633d456ae1ac/mkdocs_autorefs-1.4.4.tar.gz", hash = "sha256:d54a284f27a7346b9c38f1f852177940c222da508e66edc816a0fa55fc6da197", size = 56588, upload-time = "2026-02-10T15:23:55.105Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl", hash = "sha256:834ef5408d827071ad1bc69e0f39704fa34c7fc05bc8e1c72b227dfdc5c76089", size = 25530, upload-time = "2026-02-10T15:23:53.817Z" },
]
[[package]]
name = "mkdocs-get-deps"
version = "0.2.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "mergedeep" },
{ name = "platformdirs" },
{ name = "pyyaml" },
]
sdist = { url = "https://files.pythonhosted.org/packages/ce/25/b3cccb187655b9393572bde9b09261d267c3bf2f2cdabe347673be5976a6/mkdocs_get_deps-0.2.2.tar.gz", hash = "sha256:8ee8d5f316cdbbb2834bc1df6e69c08fe769a83e040060de26d3c19fad3599a1", size = 11047, upload-time = "2026-03-10T02:46:33.632Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl", hash = "sha256:e7878cbeac04860b8b5e0ca31d3abad3df9411a75a32cde82f8e44b6c16ff650", size = 9555, upload-time = "2026-03-10T02:46:32.256Z" },
]
[[package]]
name = "mkdocs-material"
version = "9.7.6"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "babel" },
{ name = "backrefs" },
{ name = "colorama" },
{ name = "jinja2" },
{ name = "markdown" },
{ name = "mkdocs" },
{ name = "mkdocs-material-extensions" },
{ name = "paginate" },
{ name = "pygments" },
{ name = "pymdown-extensions" },
{ name = "requests" },
]
sdist = { url = "https://files.pythonhosted.org/packages/45/29/6d2bcf41ae40802c4beda2432396fff97b8456fb496371d1bc7aad6512ec/mkdocs_material-9.7.6.tar.gz", hash = "sha256:00bdde50574f776d328b1862fe65daeaf581ec309bd150f7bff345a098c64a69", size = 4097959, upload-time = "2026-03-19T15:41:58.161Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/2c/01/bc663630c510822c95c47a66af9fa7a443c295b47d5f041e5e6ae62ef659/mkdocs_material-9.7.6-py3-none-any.whl", hash = "sha256:71b84353921b8ea1ba84fe11c50912cc512da8fe0881038fcc9a0761c0e635ba", size = 9305470, upload-time = "2026-03-19T15:41:55.217Z" },
]
[[package]]
name = "mkdocs-material-extensions"
version = "1.3.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/79/9b/9b4c96d6593b2a541e1cb8b34899a6d021d208bb357042823d4d2cabdbe7/mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443", size = 11847, upload-time = "2023-11-22T19:09:45.208Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31", size = 8728, upload-time = "2023-11-22T19:09:43.465Z" },
]
[[package]]
name = "mkdocstrings"
version = "1.0.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "jinja2" },
{ name = "markdown" },
{ name = "markupsafe" },
{ name = "mkdocs" },
{ name = "mkdocs-autorefs" },
{ name = "pymdown-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/46/62/0dfc5719514115bf1781f44b1d7f2a0923fcc01e9c5d7990e48a05c9ae5d/mkdocstrings-1.0.3.tar.gz", hash = "sha256:ab670f55040722b49bb45865b2e93b824450fb4aef638b00d7acb493a9020434", size = 100946, upload-time = "2026-02-07T14:31:40.973Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/04/41/1cf02e3df279d2dd846a1bf235a928254eba9006dd22b4a14caa71aed0f7/mkdocstrings-1.0.3-py3-none-any.whl", hash = "sha256:0d66d18430c2201dc7fe85134277382baaa15e6b30979f3f3bdbabd6dbdb6046", size = 35523, upload-time = "2026-02-07T14:31:39.27Z" },
]
[[package]]
name = "mkdocstrings-python"
version = "2.0.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "griffelib" },
{ name = "mkdocs-autorefs" },
{ name = "mkdocstrings" },
{ name = "typing-extensions", marker = "python_full_version < '3.11'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/29/33/c225eaf898634bdda489a6766fc35d1683c640bffe0e0acd10646b13536d/mkdocstrings_python-2.0.3.tar.gz", hash = "sha256:c518632751cc869439b31c9d3177678ad2bfa5c21b79b863956ad68fc92c13b8", size = 199083, upload-time = "2026-02-20T10:38:36.368Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl", hash = "sha256:0b83513478bdfd803ff05aa43e9b1fca9dd22bcd9471f09ca6257f009bc5ee12", size = 104779, upload-time = "2026-02-20T10:38:34.517Z" },
]
[[package]] [[package]]
name = "mypy-extensions" name = "mypy-extensions"
version = "1.1.0" version = "1.1.0"
@ -704,6 +888,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" }, { url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" },
] ]
[[package]]
name = "paginate"
version = "0.5.7"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/ec/46/68dde5b6bc00c1296ec6466ab27dddede6aec9af1b99090e1107091b3b84/paginate-0.5.7.tar.gz", hash = "sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945", size = 19252, upload-time = "2024-08-25T14:17:24.139Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591", size = 13746, upload-time = "2024-08-25T14:17:22.55Z" },
]
[[package]] [[package]]
name = "pathspec" name = "pathspec"
version = "1.0.4" version = "1.0.4"
@ -898,6 +1091,19 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" },
] ]
[[package]]
name = "pymdown-extensions"
version = "10.21"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "markdown" },
{ name = "pyyaml" },
]
sdist = { url = "https://files.pythonhosted.org/packages/ba/63/06673d1eb6d8f83c0ea1f677d770e12565fb516928b4109c9e2055656a9e/pymdown_extensions-10.21.tar.gz", hash = "sha256:39f4a020f40773f6b2ff31d2cd2546c2c04d0a6498c31d9c688d2be07e1767d5", size = 853363, upload-time = "2026-02-15T20:44:06.748Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/6f/2c/5b079febdc65e1c3fb2729bf958d18b45be7113828528e8a0b5850dd819a/pymdown_extensions-10.21-py3-none-any.whl", hash = "sha256:91b879f9f864d49794c2d9534372b10150e6141096c3908a455e45ca72ad9d3f", size = 268877, upload-time = "2026-02-15T20:44:05.464Z" },
]
[[package]] [[package]]
name = "pytest" name = "pytest"
version = "9.0.2" version = "9.0.2"
@ -944,6 +1150,18 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", hash = "sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678", size = 22876, upload-time = "2026-03-21T20:11:14.438Z" }, { url = "https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", hash = "sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678", size = 22876, upload-time = "2026-03-21T20:11:14.438Z" },
] ]
[[package]]
name = "python-dateutil"
version = "2.9.0.post0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "six" },
]
sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" },
]
[[package]] [[package]]
name = "pyyaml" name = "pyyaml"
version = "6.0.3" version = "6.0.3"
@ -1008,6 +1226,18 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" },
] ]
[[package]]
name = "pyyaml-env-tag"
version = "1.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pyyaml" },
]
sdist = { url = "https://files.pythonhosted.org/packages/eb/2e/79c822141bfd05a853236b504869ebc6b70159afc570e1d5a20641782eaa/pyyaml_env_tag-1.1.tar.gz", hash = "sha256:2eb38b75a2d21ee0475d6d97ec19c63287a7e140231e4214969d0eac923cd7ff", size = 5737, upload-time = "2025-05-13T15:24:01.64Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl", hash = "sha256:17109e1a528561e32f026364712fee1264bc2ea6715120891174ed1b980d2e04", size = 4722, upload-time = "2025-05-13T15:23:59.629Z" },
]
[[package]] [[package]]
name = "requests" name = "requests"
version = "2.32.5" version = "2.32.5"
@ -1060,6 +1290,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/8f/e8/726643a3ea68c727da31570bde48c7a10f1aa60eddd628d94078fec586ff/ruff-0.15.7-py3-none-win_arm64.whl", hash = "sha256:18e8d73f1c3fdf27931497972250340f92e8c861722161a9caeb89a58ead6ed2", size = 11023304, upload-time = "2026-03-19T16:26:51.669Z" }, { url = "https://files.pythonhosted.org/packages/8f/e8/726643a3ea68c727da31570bde48c7a10f1aa60eddd628d94078fec586ff/ruff-0.15.7-py3-none-win_arm64.whl", hash = "sha256:18e8d73f1c3fdf27931497972250340f92e8c861722161a9caeb89a58ead6ed2", size = 11023304, upload-time = "2026-03-19T16:26:51.669Z" },
] ]
[[package]]
name = "six"
version = "1.17.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" },
]
[[package]] [[package]]
name = "structlog" name = "structlog"
version = "25.5.0" version = "25.5.0"