diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..e4b0c71 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,49 @@ +name: Docs + +on: + push: + branches: [main] + pull_request: + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + name: Build docs + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - uses: astral-sh/setup-uv@v6 + with: + enable-cache: true + - name: Install social card dependencies + run: sudo apt-get update && sudo apt-get install -y libcairo2-dev libfreetype6-dev libffi-dev libjpeg-dev libpng-dev libz-dev + - run: uv sync --locked --group docs + - run: uv run mkdocs build --strict + env: + SOCIAL_CARDS: "true" + - if: github.event_name != 'pull_request' + uses: actions/upload-pages-artifact@v4 + with: + path: site + + deploy: + name: Deploy to GitHub Pages + if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main' + needs: build + runs-on: ubuntu-latest + permissions: + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index 312f336..1db7705 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,7 @@ htmlcov/ codegen/extract/node_modules/ codegen/extract/.cache/ .DS_Store + +# MkDocs output +site/ +.cache/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 974294e..3d8a84a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -30,6 +30,35 @@ uv run python -m codegen --check uv run pytest ``` +## Documentation + +The site in `docs/` is built with MkDocs Material and mkdocstrings. The API reference is generated from docstrings +at build time by `docs/hooks/types_reference.py`. + +```bash +uv sync --group docs +uv run mkdocs serve +uv run mkdocs build --strict +``` + +### Docs must keep up with the code + +A change to the public API is not done until the docs cover it. CI enforces this: + +| Check | Where | Fails when | +| --- | --- | --- | +| `tests/test_docs_coverage.py` | `pytest` job | A resource, method, `opencode.__all__` name or `opencode.types` model is not in the reference; an exported class or one of its public methods has no docstring; a resource group is missing from `docs/guides/index.md`; a guide mentions a method or type that does not exist | +| ruff `D1` rules | Lint job | A public function in a public module has no docstring | +| `mkdocs build --strict` | Docs workflow | A link or cross-reference is broken | + +Each failure names what is missing and the file to change. In practice: + +- **New endpoint or resource group** (from a spec sync): resource and type pages are generated from the code, so + they appear on their own. Add a row for a new group to `docs/guides/index.md`. +- **New hand-written class or function exported from `opencode`**: give it a docstring and add a `::: opencode.Name` + directive to the right page in `docs/reference/`. +- **Renamed or removed API**: update every guide that mentions it. + ## Layout | Path | What it is | Edit by hand? | diff --git a/README.md b/README.md index cf8c783..4d01836 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,13 @@ [![CI](https://github.com/shrijayan/opencode-python-sdk/actions/workflows/ci.yml/badge.svg)](https://github.com/shrijayan/opencode-python-sdk/actions/workflows/ci.yml) [![PyPI](https://img.shields.io/pypi/v/opencode-python-sdk.svg)](https://pypi.org/project/opencode-python-sdk/) +[![Docs](https://img.shields.io/badge/docs-shrijayan.github.io-d9730d)](https://shrijayan.github.io/opencode-python-sdk/) [![Python](https://img.shields.io/pypi/pyversions/opencode-python-sdk.svg)](https://pypi.org/project/opencode-python-sdk/) Typed Python client for the [OpenCode](https://github.com/anomalyco/opencode) 2.x server API. +**Documentation: ** + > **Unofficial, community-maintained.** This package is not affiliated with or endorsed by the OpenCode team. > If the OpenCode maintainers want to take it over, we are happy to transfer this repository and the `opencode-python-sdk` > name on PyPI. Open an issue and we will hand it over. diff --git a/codegen/render.py b/codegen/render.py index 8451ff8..dc22306 100644 --- a/codegen/render.py +++ b/codegen/render.py @@ -265,14 +265,14 @@ def _method_doc(operation: Operation, errors: dict[str, dict[str, Any]], indent: documented = [param for param in operation.params if param.doc] if documented: parts.append("Args:\n" + "\n".join(f" {param.name}: {_one_line(param.doc or '')}" for param in documented)) - raised = [] + raised: dict[str, int] = {} for error in operation.errors: if error.tag and error.tag in errors: - name = errors[error.tag]["class"] - if name not in raised: - raised.append(name) + raised.setdefault(errors[error.tag]["class"], errors[error.tag]["status"]) if raised: - parts.append("Raises:\n" + "\n".join(f" {name}" for name in raised)) + parts.append( + "Raises:\n" + "\n".join(f" {name}: The server answered {status}." for name, status in raised.items()) + ) parts.append(f"``{operation.http_method} {operation.path}``") return docstring("\n\n".join(parts), indent) or "" @@ -391,6 +391,7 @@ def _resource_classes(resource: Resource, errors: dict[str, dict[str, Any]], *, lines += [ " @cached_property", f" def {name}(self) -> {prefix}{child.class_name}Resource:", + f' """Operations under ``client.{_attr_path(child)}``."""', f" return {prefix}{child.class_name}Resource(self._client)\n", ] for operation in resource.operations: diff --git a/docs/assets/logo.svg b/docs/assets/logo.svg new file mode 100644 index 0000000..083ef27 --- /dev/null +++ b/docs/assets/logo.svg @@ -0,0 +1 @@ + diff --git a/docs/getting-started/connect.md b/docs/getting-started/connect.md new file mode 100644 index 0000000..f430d55 --- /dev/null +++ b/docs/getting-started/connect.md @@ -0,0 +1,61 @@ +# Connect to a server + +Start a server with the CLI, then point a client at it: + +```bash +OPENCODE_PASSWORD=secret opencode serve --port 4096 +``` + +```python +from opencode import Opencode + +client = Opencode("http://127.0.0.1:4096", password="secret") +print(client.server.info().version) +``` + +## Environment variables + +`base_url` and `password` fall back to environment variables, so the shortest form is `Opencode()`. + +| Argument | Variable | +| --- | --- | +| `base_url` | `OPENCODE_BASE_URL` | +| `password` | `OPENCODE_PASSWORD`, then `OPENCODE_SERVER_PASSWORD` | + +`OPENCODE_PASSWORD` is the same variable the OpenCode CLI reads. Pass `password=""` to send no credentials. + +## Closing the client + +The client owns an `httpx.Client` connection pool. Use it as a context manager, or call `close()`: + +```python +with Opencode() as client: + client.agent.list() +``` + +## Calling the API + +Methods mirror the official TypeScript client: `client..()`, in `snake_case`. Path parameters are +positional; everything else is keyword-only. + +```python +client.session.get("ses_...") +client.session.prompt("ses_...", text="Fix the failing test", resume=True) +client.session.revert.stage("ses_...", message_id="msg_...") +client.mcp.list() +``` + +Every method is listed under [Resources](../reference/resources.md). + +### Optional and null arguments + +The server distinguishes a field that is absent from a field set to `null`. Optional arguments default to +`NOT_GIVEN` and are left out of the request; passing `None` sends `null`. + +```python +client.session.update("ses_...", title="New title") # (1)! +client.session.list(parent_id=None) # (2)! +``` + +1. Sends `{"title": "New title"}`. +2. Sends `parentID=null`, which returns only root sessions. diff --git a/docs/getting-started/index.md b/docs/getting-started/index.md new file mode 100644 index 0000000..f938b54 --- /dev/null +++ b/docs/getting-started/index.md @@ -0,0 +1,35 @@ +# Install + +```bash +pip install opencode-python-sdk +``` + +=== "uv" + + ```bash + uv add opencode-python-sdk + ``` + +=== "poetry" + + ```bash + poetry add opencode-python-sdk + ``` + +The distribution is called `opencode-python-sdk`; the package imports as `opencode`. It needs Python 3.10 or newer +and depends only on `httpx`, `pydantic`, `anyio` and `typing-extensions`. + +```python +import opencode + +print(opencode.__version__) # this package +print(opencode.API_VERSION) # the OpenCode server version it was generated from +``` + +To start a server from Python with [`OpencodeServer`](server.md), install the [OpenCode CLI](https://opencode.ai) +as well, so that `opencode` is on `PATH`. + +## Next + +- [Connect to a server](connect.md) that is already running. +- [Run a server from Python](server.md) for scripts, tests and embedded use. diff --git a/docs/getting-started/server.md b/docs/getting-started/server.md new file mode 100644 index 0000000..475bbd6 --- /dev/null +++ b/docs/getting-started/server.md @@ -0,0 +1,54 @@ +# Run a server from Python + +`OpencodeServer` runs `opencode serve` as a child process, on a free local port with a random password, for the +lifetime of a `with` block. + +```python +from opencode import OpencodeServer + +server = OpencodeServer( + cwd="/path/to/repo", # (1)! + isolated=True, # (2)! + config={"model": "anthropic/claude-sonnet-5-5"}, # (3)! +) +with server: + client = server.client() + print(client.server.info().version) +``` + +1. The server's working directory, which becomes its default project. +2. Ignore project `opencode.json`, `AGENTS.md` and Claude Code files on disk, for reproducible runs. +3. Passed to the server as `OPENCODE_CONFIG_CONTENT`. + +The server runs in `--stdio` mode, so it exits when the Python process dies, even if the `with` block never +finishes. Its password reaches the child through `OPENCODE_PASSWORD`, which the server strips from the environment +its tools inherit. + +## Async + +`AsyncOpencodeServer` takes the same arguments: + +```python +from opencode import AsyncOpencodeServer + +async with AsyncOpencodeServer(cwd="/path/to/repo") as server: + async with server.client() as client: + await client.session.create(title="Async") +``` + +## When it fails to start + +If `opencode` is missing or the server exits early, `ServerStartError` is raised. Its `output` attribute holds the +last lines the server printed. + +```python +from opencode import OpencodeServer, ServerStartError + +try: + with OpencodeServer() as server: + ... +except ServerStartError as error: + print(error.output) +``` + +See the [`OpencodeServer` reference](../reference/server.md) for every argument. diff --git a/docs/guides/async.md b/docs/guides/async.md new file mode 100644 index 0000000..ef7c8bf --- /dev/null +++ b/docs/guides/async.md @@ -0,0 +1,68 @@ +# Async + +`AsyncOpencode` has the same resources and methods as `Opencode`. Methods return awaitables, list methods return an +`AsyncPaginator`, and streams return an `AsyncStream`. It runs on [AnyIO](https://anyio.readthedocs.io), so it works +under both asyncio and trio. + +=== "asyncio" + + ```python + import asyncio + from opencode import AsyncOpencode + + + async def main() -> None: + async with AsyncOpencode("http://127.0.0.1:4096") as client: + session = await client.session.create(title="Async") + await client.session.prompt(session.id, text="Hello") + async for message in client.message.list(session.id): + print(message.type) + + + asyncio.run(main()) + ``` + +=== "trio" + + ```python + import trio + from opencode import AsyncOpencode + + + async def main() -> None: + async with AsyncOpencode("http://127.0.0.1:4096") as client: + info = await client.server.info() + print(info.version) + + + trio.run(main) + ``` + +## Concurrency + +One client can serve many concurrent tasks; it shares one connection pool. + +```python +import asyncio + + +async def titles(client: AsyncOpencode, ids: list[str]) -> list[str]: + sessions = await asyncio.gather(*(client.session.get(i) for i in ids)) + return [s.title for s in sessions] +``` + +## Pages and streams + +```python +page = await client.session.list(limit=20) # (1)! +async for session in client.session.list(): # (2)! + ... + +async with await client.event.subscribe() as events: # (3)! + async for event in events: + print(event.type) +``` + +1. `await` the paginator for the first page. +2. `async for` over it for every item across pages. +3. `subscribe()` returns an `AsyncStream` once awaited. diff --git a/docs/guides/directory.md b/docs/guides/directory.md new file mode 100644 index 0000000..0345154 --- /dev/null +++ b/docs/guides/directory.md @@ -0,0 +1,22 @@ +# The project directory + +An OpenCode server can serve several projects. Most endpoints take a `location` that says which one a request is +about. Set a default once on the client: + +```python +client = Opencode("http://127.0.0.1:4096", directory="/path/to/repo") +client.agent.list() # (1)! +client.agent.list(location={"directory": "/other"}) # (2)! +``` + +1. Sent with `location` = `/path/to/repo`. +2. A per-call `location` overrides the default. + +Without a default, the server uses its own working directory. With `OpencodeServer`, that is `cwd`; you can also pass +`directory=` to `server.client()`. + +```python +with OpencodeServer(cwd="/repos/api") as server: + api = server.client() + web = server.client(directory="/repos/web") +``` diff --git a/docs/guides/errors.md b/docs/guides/errors.md new file mode 100644 index 0000000..46ba048 --- /dev/null +++ b/docs/guides/errors.md @@ -0,0 +1,59 @@ +# Errors + +Every exception derives from `opencode.OpencodeError`. Errors the server declares are raised as their own class, +with a typed body on `.error`: + +```python +import opencode + +try: + client.session.get("ses_missing") +except opencode.SessionNotFoundError as error: # (1)! + print(error.error.session_id, error.status_code) +except opencode.NotFoundError: # (2)! + ... +except opencode.APIConnectionError: # (3)! + ... +``` + +1. A declared error: `error.error` is a typed `SessionNotFoundErrorBody`. +2. Any other 404. +3. The server could not be reached, or the request timed out. + +## Hierarchy + +```text +OpencodeError +├── ServerStartError OpencodeServer could not start +└── APIError + ├── APIConnectionError no response + │ └── APITimeoutError + ├── APIResponseValidationError unexpected response body + └── APIStatusError any non-2xx response + ├── BadRequestError 400 + ├── AuthenticationError 401 + ├── PermissionDeniedError 403 + ├── NotFoundError 404 + ├── ConflictError 409 + ├── ContentTooLargeError 413 + ├── UnprocessableEntityError 422 + ├── RateLimitError 429 + └── InternalServerError 5xx + ├── NotImplementedServerError 501 + └── ServiceUnavailableError 503 +``` + +Declared errors such as `SessionNotFoundError` or `SessionBusyError` subclass the status class that matches their +HTTP status, so catching `NotFoundError` also catches `SessionNotFoundError`. Each declared error is documented on +the method that can raise it, under **Raises**. The full list is in the [exceptions reference](../reference/exceptions.md). + +## What an `APIStatusError` carries + +| Attribute | Value | +| --- | --- | +| `status_code` | The HTTP status | +| `response` | The `httpx.Response` | +| `request` | The `httpx.Request` | +| `body` | The decoded JSON body, or text | +| `error_tag` | The server's `_tag`, which may be one this client does not know yet | +| `request_id` | The `x-request-id` header, when the server sends one | diff --git a/docs/guides/events.md b/docs/guides/events.md new file mode 100644 index 0000000..0aad2ec --- /dev/null +++ b/docs/guides/events.md @@ -0,0 +1,49 @@ +# Events and streaming + +`client.event.subscribe()` opens a server-sent event stream of everything happening on the server. + +```python +with client.event.subscribe() as events: # (1)! + for event in events: + print(event.type) +``` + +1. The context manager closes the HTTP connection when you stop reading. + +Events are typed (`SessionCreatedEvent`, `SessionTextDeltaEvent` and so on; see [Events](../reference/types/events.md)). +Narrow them with `match`: + +```python +from opencode.types import SessionTextDeltaEvent, SessionIdleEvent + +with client.event.subscribe() as events: + for event in events: + match event: + case SessionTextDeltaEvent(): + print(event.to_dict()) + case SessionIdleEvent(): + break + case _: + pass +``` + +Event types this client version does not know arrive as `UnknownEvent`, with all their fields kept. + +## Timeouts + +Streams only apply the connect timeout by default, because they stay open between events. Pass `timeout=` to bound +a stream. + +## Delivery + +The event stream is volatile by contract. A slow consumer overflows and fails the stream, and events sent while you +are disconnected are lost. Keep the loop body fast, and after reconnecting, read current state (for example with +`client.message.list`) rather than assuming you saw every event. + +## Async + +```python +async with await client.event.subscribe() as events: + async for event in events: + print(event.type) +``` diff --git a/docs/guides/httpx.md b/docs/guides/httpx.md new file mode 100644 index 0000000..62d1e78 --- /dev/null +++ b/docs/guides/httpx.md @@ -0,0 +1,36 @@ +# Advanced httpx config + +The client is built on [httpx](https://www.python-httpx.org). Pass your own `httpx.Client` (or `httpx.AsyncClient`) +for proxies, custom CA bundles, transports or event hooks. You keep ownership and must close it. + +```python +import httpx +from opencode import Opencode + +client = Opencode( + "https://opencode.internal.example.com", + http_client=httpx.Client(proxy="http://proxy:8080", verify="/etc/ssl/ca.pem"), + default_headers={"X-Team": "platform"}, +) +``` + +## Per-request extras + +Every method takes `extra_headers`, `extra_query` and `extra_body`, merged into that request. Use them to reach +server features this client version does not model yet. + +```python +client.session.create( + title="t", + extra_headers={"X-Trace": "1"}, + extra_body={"future": True}, +) +``` + +## Derived clients + +`with_options()` returns a client with changed settings that shares the same connection pool: + +```python +fast = client.with_options(timeout=5.0, max_retries=0) +``` diff --git a/docs/guides/index.md b/docs/guides/index.md new file mode 100644 index 0000000..35d7142 --- /dev/null +++ b/docs/guides/index.md @@ -0,0 +1,39 @@ +# Guide index + +Every resource group on the client, and where it is documented. Every group has a reference +entry; the common ones also have a guide. CI fails if a group on the client is missing from this table +(see `tests/test_docs_coverage.py`). + +| Group | What it covers | Guide | Reference | +| --- | --- | --- | --- | +| `client.agent` | List and inspect agents | - | [`AgentResource`](../reference/resources.md#opencode.resources.agent.AgentResource) | +| `client.command` | List slash commands | - | [`CommandResource`](../reference/resources.md#opencode.resources.command.CommandResource) | +| `client.config` | Read and update configuration | - | [`ConfigResource`](../reference/resources.md#opencode.resources.config.ConfigResource) | +| `client.credential` | Manage provider credentials | - | [`CredentialResource`](../reference/resources.md#opencode.resources.credential.CredentialResource) | +| `client.debug` | Inspect loaded locations | - | [`DebugResource`](../reference/resources.md#opencode.resources.debug.DebugResource) | +| `client.event` | Subscribe to server events | [Guide](events.md) | [`EventResource`](../reference/resources.md#opencode.resources.event.EventResource) | +| `client.experimental` | Experimental endpoints, such as persistent terminals | - | [`ExperimentalResource`](../reference/resources.md#opencode.resources.experimental.ExperimentalResource) | +| `client.file` | Read, list, find and write files | - | [`FileResource`](../reference/resources.md#opencode.resources.file.FileResource) | +| `client.form` | List pending forms | - | [`FormResource`](../reference/resources.md#opencode.resources.form.FormResource) | +| `client.generate` | One-off text generation | - | [`GenerateResource`](../reference/resources.md#opencode.resources.generate.GenerateResource) | +| `client.integration` | Connect and manage integrations | - | [`IntegrationResource`](../reference/resources.md#opencode.resources.integration.IntegrationResource) | +| `client.location` | Project locations the server knows | - | [`LocationResource`](../reference/resources.md#opencode.resources.location.LocationResource) | +| `client.mcp` | MCP servers and their resources | - | [`McpResource`](../reference/resources.md#opencode.resources.mcp.McpResource) | +| `client.message` | Read session messages | [Guide](sessions.md) | [`MessageResource`](../reference/resources.md#opencode.resources.message.MessageResource) | +| `client.migration` | Data migrations | - | [`MigrationResource`](../reference/resources.md#opencode.resources.migration.MigrationResource) | +| `client.model` | List models | - | [`ModelResource`](../reference/resources.md#opencode.resources.model.ModelResource) | +| `client.permission` | Answer and manage permission requests | - | [`PermissionResource`](../reference/resources.md#opencode.resources.permission.PermissionResource) | +| `client.plugin` | List plugins | - | [`PluginResource`](../reference/resources.md#opencode.resources.plugin.PluginResource) | +| `client.project` | Projects | - | [`ProjectResource`](../reference/resources.md#opencode.resources.project.ProjectResource) | +| `client.provider` | Model providers | - | [`ProviderResource`](../reference/resources.md#opencode.resources.provider.ProviderResource) | +| `client.pty` | Terminals | - | [`PtyResource`](../reference/resources.md#opencode.resources.pty.PtyResource) | +| `client.reference` | References | - | [`ReferenceResource`](../reference/resources.md#opencode.resources.reference.ReferenceResource) | +| `client.rpc` | Plugin RPC | - | [`RpcResource`](../reference/resources.md#opencode.resources.rpc.RpcResource) | +| `client.server` | Server info and health | - | [`ServerResource`](../reference/resources.md#opencode.resources.server.ServerResource) | +| `client.session` | Sessions, prompts and their sub-resources | [Guide](sessions.md) | [`SessionResource`](../reference/resources.md#opencode.resources.session.SessionResource) | +| `client.shell` | Shells | - | [`ShellResource`](../reference/resources.md#opencode.resources.shell.ShellResource) | +| `client.skill` | Skills | - | [`SkillResource`](../reference/resources.md#opencode.resources.skill.SkillResource) | +| `client.vcs` | Version control status and branches | - | [`VcsResource`](../reference/resources.md#opencode.resources.vcs.VcsResource) | +| `client.voice` | Voice input | - | [`VoiceResource`](../reference/resources.md#opencode.resources.voice.VoiceResource) | +| `client.websearch` | Web search | - | [`WebsearchResource`](../reference/resources.md#opencode.resources.websearch.WebsearchResource) | +| `client.worktree` | Git worktrees | - | [`WorktreeResource`](../reference/resources.md#opencode.resources.worktree.WorktreeResource) | diff --git a/docs/guides/logging.md b/docs/guides/logging.md new file mode 100644 index 0000000..b2492e0 --- /dev/null +++ b/docs/guides/logging.md @@ -0,0 +1,18 @@ +# Logging + +The client logs to the `opencode` logger with the standard `logging` module. It is silent unless you configure it. + +```python +import logging + +logging.basicConfig() +logging.getLogger("opencode").setLevel(logging.DEBUG) +``` + +| Level | What is logged | +| --- | --- | +| `DEBUG` | Every request and response: method, URL, attempt, status | +| `INFO` | Retries, with the delay and the reason | + +Credentials are never logged. The password only travels in the `Authorization` header and never appears in +`repr()`, log lines or exception messages. diff --git a/docs/guides/models.md b/docs/guides/models.md new file mode 100644 index 0000000..733dbe5 --- /dev/null +++ b/docs/guides/models.md @@ -0,0 +1,50 @@ +# Models and unions + +Responses are [pydantic](https://docs.pydantic.dev) v2 models, defined in `opencode.types`. Attributes are +`snake_case`; the wire names stay available as aliases, so a model validates server JSON and serializes back to it +unchanged. + +```python +from opencode.types import ModelRef + +session = client.session.create(model=ModelRef(id="claude-sonnet-5-5", provider_id="anthropic")) +session.project_id # (1)! +session.to_dict() # (2)! +session.to_json(indent=2) +``` + +1. Attribute access in `snake_case`. +2. `{"id": "...", "projectID": "...", ...}`: wire names, unset fields left out. + +Requests accept either model instances or plain dicts with wire names. + +## Discriminated unions + +Unions are discriminated on their `type` field, so `isinstance` and `match` narrow them, and type checkers follow: + +```python +from opencode.types import SessionMessageAssistant, SessionMessageUser + +for message in client.message.list(session.id): + match message: + case SessionMessageUser(text=text): + print("user:", text) + case SessionMessageAssistant(): + print("assistant replied") + case _: + pass # (1)! +``` + +1. Always keep a fallback arm: it also catches variants added by newer servers. + +## Forward compatibility + +A client generated from an older contract keeps working against a newer server: + +- **New fields** are kept on the model and available as attributes and through `model_extra`. +- **New enum values** are accepted as plain strings. +- **New union variants** are parsed into an `Unknown...` fallback model with all their fields, rather than failing. +- **New event types** arrive as `UnknownEvent`. + +Validation errors on a response are raised as `APIResponseValidationError`, and report field locations and reasons +without values. diff --git a/docs/guides/pagination.md b/docs/guides/pagination.md new file mode 100644 index 0000000..48c2e2b --- /dev/null +++ b/docs/guides/pagination.md @@ -0,0 +1,35 @@ +# Pagination + +List endpoints with cursors return a page. Iterating a page fetches the following pages as needed. + +```python +for session in client.session.list(limit=50): # (1)! + print(session.title) +``` + +1. `limit` is the page size, not a cap on the total. + +To work page by page: + +```python +page = client.session.list(limit=50) +page.data # this page only +page.has_next_page() +next_page = page.next_page() + +for page in client.session.list(limit=50).iter_pages(): + print(len(page.data)) +``` + +## Async + +Async list methods return an `AsyncPaginator`. `await` it for the first page, or `async for` over it for every item: + +```python +first = await client.session.list(limit=50) +async for session in client.session.list(limit=50): + print(session.title) +``` + +Endpoints without cursors return a plain list or a response model. The [resources reference](../reference/resources.md) +shows each method's return type. diff --git a/docs/guides/retries.md b/docs/guides/retries.md new file mode 100644 index 0000000..9261d25 --- /dev/null +++ b/docs/guides/retries.md @@ -0,0 +1,38 @@ +# Retries and timeouts + +## Retries + +The client retries twice by default, with exponential backoff and jitter, and honors `Retry-After` up to 60 seconds. +Which requests are retried depends on whether they may already have run: + +| Method | Retried on | +| --- | --- | +| `GET`, `PUT`, `DELETE` | Connection errors, 408, 429, 500, 502, 503, 504 | +| `POST`, `PATCH` | Only when the request cannot have run: connection could not be opened, 429, 503 | + +So a prompt is never sent twice because a response was slow. + +```python +client = Opencode(max_retries=5) +client.with_options(max_retries=0).session.prompt(session_id, text="...") +``` + +## Timeouts + +The default is 10 minutes overall with a 10 second connect timeout. Set it per client, per derived client, or per +call. A float is seconds; an `httpx.Timeout` gives full control. + +```python +import httpx + +client = Opencode(timeout=30.0) +client.with_options(timeout=None).session.wait(session_id) # (1)! +client.session.get("ses_...", timeout=5.0) # (2)! +client = Opencode(timeout=httpx.Timeout(60.0, connect=2.0)) +``` + +1. `with_options` returns a client that shares the connection pool. `None` waits forever. +2. Per call. + +Event streams apply only the connect timeout unless you pass one, because they stay open between events. A timed-out +request raises `APITimeoutError`. diff --git a/docs/guides/sessions.md b/docs/guides/sessions.md new file mode 100644 index 0000000..257ce0c --- /dev/null +++ b/docs/guides/sessions.md @@ -0,0 +1,61 @@ +# Sessions and prompts + +A session is one conversation with an agent. The usual loop is: create a session, send a prompt, wait for the agent +to go idle, then read the messages. + +```python +from opencode import Opencode + +with Opencode() as client: + session = client.session.create(title="Fix tests", agent="build") # (1)! + client.session.prompt(session.id, text="Fix the failing test in tests/test_api.py") + client.session.wait(session.id) # (2)! + + for message in client.message.list(session.id): + print(message.type) +``` + +1. `agent` picks one of the server's agents; `client.agent.list()` shows them. +2. Blocks until the agent loop is idle. Long runs may exceed the default timeout; see below. + +## Waiting for long runs + +`wait()` uses the client's timeout (10 minutes by default). To wait as long as it takes: + +```python +client.with_options(timeout=None).session.wait(session.id) +``` + +To react to progress instead of blocking, subscribe to [events](events.md). + +## Prompt options + +```python +from opencode.types import PromptInputFileAttachment + +client.session.prompt( + session.id, + text="Review this file", + files=[PromptInputFileAttachment(...)], # (1)! + resume=True, # (2)! +) +``` + +1. Files, agents and skills can be attached to a prompt. +2. Resume the agent loop if it was interrupted. + +## Managing sessions + +| Task | Call | +| --- | --- | +| List sessions | `client.session.list()` | +| Rename | `client.session.update(session_id, title=...)` | +| Fork at a message | `client.session.fork(session_id, ...)` | +| Switch model | `client.session.switch_model(session_id, ...)` | +| Stop the agent | `client.session.interrupt(session_id)` | +| Compact history | `client.session.compact(session_id)` | +| Diff of changes | `client.session.diff(session_id)` | +| Delete | `client.session.remove(session_id)` | +| Revert changes | `client.session.revert.stage(session_id, message_id=...)` | + +The full list, with arguments, is in the [`SessionResource` reference](../reference/resources.md#opencode.resources.session.SessionResource). diff --git a/docs/hooks/types_reference.py b/docs/hooks/types_reference.py new file mode 100644 index 0000000..a577071 --- /dev/null +++ b/docs/hooks/types_reference.py @@ -0,0 +1,213 @@ +"""MkDocs hook that generates the resource and type reference pages and fills version placeholders. + +`opencode.types` holds ~640 generated models. One page per model would bloat the nav and one page for all of them +would be unusable, so this groups them by domain (the leading word of the class name, with events and session +messages split out) and writes one page per group. Pages are generated at build time from the source, so they +never drift from the code. +""" + +from __future__ import annotations + +import ast +import re +from collections import defaultdict +from pathlib import Path +from typing import TYPE_CHECKING, Any + +if TYPE_CHECKING: + from mkdocs.structure.files import Files + +ROOT = Path(__file__).resolve().parents[2] +TYPES_SRC = ROOT / "src/opencode/types/_generated.py" +RESOURCES_DIR = ROOT / "src/opencode/resources" +TYPES_DIR = "reference/types" +MIN_GROUP = 4 + +GROUP_TITLES = { + "Mcp": "MCP", + "Pty": "PTY", + "Rpc": "RPC", + "Vcs": "VCS", + "Tui": "TUI", + "Persistent": "Persistent PTY", + "Websearch": "Web search", +} + + +def _public_names() -> list[str]: + tree = ast.parse(TYPES_SRC.read_text()) + names: list[str] = [] + for node in tree.body: + if isinstance(node, ast.ClassDef): + names.append(node.name) + elif isinstance(node, ast.AnnAssign) and isinstance(node.target, ast.Name): + names.append(node.target.id) + elif isinstance(node, ast.Assign) and len(node.targets) == 1 and isinstance(node.targets[0], ast.Name): + names.append(node.targets[0].id) + return [n for n in names if not n.startswith("_") and n[0].isupper() and n != "__all__"] + + +def _group_of(name: str) -> str: + if name.endswith("Event"): + return "Events" + words = re.findall(r"[A-Z][a-z0-9]*", name) + if name.endswith("ErrorBody"): + return "Error bodies" + if words[0] == "Session" and len(words) > 1 and words[1] == "Message": + return "Session messages" + if words[0] == "Sessions": + return "Session" + return words[0] + + +def _slug(title: str) -> str: + return re.sub(r"[^a-z0-9]+", "-", title.lower()).strip("-") + + +def type_groups() -> dict[str, list[str]]: + raw: dict[str, list[str]] = defaultdict(list) + for name in _public_names(): + raw[_group_of(name)].append(name) + groups: dict[str, list[str]] = defaultdict(list) + for key, names in raw.items(): + target = key if len(names) >= MIN_GROUP or key in {"Events", "Error bodies"} else "Miscellaneous" + groups[GROUP_TITLES.get(target, target)].extend(names) + return dict(sorted(groups.items(), key=lambda kv: (kv[0] == "Miscellaneous", kv[0].lower()))) + + +def type_page(title: str, names: list[str]) -> str: + lines = [f"# {title}", "", f"{len(names)} types. Import any of them from `opencode.types`.", ""] + for name in sorted(names): + lines += [ + f"::: opencode.types.{name}", + " options:", + " heading_level: 2", + " show_bases: false", + " show_signature: false", + " members_order: source", + "", + ] + return "\n".join(lines) + + +def _types_index(groups: dict[str, list[str]]) -> str: + total = sum(len(v) for v in groups.values()) + lines = [ + "# Types", + "", + f"`opencode.types` has {total} generated models, unions and aliases, one for every request, response and " + "event in the OpenCode contract. They are grouped by domain below. Use search (++slash++) to jump to a " + "type by name.", + "", + "| Group | Types | Examples |", + "| --- | ---: | --- |", + ] + for title, names in groups.items(): + sample = ", ".join(f"`{n}`" for n in sorted(names)[:3]) + lines.append(f"| [{title}]({_slug(title)}.md) | {len(names)} | {sample} |") + return "\n".join(lines) + "\n" + + +def resources_page() -> str: + lines = [ + "# Resources", + "", + "Every resource is reachable as an attribute of the client, for example `client.session`. Each sync class " + "below has an `Async` twin with the same methods, which return awaitables. The method list with HTTP routes " + "is also in [api.md](https://github.com/shrijayan/opencode-python-sdk/blob/main/api.md).", + "", + ] + for path in sorted(RESOURCES_DIR.glob("*.py")): + if path.name.startswith("_"): + continue + tree = ast.parse(path.read_text()) + classes = [n.name for n in tree.body if isinstance(n, ast.ClassDef) and not n.name.startswith("Async")] + for cls in classes: + lines += [f"::: opencode.resources.{path.stem}.{cls}", " options:", " show_bases: false", ""] + return "\n".join(lines) + + +_GROUPS: dict[str, list[str]] = {} + + +def on_config(config: Any) -> Any: + _GROUPS.clear() + _GROUPS.update(type_groups()) + for section in config["nav"]: + if "API reference" not in section: + continue + for i, item in enumerate(section["API reference"]): + if isinstance(item, dict) and "Types" in item: + pages: list[Any] = [f"{TYPES_DIR}/index.md"] + pages += [{title: f"{TYPES_DIR}/{_slug(title)}.md"} for title in _GROUPS] + section["API reference"][i] = {"Types": pages} + return config + + +def _read_constant(path: Path, name: str) -> str: + match = re.search(rf'^{name}\s*=\s*"([^"]+)"', path.read_text(), re.M) + return match.group(1) if match else "unknown" + + +def on_page_markdown(markdown: str, page: Any, config: Any, files: Files) -> str: + """Fills ``{{ version }}`` and ``{{ api_version }}`` from the package source.""" + version = _read_constant(ROOT / "src/opencode/_version.py", "__version__") + api_version = _read_constant(ROOT / "src/opencode/__init__.py", "API_VERSION") + return markdown.replace("{{ version }}", version).replace("{{ api_version }}", api_version) + + +def on_files(files: Files, config: Any) -> Files: + from mkdocs.structure.files import File + + def add(path: str, content: str) -> None: + files.append(File.generated(config, path, content=content)) + + add(f"{TYPES_DIR}/index.md", _types_index(_GROUPS)) + for title, names in _GROUPS.items(): + add(f"{TYPES_DIR}/{_slug(title)}.md", type_page(title, names)) + add("reference/resources.md", resources_page()) + return files + + +_PAGES: list[tuple[str, str, str]] = [] + + +def on_page_content(html: str, page: Any, config: Any, files: Files) -> str: + """Records hand-written pages for ``llms.txt``. Generated reference pages are left out: they are huge.""" + if not page.file.generated_by and page.file.src_uri.endswith(".md"): + markdown = re.sub( + r'^--8<-- "([^"]+)"$', lambda m: (ROOT / m.group(1)).read_text(), page.markdown or "", flags=re.M + ) + _PAGES.append((page.title or page.file.src_uri, page.url, markdown)) + return html + + +def on_pre_build(config: Any) -> None: + _PAGES.clear() + + +def on_post_build(config: Any) -> None: + """Writes ``llms.txt`` (an index, per llmstxt.org) and ``llms-full.txt`` (every hand-written page).""" + base = config["site_url"] + site = Path(config["site_dir"]) + pages = sorted(_PAGES, key=lambda p: p[1]) + index = [ + f"# {config['site_name']}", + "", + f"> {config['site_description']} Install with `pip install opencode-python-sdk`; import as `opencode`.", + "", + "## Docs", + "", + ] + index += [f"- [{title}]({base}{url})" for title, url, _ in pages] + index += [ + "", + "## Optional", + "", + f"- [Full docs as one file]({base}llms-full.txt)", + "- [Method table with HTTP routes](https://github.com/shrijayan/opencode-python-sdk/blob/main/api.md)", + ] + (site / "llms.txt").write_text("\n".join(index) + "\n") + full = [f"# {config['site_name']}\n\n> {config['site_description']}\n"] + full += [f"\n---\n\nSource: {base}{url}\n\n{markdown.strip()}\n" for _, url, markdown in pages] + (site / "llms-full.txt").write_text("".join(full)) diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..e7da18f --- /dev/null +++ b/docs/index.md @@ -0,0 +1,138 @@ +--- +title: Typed Python client for OpenCode +description: opencode-python-sdk is a typed, sync and async Python client for the OpenCode 2.x server API. +hide: + - navigation + - toc +--- + +
+
+ +v{{ version }} for OpenCode server {{ api_version }} + +# Drive OpenCode from Python, fully typed. + +

All 142 operations of the OpenCode server API, sync and async, with pydantic models for every +request, response and event. Generated from the same contract as the official TypeScript client.

+ +
+ +```bash +pip install opencode-python-sdk +``` + +
+ +
+[![PyPI](https://img.shields.io/pypi/v/opencode-python-sdk?color=d9730d&label=pypi)](https://pypi.org/project/opencode-python-sdk/) +[![Python](https://img.shields.io/pypi/pyversions/opencode-python-sdk?color=0f6e6a)](https://pypi.org/project/opencode-python-sdk/) +[![CI](https://github.com/shrijayan/opencode-python-sdk/actions/workflows/ci.yml/badge.svg)](https://github.com/shrijayan/opencode-python-sdk/actions/workflows/ci.yml) +
+ +
+[Get started](getting-started/index.md){ .md-button .md-button--primary } +[API reference](reference/index.md){ .md-button } +
+ +
+
+ +=== "Sync" + + ```python + from opencode import OpencodeServer + + with OpencodeServer(cwd="/path/to/repo") as server: # (1)! + client = server.client() + session = client.session.create(title="Review") + client.session.prompt(session.id, text="Summarize the open TODOs") + client.session.wait(session.id) + + for message in client.message.list(session.id): # (2)! + print(message.type) + ``` + + 1. Starts `opencode serve` on a free port with a random password, and stops it on exit. + 2. Iterating a page fetches the following pages as needed. + +=== "Async" + + ```python + import asyncio + from opencode import AsyncOpencode + + + async def main() -> None: + async with AsyncOpencode("http://127.0.0.1:4096") as client: + session = await client.session.create(title="Review") + await client.session.prompt(session.id, text="Hello") + + async for message in client.message.list(session.id): + print(message.type) + + + asyncio.run(main()) # (1)! + ``` + + 1. Works with asyncio and trio. + +
+
+ +
+
+01 + +### Complete + +Every operation of the OpenCode 2.1 API, on `Opencode` and `AsyncOpencode`, with 96 typed event classes. +
+
+02 + +### Generated from the source + +The contract is exported from OpenCode's own Effect `HttpApi`, so names and shapes match the TypeScript client. +
+
+03 + +### Safe retries + +Only retries when a request cannot have changed server state. A prompt is never sent twice. +
+
+04 + +### Forward compatible + +New fields, enum values, union variants and events from newer servers are kept, not rejected. +
+
+05 + +### Typed errors + +Every error the server declares is its own exception class with a typed body. +
+
+06 + +### Batteries included + +Launch `opencode serve`, paginate lists, and stream server-sent events with one call each. +
+
+ +## Where to next { .oc-section-title } + +- [Connect to a server](getting-started/connect.md) you already run, or [start one from Python](getting-started/server.md). +- Read the [sessions and prompts guide](guides/sessions.md) for the core workflow. +- Browse the [API reference](reference/index.md), or search it with ++slash++. +- Using an LLM? Point it at [`llms.txt`](https://shrijayan.github.io/opencode-python-sdk/llms.txt) or [`llms-full.txt`](https://shrijayan.github.io/opencode-python-sdk/llms-full.txt). + +!!! note "Unofficial" + + This package is community-maintained and not affiliated with or endorsed by the OpenCode team. If the OpenCode + maintainers want to take it over, the repository and the PyPI name will be transferred. diff --git a/docs/project/changelog.md b/docs/project/changelog.md new file mode 100644 index 0000000..786b75d --- /dev/null +++ b/docs/project/changelog.md @@ -0,0 +1 @@ +--8<-- "CHANGELOG.md" diff --git a/docs/project/contributing.md b/docs/project/contributing.md new file mode 100644 index 0000000..ea38c9b --- /dev/null +++ b/docs/project/contributing.md @@ -0,0 +1 @@ +--8<-- "CONTRIBUTING.md" diff --git a/docs/project/how-its-built.md b/docs/project/how-its-built.md new file mode 100644 index 0000000..6ee6a94 --- /dev/null +++ b/docs/project/how-its-built.md @@ -0,0 +1,44 @@ +# How it's built + +Most of this package is generated. The models, resources, error classes and `api.md` come from OpenCode's own +contract; the transport, retries, streaming, pagination and server launcher are written by hand. + +```text +@opencode/protocol (npm) ──bun codegen/extract──▶ spec/contract.json ──python -m codegen──▶ src/opencode +``` + +## 1. Extract the contract + +`codegen/extract/extract.ts` loads `ClientApi` from the published `@opencode/protocol` package, the same Effect +`HttpApi` definition the official TypeScript client is built from. It exports every endpoint with its inputs, +outputs and declared errors, and every schema as JSON Schema, into `spec/contract.json`. + +Because the contract comes from the server's source of truth rather than a hand-written OpenAPI file, method names +and request shapes match the TypeScript client exactly. + +## 2. Generate Python + +`python -m codegen` reads the contract and writes: + +| Output | What it contains | +| --- | --- | +| `src/opencode/types/` | pydantic models for every schema, discriminated unions with `Unknown...` fallbacks, open enums | +| `src/opencode/resources/` | A sync and an async class per API group, with typed arguments and docstrings | +| `src/opencode/_errors.py` | An exception class for every declared server error | +| `api.md` | The method table | + +## 3. Hand-written runtime + +| Module | Responsibility | +| --- | --- | +| `_base_client.py` | Request building, auth, retries with backoff, timeouts | +| `_pagination.py` | Cursor pages and the async paginator | +| `_streaming.py` | Server-sent event decoding | +| `_server.py` | `OpencodeServer` | +| `_models.py`, `_types.py` | Model base class, `NOT_GIVEN`, open enums | + +## Keeping it current + +Generated code is committed. CI regenerates it and fails if anything changed, so the committed code always matches +`spec/contract.json`. A nightly workflow checks for new `@opencode/protocol` releases and opens a pull request with +the regenerated client. See [Contributing](contributing.md) for running it locally. diff --git a/docs/project/security.md b/docs/project/security.md new file mode 100644 index 0000000..a8ada70 --- /dev/null +++ b/docs/project/security.md @@ -0,0 +1 @@ +--8<-- "SECURITY.md" diff --git a/docs/project/versioning.md b/docs/project/versioning.md new file mode 100644 index 0000000..ec0113b --- /dev/null +++ b/docs/project/versioning.md @@ -0,0 +1,20 @@ +# Versioning and releases + +| `opencode-python-sdk` | OpenCode server | +| --- | --- | +| 0.1.x | 2.1.x | + +`opencode.API_VERSION` is the server version the client was generated from. + +The package follows [semantic versioning](https://semver.org). Until 1.0, minor versions may contain breaking changes; +each is noted in the [changelog](changelog.md). + +## Compatibility with newer servers + +A client keeps working when the server is upgraded within a major version: new fields, enum values, union variants +and event types are kept rather than rejected. See [forward compatibility](../guides/models.md#forward-compatibility). + +## Releases + +Releases are published to [PyPI](https://pypi.org/project/opencode-python-sdk/) from GitHub Actions with trusted +publishing and build attestations, so no API token is stored in the repository. diff --git a/docs/reference/clients.md b/docs/reference/clients.md new file mode 100644 index 0000000..547291b --- /dev/null +++ b/docs/reference/clients.md @@ -0,0 +1,23 @@ +# Clients + +::: opencode.Opencode + options: + members: [with_options, close] + show_bases: false + +::: opencode.AsyncOpencode + options: + members: [with_options, close] + show_bases: false + +## Module constants + +::: opencode.API_VERSION + +::: opencode.NOT_GIVEN + +::: opencode.NotGiven + +::: opencode.BaseModel + options: + members: [to_dict, to_json] diff --git a/docs/reference/exceptions.md b/docs/reference/exceptions.md new file mode 100644 index 0000000..e186e2d --- /dev/null +++ b/docs/reference/exceptions.md @@ -0,0 +1,205 @@ +# Exceptions + +See the [errors guide](../guides/errors.md) for the hierarchy and how to catch them. + +## Base and status errors + +::: opencode.OpencodeError + options: + heading_level: 3 + +::: opencode.APIError + options: + heading_level: 3 + +::: opencode.APIConnectionError + options: + heading_level: 3 + +::: opencode.APITimeoutError + options: + heading_level: 3 + +::: opencode.APIResponseValidationError + options: + heading_level: 3 + +::: opencode.APIStatusError + options: + heading_level: 3 + +::: opencode.BadRequestError + options: + heading_level: 3 + +::: opencode.AuthenticationError + options: + heading_level: 3 + +::: opencode.PermissionDeniedError + options: + heading_level: 3 + +::: opencode.NotFoundError + options: + heading_level: 3 + +::: opencode.ConflictError + options: + heading_level: 3 + +::: opencode.ContentTooLargeError + options: + heading_level: 3 + +::: opencode.UnprocessableEntityError + options: + heading_level: 3 + +::: opencode.RateLimitError + options: + heading_level: 3 + +::: opencode.InternalServerError + options: + heading_level: 3 + +::: opencode.NotImplementedServerError + options: + heading_level: 3 + +::: opencode.ServiceUnavailableError + options: + heading_level: 3 + +## Declared server errors + +Raised when the server returns an error it declares in its contract. Each has a typed body on `.error`. + +::: opencode.AgentNotFoundError + options: + heading_level: 3 + +::: opencode.CommandExecutionError + options: + heading_level: 3 + +::: opencode.CommandNotFoundError + options: + heading_level: 3 + +::: opencode.ForbiddenError + options: + heading_level: 3 + +::: opencode.FormAlreadySettledError + options: + heading_level: 3 + +::: opencode.FormInvalidAnswerError + options: + heading_level: 3 + +::: opencode.FormNotFoundError + options: + heading_level: 3 + +::: opencode.InstructionEntryValueTooLargeError + options: + heading_level: 3 + +::: opencode.IntegrationAttemptNotFoundError + options: + heading_level: 3 + +::: opencode.IntegrationMethodNotFoundError + options: + heading_level: 3 + +::: opencode.IntegrationNotFoundError + options: + heading_level: 3 + +::: opencode.InvalidCursorError + options: + heading_level: 3 + +::: opencode.InvalidRequestError + options: + heading_level: 3 + +::: opencode.LocationNotFoundError + options: + heading_level: 3 + +::: opencode.McpServerNotFoundError + options: + heading_level: 3 + +::: opencode.MessageNotFoundError + options: + heading_level: 3 + +::: opencode.PermissionNotFoundError + options: + heading_level: 3 + +::: opencode.PermissionSavedNotFoundError + options: + heading_level: 3 + +::: opencode.ProjectNotFoundError + options: + heading_level: 3 + +::: opencode.ProviderNotFoundError + options: + heading_level: 3 + +::: opencode.PtyNotFoundError + options: + heading_level: 3 + +::: opencode.RemoteFileNotFoundError + options: + heading_level: 3 + +::: opencode.RpcError + options: + heading_level: 3 + +::: opencode.RpcInternalError + options: + heading_level: 3 + +::: opencode.SessionBusyError + options: + heading_level: 3 + +::: opencode.SessionNotFoundError + options: + heading_level: 3 + +::: opencode.ShellNotFoundError + options: + heading_level: 3 + +::: opencode.SkillNotFoundError + options: + heading_level: 3 + +::: opencode.UnauthorizedError + options: + heading_level: 3 + +::: opencode.UnknownError + options: + heading_level: 3 + +::: opencode.VcsInitNotSupportedError + options: + heading_level: 3 + +::: opencode.WorktreeError + options: + heading_level: 3 diff --git a/docs/reference/index.md b/docs/reference/index.md new file mode 100644 index 0000000..f54eeb5 --- /dev/null +++ b/docs/reference/index.md @@ -0,0 +1,15 @@ +# API reference + +Generated from the docstrings in `src/opencode`. + +| Page | Contents | +| --- | --- | +| [Clients](clients.md) | `Opencode`, `AsyncOpencode` | +| [Server launcher](server.md) | `OpencodeServer`, `AsyncOpencodeServer` | +| [Resources](resources.md) | Every `client.` and its methods | +| [Pagination and streams](pagination.md) | `SyncCursorPage`, `AsyncPaginator`, `Stream`, `AsyncStream` | +| [Exceptions](exceptions.md) | Status errors and every declared server error | +| [Types](types/index.md) | The models in `opencode.types`, grouped by domain | + +The method table with HTTP routes is also in +[api.md](https://github.com/shrijayan/opencode-python-sdk/blob/main/api.md). diff --git a/docs/reference/pagination.md b/docs/reference/pagination.md new file mode 100644 index 0000000..4a83486 --- /dev/null +++ b/docs/reference/pagination.md @@ -0,0 +1,11 @@ +# Pagination and streams + +::: opencode.SyncCursorPage + +::: opencode.AsyncCursorPage + +::: opencode.AsyncPaginator + +::: opencode.Stream + +::: opencode.AsyncStream diff --git a/docs/reference/server.md b/docs/reference/server.md new file mode 100644 index 0000000..3fbf53e --- /dev/null +++ b/docs/reference/server.md @@ -0,0 +1,7 @@ +# Server launcher + +::: opencode.OpencodeServer + +::: opencode.AsyncOpencodeServer + +::: opencode.ServerStartError diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css new file mode 100644 index 0000000..7574253 --- /dev/null +++ b/docs/stylesheets/extra.css @@ -0,0 +1,235 @@ +/* Palette: warm paper and ink, with a signal-amber accent and a deep teal for links. + Headings use Fraunces; body IBM Plex Sans; code JetBrains Mono (set in mkdocs.yml). */ +@import url("https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,650&display=swap"); + +:root { + --oc-amber: #d9730d; + --oc-amber-soft: #f6e3cc; + --oc-teal: #0f6e6a; + --oc-ink: #1b1714; + --oc-paper: #fbf8f3; + --oc-rule: #e7dfd3; + --oc-card: #ffffff; + --oc-heading-font: "Fraunces", Georgia, serif; +} + +[data-md-color-scheme="default"] { + --md-primary-fg-color: var(--oc-ink); + --md-primary-fg-color--light: #3a332d; + --md-primary-fg-color--dark: #000; + --md-primary-bg-color: var(--oc-paper); + --md-accent-fg-color: var(--oc-amber); + --md-accent-fg-color--transparent: rgba(217, 115, 13, 0.1); + --md-default-bg-color: var(--oc-paper); + --md-default-fg-color: var(--oc-ink); + --md-typeset-a-color: var(--oc-teal); + --md-code-bg-color: #f3ede4; + --md-code-fg-color: #2a241f; + --md-footer-bg-color: var(--oc-ink); + --md-footer-bg-color--dark: #0f0c0a; +} + +[data-md-color-scheme="slate"] { + --oc-rule: #2e2924; + --oc-card: #1c1917; + --oc-amber-soft: rgba(242, 153, 74, 0.14); + --md-hue: 30; + --md-primary-fg-color: #14110f; + --md-primary-fg-color--light: #2a2521; + --md-primary-fg-color--dark: #0b0908; + --md-primary-bg-color: #f4efe6; + --md-accent-fg-color: #f2994a; + --md-accent-fg-color--transparent: rgba(242, 153, 74, 0.12); + --md-default-bg-color: #14110f; + --md-default-fg-color: rgba(244, 239, 230, 0.92); + --md-default-fg-color--light: rgba(244, 239, 230, 0.66); + --md-default-fg-color--lighter: rgba(244, 239, 230, 0.4); + --md-typeset-a-color: #5fc2b9; + --md-code-bg-color: #1e1a17; + --md-code-fg-color: #ece4d8; + --md-footer-bg-color: #0b0908; + --md-footer-bg-color--dark: #070605; +} + +.md-header, +.md-tabs { + border-bottom: 1px solid var(--oc-rule); +} +[data-md-color-scheme="default"] .md-header, +[data-md-color-scheme="default"] .md-tabs { + background-color: var(--oc-paper); + color: var(--oc-ink); +} +.md-header__title { + font-family: var(--md-code-font-family); + font-weight: 600; + letter-spacing: -0.01em; +} + +.md-typeset h1, +.md-typeset h2, +.md-typeset h3 { + font-family: var(--oc-heading-font); + font-weight: 650; + letter-spacing: -0.015em; + color: var(--md-default-fg-color); +} +.md-typeset h1 { + font-size: 2.1rem; +} +/* mkdocstrings headings stay monospace: they are code. */ +.md-typeset .doc-heading, +.md-typeset h2.doc-heading, +.md-typeset h3.doc-heading { + font-family: var(--md-code-font-family); + font-weight: 600; + letter-spacing: 0; +} + +.md-typeset code { + border-radius: 4px; +} +.md-typeset pre > code { + border: 1px solid var(--oc-rule); + border-radius: 8px; +} +.md-typeset .admonition, +.md-typeset details { + border-radius: 8px; + box-shadow: none; +} +.md-typeset table:not([class]) { + border-radius: 8px; + border: 1px solid var(--oc-rule); + font-size: 0.72rem; +} +.md-typeset table:not([class]) th { + background: var(--md-code-bg-color); +} + +/* ---------- Landing page ---------- */ +.oc-hero { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); + gap: 2.4rem; + align-items: center; + padding: 2.4rem 0 1.6rem; +} +.oc-hero h1 { + font-size: 2.6rem; + line-height: 1.08; + margin: 0.4rem 0 1rem; +} +.oc-hero h1 em { + font-style: italic; + color: var(--md-accent-fg-color); +} +.oc-eyebrow { + font-family: var(--md-code-font-family); + font-size: 0.68rem; + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--md-default-fg-color--light); +} +.oc-chip { + display: inline-block; + font-family: var(--md-code-font-family); + font-size: 0.66rem; + font-weight: 600; + padding: 0.1rem 0.5rem; + margin-right: 0.4rem; + border-radius: 999px; + background: var(--oc-amber-soft); + color: var(--md-accent-fg-color); +} +.oc-lede { + font-size: 0.95rem; + color: var(--md-default-fg-color--light); + max-width: 34rem; +} +.oc-install { + margin: 1.2rem 0 0.8rem; +} +.oc-install pre { + margin: 0; +} +.oc-badges img { + margin-right: 0.3rem; + vertical-align: middle; +} +.md-typeset .oc-actions .md-button { + margin: 0.4rem 0.5rem 0 0; + border-radius: 6px; +} +.md-typeset .oc-actions .md-button--primary { + background: var(--md-accent-fg-color); + border-color: var(--md-accent-fg-color); + color: #fff; +} + +.oc-grid { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 0; + border-top: 1px solid var(--oc-rule); + border-left: 1px solid var(--oc-rule); + margin: 2rem 0; +} +.oc-grid > div { + padding: 1.1rem 1.2rem 1.2rem; + border-right: 1px solid var(--oc-rule); + border-bottom: 1px solid var(--oc-rule); + background: var(--oc-card); +} +.oc-grid h3 { + margin: 0 0 0.4rem; + font-size: 0.95rem; +} +.oc-grid p { + margin: 0; + font-size: 0.74rem; + color: var(--md-default-fg-color--light); +} +.oc-grid .oc-num { + font-family: var(--md-code-font-family); + font-size: 0.65rem; + color: var(--md-accent-fg-color); +} + +.oc-section-title { + margin-top: 2.4rem !important; +} + +@media screen and (max-width: 60em) { + .oc-hero { + grid-template-columns: minmax(0, 1fr); + gap: 1rem; + padding-top: 1rem; + } + .oc-hero h1 { + font-size: 1.7rem; + overflow-wrap: anywhere; + } + .oc-grid { + grid-template-columns: minmax(0, 1fr); + } +} +@media screen and (min-width: 60em) and (max-width: 76em) { + .oc-grid { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } +} + +.md-typeset .oc-actions .md-button:not(.md-button--primary) { + color: var(--md-default-fg-color); + border-color: var(--md-default-fg-color--lighter); +} +.md-typeset .oc-actions .md-button:not(.md-button--primary):hover { + border-color: var(--md-accent-fg-color); + color: var(--md-accent-fg-color); + background: transparent; +} +/* The landing page is hand-built; an edit link there points at markup, not prose. */ +.md-content:has(.oc-hero) .md-content__button { + display: none; +} diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..2f7693a --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,160 @@ +site_name: opencode-python-sdk +site_url: https://shrijayan.github.io/opencode-python-sdk/ +site_description: Typed Python client for the OpenCode 2.x server API. +site_author: Shrijayan Rajendran +repo_url: https://github.com/shrijayan/opencode-python-sdk +repo_name: shrijayan/opencode-python-sdk +edit_uri: edit/main/docs/ +copyright: MIT licensed. Unofficial and community-maintained; not affiliated with the OpenCode team. + +exclude_docs: | + design.html + +theme: + name: material + logo: assets/logo.svg + favicon: assets/logo.svg + icon: + repo: fontawesome/brands/github + font: + text: IBM Plex Sans + code: JetBrains Mono + palette: + - media: "(prefers-color-scheme)" + toggle: + icon: material/brightness-auto + name: Switch to light mode + - media: "(prefers-color-scheme: light)" + scheme: default + primary: custom + accent: custom + toggle: + icon: material/weather-sunny + name: Switch to dark mode + - media: "(prefers-color-scheme: dark)" + scheme: slate + primary: custom + accent: custom + toggle: + icon: material/weather-night + name: Switch to system preference + features: + - navigation.instant + - navigation.instant.progress + - navigation.tracking + - navigation.tabs + - navigation.sections + - navigation.top + - navigation.footer + - navigation.indexes + - toc.follow + - search.suggest + - search.highlight + - search.share + - content.code.copy + - content.code.annotate + - content.tabs.link + - content.action.edit + - content.tooltips + +extra_css: + - stylesheets/extra.css + +hooks: + - docs/hooks/types_reference.py + +plugins: + - search + - social: + enabled: !ENV [SOCIAL_CARDS, false] + cards_layout_options: + background_color: "#14110f" + color: "#f4efe6" + font_family: IBM Plex Sans + - mkdocstrings: + default_handler: python + handlers: + python: + paths: [src] + inventories: + - https://docs.python.org/3/objects.inv + options: + docstring_style: google + show_source: false + show_root_heading: true + show_root_full_path: false + show_symbol_type_heading: true + show_symbol_type_toc: true + show_signature_annotations: true + separate_signature: true + signature_crossrefs: true + members_order: source + merge_init_into_class: true + filters: ["!^_"] + show_if_no_docstring: true + heading_level: 2 + +markdown_extensions: + - abbr + - admonition + - attr_list + - md_in_html + - tables + - footnotes + - toc: + permalink: true + toc_depth: 2 + - pymdownx.details + - pymdownx.superfences + - pymdownx.highlight: + anchor_linenums: true + line_spans: __span + pygments_lang_class: true + - pymdownx.inlinehilite + - pymdownx.snippets: + check_paths: true + - pymdownx.tabbed: + alternate_style: true + - pymdownx.emoji: + emoji_index: !!python/name:material.extensions.emoji.twemoji + emoji_generator: !!python/name:material.extensions.emoji.to_svg + +extra: + social: + - icon: fontawesome/brands/github + link: https://github.com/shrijayan/opencode-python-sdk + - icon: fontawesome/brands/python + link: https://pypi.org/project/opencode-python-sdk/ + +nav: + - Home: index.md + - Getting started: + - getting-started/index.md + - Connect to a server: getting-started/connect.md + - Run a server from Python: getting-started/server.md + - Guides: + - guides/index.md + - Sessions and prompts: guides/sessions.md + - Async: guides/async.md + - Models and unions: guides/models.md + - Pagination: guides/pagination.md + - Events and streaming: guides/events.md + - Errors: guides/errors.md + - Retries and timeouts: guides/retries.md + - The project directory: guides/directory.md + - Advanced httpx config: guides/httpx.md + - Logging: guides/logging.md + - API reference: + - reference/index.md + - Clients: reference/clients.md + - Server launcher: reference/server.md + - Resources: reference/resources.md + - Pagination and streams: reference/pagination.md + - Exceptions: reference/exceptions.md + - Types: reference/types/index.md + - Project: + - How it's built: project/how-its-built.md + - Contributing: project/contributing.md + - Versioning and releases: project/versioning.md + - Security: project/security.md + - Changelog: project/changelog.md diff --git a/pyproject.toml b/pyproject.toml index a0c6f09..939b9c2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,7 @@ dependencies = [ [project.urls] Homepage = "https://github.com/shrijayan/opencode-python-sdk" -Documentation = "https://github.com/shrijayan/opencode-python-sdk#readme" +Documentation = "https://shrijayan.github.io/opencode-python-sdk/" Repository = "https://github.com/shrijayan/opencode-python-sdk" Issues = "https://github.com/shrijayan/opencode-python-sdk/issues" Changelog = "https://github.com/shrijayan/opencode-python-sdk/blob/main/CHANGELOG.md" @@ -49,6 +49,10 @@ dev = [ "ruff>=0.14", "trio>=0.31", ] +docs = [ + "mkdocs-material[imaging]>=9.6", + "mkdocstrings[python]>=0.30", +] [build-system] requires = ["hatchling>=1.27", "hatch-vcs>=0.5"] @@ -93,6 +97,7 @@ src = ["src", "tests", "codegen"] select = [ "B", # bugbear "C4", # comprehensions + "D1", # missing docstrings (public modules only; tests/test_docs_coverage.py covers the private runtime modules) "E", # pycodestyle errors "F", # pyflakes "FA", # future annotations @@ -107,6 +112,8 @@ select = [ "W", # pycodestyle warnings ] ignore = [ + "D105", # magic methods + "D107", # __init__: arguments are documented on the class "E501", # line length is handled by the formatter "RUF022", # __all__ keeps a readable, grouped order ] @@ -116,10 +123,12 @@ ignore = [ "src/opencode/types/**" = ["E741", "TC"] "src/opencode/resources/**" = ["TC"] "src/opencode/_errors.py" = ["TC"] -"codegen/**" = ["T20"] -"scripts/**" = ["T20"] -"examples/**" = ["T20"] -"tests/**" = ["E501", "TC"] +# D1 applies to the published package only. +"codegen/**" = ["T20", "D1"] +"scripts/**" = ["T20", "D1"] +"examples/**" = ["T20", "D1"] +"tests/**" = ["E501", "TC", "D1"] +"docs/**" = ["D1"] [tool.ruff.lint.isort] known-first-party = ["opencode", "codegen"] diff --git a/src/opencode/_exceptions.py b/src/opencode/_exceptions.py index 7b4d8c5..31e9ef1 100644 --- a/src/opencode/_exceptions.py +++ b/src/opencode/_exceptions.py @@ -147,47 +147,69 @@ def __str__(self) -> str: class BadRequestError(APIStatusError): + """The server rejected the request as malformed (400).""" + status = 400 class AuthenticationError(APIStatusError): + """The password was missing or wrong (401).""" + status = 401 class PermissionDeniedError(APIStatusError): + """The request is not allowed (403).""" + status = 403 class NotFoundError(APIStatusError): + """The requested resource does not exist (404).""" + status = 404 class ConflictError(APIStatusError): + """The request conflicts with the current state, for example a busy session (409).""" + status = 409 tag = "ConflictError" class ContentTooLargeError(APIStatusError): + """The request body is too large (413).""" + status = 413 class UnprocessableEntityError(APIStatusError): + """The request was well formed but could not be processed (422).""" + status = 422 class RateLimitError(APIStatusError): + """Too many requests (429). Retried automatically, honoring ``Retry-After``.""" + status = 429 class InternalServerError(APIStatusError): + """The server failed (500, and the base class for every 5xx).""" + status = 500 class NotImplementedServerError(InternalServerError): + """The server does not implement this endpoint (501).""" + status = 501 class ServiceUnavailableError(InternalServerError): + """The server is temporarily unavailable (503). Retried automatically.""" + status = 503 tag = "ServiceUnavailableError" diff --git a/src/opencode/_server.py b/src/opencode/_server.py index 5a63701..4aae6da 100644 --- a/src/opencode/_server.py +++ b/src/opencode/_server.py @@ -109,10 +109,12 @@ def url(self) -> str: @property def process(self) -> subprocess.Popen[str] | None: + """The ``opencode serve`` child process, or ``None`` before it starts.""" return self._process @property def running(self) -> bool: + """Whether the server process is alive.""" return self._process is not None and self._process.poll() is None def client(self, *, directory: str | os.PathLike[str] | None = None, timeout: Timeout | None = None) -> Opencode: @@ -291,18 +293,22 @@ def __init__(self, **kwargs: Any) -> None: @property def url(self) -> str: + """The server's base URL. Available once started.""" return self._server.url @property def password(self) -> str: + """The server password clients authenticate with.""" return self._server.password @property def running(self) -> bool: + """Whether the server process is alive.""" return self._server.running @property def output(self) -> str: + """The last lines the server wrote, for diagnostics.""" return self._server.output def client( @@ -312,10 +318,12 @@ def client( return self._server.async_client(directory=directory, timeout=timeout) async def start(self) -> Self: + """Starts the server and waits until it reports its address.""" await anyio.to_thread.run_sync(self._server.start) return self async def stop(self, timeout: float = 10.0) -> None: + """Stops the server: closes its stdin, then terminates it if it has not exited within ``timeout``.""" await anyio.to_thread.run_sync(lambda: self._server.stop(timeout)) async def __aenter__(self) -> Self: diff --git a/src/opencode/resources/agent.py b/src/opencode/resources/agent.py index 98e1d82..5074724 100644 --- a/src/opencode/resources/agent.py +++ b/src/opencode/resources/agent.py @@ -38,9 +38,9 @@ def list( Retrieve currently registered agents. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/agent`` """ @@ -75,10 +75,10 @@ def get( Retrieve a single currently registered agent. Raises: - InvalidRequestError - UnauthorizedError - AgentNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + AgentNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/agent/:agentID`` """ @@ -116,9 +116,9 @@ async def list( Retrieve currently registered agents. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/agent`` """ @@ -153,10 +153,10 @@ async def get( Retrieve a single currently registered agent. Raises: - InvalidRequestError - UnauthorizedError - AgentNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + AgentNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/agent/:agentID`` """ diff --git a/src/opencode/resources/command.py b/src/opencode/resources/command.py index 6f9692c..68291eb 100644 --- a/src/opencode/resources/command.py +++ b/src/opencode/resources/command.py @@ -35,9 +35,9 @@ def list( Retrieve currently registered commands. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/command`` """ @@ -75,9 +75,9 @@ async def list( Retrieve currently registered commands. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/command`` """ diff --git a/src/opencode/resources/config.py b/src/opencode/resources/config.py index 4df8504..18af343 100644 --- a/src/opencode/resources/config.py +++ b/src/opencode/resources/config.py @@ -37,9 +37,9 @@ def get( Return configuration documents and discovery sources for the requested location, from lowest to highest priority. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/config`` """ @@ -72,9 +72,9 @@ def shells( Return shells available to terminal and agent execution. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/config/shell`` """ @@ -109,9 +109,9 @@ def update( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``PATCH /api/experimental/config`` """ @@ -146,9 +146,9 @@ async def get( Return configuration documents and discovery sources for the requested location, from lowest to highest priority. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/config`` """ @@ -181,9 +181,9 @@ async def shells( Return shells available to terminal and agent execution. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/config/shell`` """ @@ -218,9 +218,9 @@ async def update( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``PATCH /api/experimental/config`` """ diff --git a/src/opencode/resources/credential.py b/src/opencode/resources/credential.py index 2b50999..005e545 100644 --- a/src/opencode/resources/credential.py +++ b/src/opencode/resources/credential.py @@ -38,8 +38,8 @@ def list( List every stored integration credential, including its secret value. Raises: - InvalidRequestError - UnauthorizedError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``GET /api/credential`` """ @@ -77,9 +77,9 @@ def create( Store an integration credential. It becomes the integration's active credential unless activate is false and the integration already has one. Fails with a conflict when the requested ID already exists. Raises: - InvalidRequestError - UnauthorizedError - ConflictError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ConflictError: The server answered 409. ``POST /api/credential`` """ @@ -121,8 +121,8 @@ def update( Update a stored credential label. Raises: - InvalidRequestError - UnauthorizedError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``PATCH /api/credential/:credentialID`` """ @@ -153,8 +153,8 @@ def activate( Activate a stored integration credential. Raises: - InvalidRequestError - UnauthorizedError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``POST /api/credential/:credentialID/activate`` """ @@ -184,8 +184,8 @@ def remove( Remove a stored integration credential. Raises: - InvalidRequestError - UnauthorizedError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``DELETE /api/credential/:credentialID`` """ @@ -218,8 +218,8 @@ async def list( List every stored integration credential, including its secret value. Raises: - InvalidRequestError - UnauthorizedError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``GET /api/credential`` """ @@ -257,9 +257,9 @@ async def create( Store an integration credential. It becomes the integration's active credential unless activate is false and the integration already has one. Fails with a conflict when the requested ID already exists. Raises: - InvalidRequestError - UnauthorizedError - ConflictError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ConflictError: The server answered 409. ``POST /api/credential`` """ @@ -301,8 +301,8 @@ async def update( Update a stored credential label. Raises: - InvalidRequestError - UnauthorizedError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``PATCH /api/credential/:credentialID`` """ @@ -333,8 +333,8 @@ async def activate( Activate a stored integration credential. Raises: - InvalidRequestError - UnauthorizedError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``POST /api/credential/:credentialID/activate`` """ @@ -364,8 +364,8 @@ async def remove( Remove a stored integration credential. Raises: - InvalidRequestError - UnauthorizedError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``DELETE /api/credential/:credentialID`` """ diff --git a/src/opencode/resources/debug.py b/src/opencode/resources/debug.py index ccad119..d1f2442 100644 --- a/src/opencode/resources/debug.py +++ b/src/opencode/resources/debug.py @@ -36,8 +36,8 @@ def list( List locations currently loaded by the server. Raises: - InvalidRequestError - UnauthorizedError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``GET /api/debug/location`` """ @@ -70,8 +70,8 @@ def evict( Dispose the requested location's cached services so its next use boots them fresh. Raises: - InvalidRequestError - UnauthorizedError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``DELETE /api/debug/location`` """ @@ -94,6 +94,7 @@ class DebugResource(SyncAPIResource): @cached_property def location(self) -> DebugLocationResource: + """Operations under ``client.debug.location``.""" return DebugLocationResource(self._client) @@ -113,8 +114,8 @@ async def list( List locations currently loaded by the server. Raises: - InvalidRequestError - UnauthorizedError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``GET /api/debug/location`` """ @@ -147,8 +148,8 @@ async def evict( Dispose the requested location's cached services so its next use boots them fresh. Raises: - InvalidRequestError - UnauthorizedError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``DELETE /api/debug/location`` """ @@ -171,4 +172,5 @@ class AsyncDebugResource(AsyncAPIResource): @cached_property def location(self) -> AsyncDebugLocationResource: + """Operations under ``client.debug.location``.""" return AsyncDebugLocationResource(self._client) diff --git a/src/opencode/resources/event.py b/src/opencode/resources/event.py index b8cc168..0706f59 100644 --- a/src/opencode/resources/event.py +++ b/src/opencode/resources/event.py @@ -32,8 +32,8 @@ def subscribe( Subscribe to native events and plugin RPC events across all server locations. Volatile by contract: a slow consumer overflows and fails the stream, and events during disconnection are missed. Raises: - InvalidRequestError - UnauthorizedError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``GET /api/event`` """ @@ -66,8 +66,8 @@ async def subscribe( Subscribe to native events and plugin RPC events across all server locations. Volatile by contract: a slow consumer overflows and fails the stream, and events during disconnection are missed. Raises: - InvalidRequestError - UnauthorizedError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``GET /api/event`` """ diff --git a/src/opencode/resources/experimental.py b/src/opencode/resources/experimental.py index 866f5b0..01ba58b 100644 --- a/src/opencode/resources/experimental.py +++ b/src/opencode/resources/experimental.py @@ -50,9 +50,9 @@ def read( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ServiceUnavailableError: The server answered 503. ``GET /api/experimental/session/:sessionID/terminal/read`` """ @@ -85,9 +85,9 @@ def list( """This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ServiceUnavailableError: The server answered 503. ``GET /api/experimental/session/:sessionID/terminal`` """ @@ -125,9 +125,9 @@ def create( """This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ServiceUnavailableError: The server answered 503. ``POST /api/experimental/session/:sessionID/terminal`` """ @@ -159,9 +159,9 @@ def shutdown( """This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ServiceUnavailableError: The server answered 503. ``POST /api/experimental/persistent-pty/shutdown`` """ @@ -188,9 +188,9 @@ def handoff( """This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ServiceUnavailableError: The server answered 503. ``POST /api/experimental/persistent-pty/handoff`` """ @@ -221,10 +221,10 @@ def get( """This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - PtyNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + PtyNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``GET /api/experimental/persistent-pty/:ptyID`` """ @@ -258,10 +258,10 @@ def update( """This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - PtyNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + PtyNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``PUT /api/experimental/persistent-pty/:ptyID`` """ @@ -294,10 +294,10 @@ def snapshot( """This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - PtyNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + PtyNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``GET /api/experimental/persistent-pty/:ptyID/snapshot`` """ @@ -329,10 +329,10 @@ def remove( """This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - PtyNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + PtyNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``DELETE /api/experimental/persistent-pty/:ptyID`` """ @@ -361,11 +361,11 @@ def connect_token( """This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - ForbiddenError - PtyNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ForbiddenError: The server answered 403. + PtyNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``POST /api/experimental/persistent-pty/:ptyID/connect-token`` """ @@ -392,6 +392,7 @@ class ExperimentalResource(SyncAPIResource): @cached_property def persistent_pty(self) -> ExperimentalPersistentPtyResource: + """Operations under ``client.experimental.persistent_pty``.""" return ExperimentalPersistentPtyResource(self._client) @@ -415,9 +416,9 @@ async def read( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ServiceUnavailableError: The server answered 503. ``GET /api/experimental/session/:sessionID/terminal/read`` """ @@ -450,9 +451,9 @@ async def list( """This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ServiceUnavailableError: The server answered 503. ``GET /api/experimental/session/:sessionID/terminal`` """ @@ -490,9 +491,9 @@ async def create( """This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ServiceUnavailableError: The server answered 503. ``POST /api/experimental/session/:sessionID/terminal`` """ @@ -524,9 +525,9 @@ async def shutdown( """This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ServiceUnavailableError: The server answered 503. ``POST /api/experimental/persistent-pty/shutdown`` """ @@ -553,9 +554,9 @@ async def handoff( """This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ServiceUnavailableError: The server answered 503. ``POST /api/experimental/persistent-pty/handoff`` """ @@ -586,10 +587,10 @@ async def get( """This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - PtyNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + PtyNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``GET /api/experimental/persistent-pty/:ptyID`` """ @@ -623,10 +624,10 @@ async def update( """This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - PtyNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + PtyNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``PUT /api/experimental/persistent-pty/:ptyID`` """ @@ -659,10 +660,10 @@ async def snapshot( """This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - PtyNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + PtyNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``GET /api/experimental/persistent-pty/:ptyID/snapshot`` """ @@ -694,10 +695,10 @@ async def remove( """This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - PtyNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + PtyNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``DELETE /api/experimental/persistent-pty/:ptyID`` """ @@ -726,11 +727,11 @@ async def connect_token( """This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - ForbiddenError - PtyNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ForbiddenError: The server answered 403. + PtyNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``POST /api/experimental/persistent-pty/:ptyID/connect-token`` """ @@ -757,4 +758,5 @@ class AsyncExperimentalResource(AsyncAPIResource): @cached_property def persistent_pty(self) -> AsyncExperimentalPersistentPtyResource: + """Operations under ``client.experimental.persistent_pty``.""" return AsyncExperimentalPersistentPtyResource(self._client) diff --git a/src/opencode/resources/file.py b/src/opencode/resources/file.py index 761fb57..eebbcc0 100644 --- a/src/opencode/resources/file.py +++ b/src/opencode/resources/file.py @@ -39,10 +39,10 @@ def read( Stream one file relative to the requested location with ETag, Last-Modified, and single-range HTTP Range support (206 Partial Content, 416 Range Not Satisfiable, and 304 Not Modified; multi-range and malformed Range headers fall back to 200). Raises: - InvalidRequestError - UnauthorizedError - RemoteFileNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + RemoteFileNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/fs/read/*`` """ @@ -80,10 +80,10 @@ def list( path: An absolute path or a path relative to the requested location. Defaults to the location directory. Raises: - InvalidRequestError - UnauthorizedError - RemoteFileNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + RemoteFileNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/fs/list`` """ @@ -120,9 +120,9 @@ def find( Find recursively ranked filesystem entries relative to the requested location. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/fs/find`` """ @@ -163,9 +163,9 @@ def write( path: An absolute path or a path relative to the requested location. Missing parent directories are created. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``POST /api/experimental/fs/write`` """ @@ -205,10 +205,10 @@ async def read( Stream one file relative to the requested location with ETag, Last-Modified, and single-range HTTP Range support (206 Partial Content, 416 Range Not Satisfiable, and 304 Not Modified; multi-range and malformed Range headers fall back to 200). Raises: - InvalidRequestError - UnauthorizedError - RemoteFileNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + RemoteFileNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/fs/read/*`` """ @@ -246,10 +246,10 @@ async def list( path: An absolute path or a path relative to the requested location. Defaults to the location directory. Raises: - InvalidRequestError - UnauthorizedError - RemoteFileNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + RemoteFileNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/fs/list`` """ @@ -286,9 +286,9 @@ async def find( Find recursively ranked filesystem entries relative to the requested location. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/fs/find`` """ @@ -329,9 +329,9 @@ async def write( path: An absolute path or a path relative to the requested location. Missing parent directories are created. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``POST /api/experimental/fs/write`` """ diff --git a/src/opencode/resources/form.py b/src/opencode/resources/form.py index b692857..b467928 100644 --- a/src/opencode/resources/form.py +++ b/src/opencode/resources/form.py @@ -35,9 +35,9 @@ def list( Retrieve pending forms for a location. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/form`` """ @@ -75,9 +75,9 @@ async def list( Retrieve pending forms for a location. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/form`` """ diff --git a/src/opencode/resources/generate.py b/src/opencode/resources/generate.py index 380d680..e481baa 100644 --- a/src/opencode/resources/generate.py +++ b/src/opencode/resources/generate.py @@ -38,10 +38,10 @@ def text( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``POST /api/experimental/generate`` """ @@ -83,10 +83,10 @@ async def text( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``POST /api/experimental/generate`` """ diff --git a/src/opencode/resources/integration.py b/src/opencode/resources/integration.py index 9d28287..6b86b69 100644 --- a/src/opencode/resources/integration.py +++ b/src/opencode/resources/integration.py @@ -49,9 +49,9 @@ def add( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``POST /api/experimental/integration/wellknown`` """ @@ -91,10 +91,10 @@ def key( Run a key authentication method and store the resulting credential. Raises: - InvalidRequestError - UnauthorizedError - IntegrationNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + IntegrationNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/integration/:integrationID/connect/key`` """ @@ -130,10 +130,10 @@ def external( Run an external authentication method and store a reference to its credential source. Raises: - InvalidRequestError - UnauthorizedError - IntegrationNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + IntegrationNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/integration/:integrationID/connect/external`` """ @@ -173,9 +173,9 @@ def connect( Start an OAuth attempt and return the authorization details. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``POST /api/integration/:integrationID/connect/oauth`` """ @@ -212,11 +212,11 @@ def status( Poll the current status of an OAuth attempt. Raises: - InvalidRequestError - UnauthorizedError - IntegrationNotFoundError - IntegrationAttemptNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + IntegrationNotFoundError: The server answered 404. + IntegrationAttemptNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/integration/:integrationID/connect/oauth/:attemptID`` """ @@ -253,11 +253,11 @@ def complete( Complete a code-based OAuth attempt and store the resulting credential. Raises: - InvalidRequestError - UnauthorizedError - IntegrationNotFoundError - IntegrationAttemptNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + IntegrationNotFoundError: The server answered 404. + IntegrationAttemptNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/integration/:integrationID/connect/oauth/:attemptID/complete`` """ @@ -291,9 +291,9 @@ def cancel( Cancel an OAuth attempt and release its resources. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``DELETE /api/integration/:integrationID/connect/oauth/:attemptID`` """ @@ -331,11 +331,11 @@ def connect( Start a command authentication attempt. Raises: - InvalidRequestError - UnauthorizedError - IntegrationNotFoundError - IntegrationMethodNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + IntegrationNotFoundError: The server answered 404. + IntegrationMethodNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/integration/:integrationID/connect/command`` """ @@ -372,11 +372,11 @@ def status( Poll the current status and output of a command authentication attempt. Raises: - InvalidRequestError - UnauthorizedError - IntegrationNotFoundError - IntegrationAttemptNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + IntegrationNotFoundError: The server answered 404. + IntegrationAttemptNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/integration/:integrationID/connect/command/:attemptID`` """ @@ -412,9 +412,9 @@ def cancel( Cancel a command authentication attempt and terminate its process. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``DELETE /api/integration/:integrationID/connect/command/:attemptID`` """ @@ -437,18 +437,22 @@ class IntegrationResource(SyncAPIResource): @cached_property def wellknown(self) -> IntegrationWellknownResource: + """Operations under ``client.integration.wellknown``.""" return IntegrationWellknownResource(self._client) @cached_property def connect(self) -> IntegrationConnectResource: + """Operations under ``client.integration.connect``.""" return IntegrationConnectResource(self._client) @cached_property def oauth(self) -> IntegrationOauthResource: + """Operations under ``client.integration.oauth``.""" return IntegrationOauthResource(self._client) @cached_property def command(self) -> IntegrationCommandResource: + """Operations under ``client.integration.command``.""" return IntegrationCommandResource(self._client) def list( @@ -465,9 +469,9 @@ def list( Retrieve available integrations and their authentication methods. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/integration`` """ @@ -502,10 +506,10 @@ def get( Retrieve one integration and its authentication methods. Raises: - InvalidRequestError - UnauthorizedError - IntegrationNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + IntegrationNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/integration/:integrationID`` """ @@ -546,9 +550,9 @@ async def add( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``POST /api/experimental/integration/wellknown`` """ @@ -588,10 +592,10 @@ async def key( Run a key authentication method and store the resulting credential. Raises: - InvalidRequestError - UnauthorizedError - IntegrationNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + IntegrationNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/integration/:integrationID/connect/key`` """ @@ -627,10 +631,10 @@ async def external( Run an external authentication method and store a reference to its credential source. Raises: - InvalidRequestError - UnauthorizedError - IntegrationNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + IntegrationNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/integration/:integrationID/connect/external`` """ @@ -670,9 +674,9 @@ async def connect( Start an OAuth attempt and return the authorization details. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``POST /api/integration/:integrationID/connect/oauth`` """ @@ -709,11 +713,11 @@ async def status( Poll the current status of an OAuth attempt. Raises: - InvalidRequestError - UnauthorizedError - IntegrationNotFoundError - IntegrationAttemptNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + IntegrationNotFoundError: The server answered 404. + IntegrationAttemptNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/integration/:integrationID/connect/oauth/:attemptID`` """ @@ -750,11 +754,11 @@ async def complete( Complete a code-based OAuth attempt and store the resulting credential. Raises: - InvalidRequestError - UnauthorizedError - IntegrationNotFoundError - IntegrationAttemptNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + IntegrationNotFoundError: The server answered 404. + IntegrationAttemptNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/integration/:integrationID/connect/oauth/:attemptID/complete`` """ @@ -788,9 +792,9 @@ async def cancel( Cancel an OAuth attempt and release its resources. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``DELETE /api/integration/:integrationID/connect/oauth/:attemptID`` """ @@ -828,11 +832,11 @@ async def connect( Start a command authentication attempt. Raises: - InvalidRequestError - UnauthorizedError - IntegrationNotFoundError - IntegrationMethodNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + IntegrationNotFoundError: The server answered 404. + IntegrationMethodNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/integration/:integrationID/connect/command`` """ @@ -869,11 +873,11 @@ async def status( Poll the current status and output of a command authentication attempt. Raises: - InvalidRequestError - UnauthorizedError - IntegrationNotFoundError - IntegrationAttemptNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + IntegrationNotFoundError: The server answered 404. + IntegrationAttemptNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/integration/:integrationID/connect/command/:attemptID`` """ @@ -909,9 +913,9 @@ async def cancel( Cancel a command authentication attempt and terminate its process. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``DELETE /api/integration/:integrationID/connect/command/:attemptID`` """ @@ -934,18 +938,22 @@ class AsyncIntegrationResource(AsyncAPIResource): @cached_property def wellknown(self) -> AsyncIntegrationWellknownResource: + """Operations under ``client.integration.wellknown``.""" return AsyncIntegrationWellknownResource(self._client) @cached_property def connect(self) -> AsyncIntegrationConnectResource: + """Operations under ``client.integration.connect``.""" return AsyncIntegrationConnectResource(self._client) @cached_property def oauth(self) -> AsyncIntegrationOauthResource: + """Operations under ``client.integration.oauth``.""" return AsyncIntegrationOauthResource(self._client) @cached_property def command(self) -> AsyncIntegrationCommandResource: + """Operations under ``client.integration.command``.""" return AsyncIntegrationCommandResource(self._client) async def list( @@ -962,9 +970,9 @@ async def list( Retrieve available integrations and their authentication methods. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/integration`` """ @@ -999,10 +1007,10 @@ async def get( Retrieve one integration and its authentication methods. Raises: - InvalidRequestError - UnauthorizedError - IntegrationNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + IntegrationNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/integration/:integrationID`` """ diff --git a/src/opencode/resources/location.py b/src/opencode/resources/location.py index 485ded5..653beae 100644 --- a/src/opencode/resources/location.py +++ b/src/opencode/resources/location.py @@ -35,9 +35,9 @@ def get( Resolve the requested location or the server default location. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/location`` """ @@ -70,9 +70,9 @@ def reload( Shut down and rebuild every loaded location. Pending permissions and forms are cancelled; running sessions continue with fresh services at the next step boundary. Emits location.shutdown for client recovery and responds once all replacement builds settle. Raises: - InvalidRequestError - UnauthorizedError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ServiceUnavailableError: The server answered 503. ``POST /api/location/reload`` """ @@ -106,9 +106,9 @@ async def get( Resolve the requested location or the server default location. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/location`` """ @@ -141,9 +141,9 @@ async def reload( Shut down and rebuild every loaded location. Pending permissions and forms are cancelled; running sessions continue with fresh services at the next step boundary. Emits location.shutdown for client recovery and responds once all replacement builds settle. Raises: - InvalidRequestError - UnauthorizedError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ServiceUnavailableError: The server answered 503. ``POST /api/location/reload`` """ diff --git a/src/opencode/resources/mcp.py b/src/opencode/resources/mcp.py index 140df90..155456f 100644 --- a/src/opencode/resources/mcp.py +++ b/src/opencode/resources/mcp.py @@ -39,9 +39,9 @@ def catalog( Retrieve resources and resource templates from connected MCP servers. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/mcp/resource`` """ @@ -67,6 +67,7 @@ class McpResource(SyncAPIResource): @cached_property def resource(self) -> McpResourceResource: + """Operations under ``client.mcp.resource``.""" return McpResourceResource(self._client) def list( @@ -83,9 +84,9 @@ def list( Retrieve configured MCP servers and their connection status. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/mcp`` """ @@ -123,9 +124,9 @@ def add( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``PUT /api/experimental/mcp/:server`` """ @@ -160,10 +161,10 @@ def remove( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - McpServerNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + McpServerNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``DELETE /api/experimental/mcp/:server`` """ @@ -197,10 +198,10 @@ def connect( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - McpServerNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + McpServerNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/experimental/mcp/:server/connect`` """ @@ -234,10 +235,10 @@ def disconnect( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - McpServerNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + McpServerNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/experimental/mcp/:server/disconnect`` """ @@ -272,9 +273,9 @@ async def catalog( Retrieve resources and resource templates from connected MCP servers. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/mcp/resource`` """ @@ -300,6 +301,7 @@ class AsyncMcpResource(AsyncAPIResource): @cached_property def resource(self) -> AsyncMcpResourceResource: + """Operations under ``client.mcp.resource``.""" return AsyncMcpResourceResource(self._client) async def list( @@ -316,9 +318,9 @@ async def list( Retrieve configured MCP servers and their connection status. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/mcp`` """ @@ -356,9 +358,9 @@ async def add( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``PUT /api/experimental/mcp/:server`` """ @@ -393,10 +395,10 @@ async def remove( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - McpServerNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + McpServerNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``DELETE /api/experimental/mcp/:server`` """ @@ -430,10 +432,10 @@ async def connect( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - McpServerNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + McpServerNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/experimental/mcp/:server/connect`` """ @@ -467,10 +469,10 @@ async def disconnect( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - McpServerNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + McpServerNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/experimental/mcp/:server/disconnect`` """ diff --git a/src/opencode/resources/message.py b/src/opencode/resources/message.py index 810ab7d..4c35c05 100644 --- a/src/opencode/resources/message.py +++ b/src/opencode/resources/message.py @@ -64,11 +64,11 @@ def list( type: Filter by message type before pagination. When omitted, all message types are returned. Pass the same type when following cursors. Raises: - InvalidCursorError - InvalidRequestError - UnauthorizedError - SessionNotFoundError - UnknownError + InvalidCursorError: The server answered 400. + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + UnknownError: The server answered 500. ``GET /api/session/:sessionID/message`` """ @@ -129,11 +129,11 @@ def list( type: Filter by message type before pagination. When omitted, all message types are returned. Pass the same type when following cursors. Raises: - InvalidCursorError - InvalidRequestError - UnauthorizedError - SessionNotFoundError - UnknownError + InvalidCursorError: The server answered 400. + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + UnknownError: The server answered 500. ``GET /api/session/:sessionID/message`` """ diff --git a/src/opencode/resources/migration.py b/src/opencode/resources/migration.py index b84b8f1..212ea18 100644 --- a/src/opencode/resources/migration.py +++ b/src/opencode/resources/migration.py @@ -38,8 +38,8 @@ def status( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``GET /api/experimental/migration/v1`` """ @@ -66,6 +66,7 @@ class MigrationResource(SyncAPIResource): @cached_property def v1(self) -> MigrationV1Resource: + """Operations under ``client.migration.v1``.""" return MigrationV1Resource(self._client) @@ -87,8 +88,8 @@ async def status( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``GET /api/experimental/migration/v1`` """ @@ -115,4 +116,5 @@ class AsyncMigrationResource(AsyncAPIResource): @cached_property def v1(self) -> AsyncMigrationV1Resource: + """Operations under ``client.migration.v1``.""" return AsyncMigrationV1Resource(self._client) diff --git a/src/opencode/resources/model.py b/src/opencode/resources/model.py index 1da68c7..0fb2c8b 100644 --- a/src/opencode/resources/model.py +++ b/src/opencode/resources/model.py @@ -36,10 +36,10 @@ def list( Retrieve the current snapshot of available models ordered by release date. The snapshot may precede initial plugin settlement. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``GET /api/model`` """ @@ -73,10 +73,10 @@ def default( Retrieve the model used when a session has no explicit model selection. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``GET /api/model/default`` """ @@ -114,10 +114,10 @@ async def list( Retrieve the current snapshot of available models ordered by release date. The snapshot may precede initial plugin settlement. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``GET /api/model`` """ @@ -151,10 +151,10 @@ async def default( Retrieve the model used when a session has no explicit model selection. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``GET /api/model/default`` """ diff --git a/src/opencode/resources/permission.py b/src/opencode/resources/permission.py index cffff47..4a022ae 100644 --- a/src/opencode/resources/permission.py +++ b/src/opencode/resources/permission.py @@ -49,9 +49,9 @@ def list( Retrieve pending permission requests for a location. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/permission/request`` """ @@ -89,9 +89,9 @@ def list( Retrieve saved permissions, optionally filtered by project. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/permission/saved`` """ @@ -128,11 +128,11 @@ def update( Change the action or resource of a saved permission. Fails with a conflict when the project already has a saved permission with the same action and resource. Raises: - InvalidRequestError - UnauthorizedError - PermissionSavedNotFoundError - LocationNotFoundError - ConflictError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + PermissionSavedNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + ConflictError: The server answered 409. ``PATCH /api/permission/saved/:id`` """ @@ -167,9 +167,9 @@ def remove( Remove a saved permission by ID. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``DELETE /api/permission/saved/:id`` """ @@ -191,10 +191,12 @@ class PermissionResource(SyncAPIResource): @cached_property def request_(self) -> PermissionRequestResource: + """Operations under ``client.permission.request``.""" return PermissionRequestResource(self._client) @cached_property def saved(self) -> PermissionSavedResource: + """Operations under ``client.permission.saved``.""" return PermissionSavedResource(self._client) def create( @@ -218,10 +220,10 @@ def create( Evaluate and, when approval is required, create a permission request for a session. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/session/:sessionID/permission`` """ @@ -264,10 +266,10 @@ def list( Retrieve pending permission requests owned by a session. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/session/:sessionID/permission`` """ @@ -302,11 +304,11 @@ def get( Retrieve a pending permission request owned by a session. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - PermissionNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + PermissionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/session/:sessionID/permission/:requestID`` """ @@ -343,11 +345,11 @@ def reply( Respond to a pending permission request owned by a session. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - PermissionNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + PermissionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/session/:sessionID/permission/:requestID/reply`` """ @@ -382,9 +384,9 @@ async def list( Retrieve pending permission requests for a location. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/permission/request`` """ @@ -422,9 +424,9 @@ async def list( Retrieve saved permissions, optionally filtered by project. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/permission/saved`` """ @@ -461,11 +463,11 @@ async def update( Change the action or resource of a saved permission. Fails with a conflict when the project already has a saved permission with the same action and resource. Raises: - InvalidRequestError - UnauthorizedError - PermissionSavedNotFoundError - LocationNotFoundError - ConflictError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + PermissionSavedNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + ConflictError: The server answered 409. ``PATCH /api/permission/saved/:id`` """ @@ -500,9 +502,9 @@ async def remove( Remove a saved permission by ID. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``DELETE /api/permission/saved/:id`` """ @@ -524,10 +526,12 @@ class AsyncPermissionResource(AsyncAPIResource): @cached_property def request_(self) -> AsyncPermissionRequestResource: + """Operations under ``client.permission.request``.""" return AsyncPermissionRequestResource(self._client) @cached_property def saved(self) -> AsyncPermissionSavedResource: + """Operations under ``client.permission.saved``.""" return AsyncPermissionSavedResource(self._client) async def create( @@ -551,10 +555,10 @@ async def create( Evaluate and, when approval is required, create a permission request for a session. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/session/:sessionID/permission`` """ @@ -597,10 +601,10 @@ async def list( Retrieve pending permission requests owned by a session. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/session/:sessionID/permission`` """ @@ -635,11 +639,11 @@ async def get( Retrieve a pending permission request owned by a session. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - PermissionNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + PermissionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/session/:sessionID/permission/:requestID`` """ @@ -676,11 +680,11 @@ async def reply( Respond to a pending permission request owned by a session. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - PermissionNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + PermissionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/session/:sessionID/permission/:requestID/reply`` """ diff --git a/src/opencode/resources/plugin.py b/src/opencode/resources/plugin.py index 30a19eb..7553245 100644 --- a/src/opencode/resources/plugin.py +++ b/src/opencode/resources/plugin.py @@ -37,9 +37,9 @@ def list( Retrieve enabled server plugins and their current status. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/plugin`` """ @@ -74,9 +74,9 @@ def check( Check one or all package plugins for available updates. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``POST /api/plugin/check`` """ @@ -112,10 +112,10 @@ def update( Update package plugins concurrently and notify active locations to reload them. Responds once every update has finished; fails when any update fails. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``POST /api/plugin/update`` """ @@ -151,9 +151,9 @@ async def list( Retrieve enabled server plugins and their current status. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/plugin`` """ @@ -188,9 +188,9 @@ async def check( Check one or all package plugins for available updates. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``POST /api/plugin/check`` """ @@ -226,10 +226,10 @@ async def update( Update package plugins concurrently and notify active locations to reload them. Responds once every update has finished; fails when any update fails. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``POST /api/plugin/update`` """ diff --git a/src/opencode/resources/project.py b/src/opencode/resources/project.py index 882581c..2e926bf 100644 --- a/src/opencode/resources/project.py +++ b/src/opencode/resources/project.py @@ -40,9 +40,9 @@ def list( List known projects. Archived projects are excluded unless archived=true. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/project`` """ @@ -80,10 +80,10 @@ def update( Update the project canonical directory, display metadata, and workspace commands. Raises: - InvalidRequestError - UnauthorizedError - ProjectNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ProjectNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``PATCH /api/project/:projectID`` """ @@ -121,9 +121,9 @@ async def list( List known projects. Archived projects are excluded unless archived=true. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/project`` """ @@ -161,10 +161,10 @@ async def update( Update the project canonical directory, display metadata, and workspace commands. Raises: - InvalidRequestError - UnauthorizedError - ProjectNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ProjectNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``PATCH /api/project/:projectID`` """ diff --git a/src/opencode/resources/provider.py b/src/opencode/resources/provider.py index 70b661a..73e79b5 100644 --- a/src/opencode/resources/provider.py +++ b/src/opencode/resources/provider.py @@ -38,10 +38,10 @@ def list( Retrieve active AI providers so clients can show provider availability and configuration. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``GET /api/provider`` """ @@ -76,11 +76,11 @@ def get( Retrieve a single AI provider so clients can inspect its availability and endpoint settings. Raises: - InvalidRequestError - UnauthorizedError - ProviderNotFoundError - LocationNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ProviderNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``GET /api/provider/:providerID`` """ @@ -118,10 +118,10 @@ async def list( Retrieve active AI providers so clients can show provider availability and configuration. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``GET /api/provider`` """ @@ -156,11 +156,11 @@ async def get( Retrieve a single AI provider so clients can inspect its availability and endpoint settings. Raises: - InvalidRequestError - UnauthorizedError - ProviderNotFoundError - LocationNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ProviderNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``GET /api/provider/:providerID`` """ diff --git a/src/opencode/resources/pty.py b/src/opencode/resources/pty.py index 44e796e..6f5099a 100644 --- a/src/opencode/resources/pty.py +++ b/src/opencode/resources/pty.py @@ -46,11 +46,11 @@ def token( Create a short-lived single-use ticket for opening a PTY WebSocket connection. Raises: - InvalidRequestError - UnauthorizedError - ForbiddenError - PtyNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ForbiddenError: The server answered 403. + PtyNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/pty/:ptyID/connect-token`` """ @@ -77,6 +77,7 @@ class PtyResource(SyncAPIResource): @cached_property def connect(self) -> PtyConnectResource: + """Operations under ``client.pty.connect``.""" return PtyConnectResource(self._client) def list( @@ -93,9 +94,9 @@ def list( List PTY sessions for a location, including exited sessions retained until removal. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/pty`` """ @@ -134,9 +135,9 @@ def create( Create a pseudo-terminal session for a location. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``POST /api/pty`` """ @@ -172,10 +173,10 @@ def get( Get one PTY session, including its exit code once exited. Raises: - InvalidRequestError - UnauthorizedError - PtyNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + PtyNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/pty/:ptyID`` """ @@ -212,10 +213,10 @@ def update( Update the title or viewport size of one PTY session. Raises: - InvalidRequestError - UnauthorizedError - PtyNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + PtyNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``PUT /api/pty/:ptyID`` """ @@ -251,10 +252,10 @@ def remove( Terminate and remove one PTY session. Raises: - InvalidRequestError - UnauthorizedError - PtyNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + PtyNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``DELETE /api/pty/:ptyID`` """ @@ -291,11 +292,11 @@ async def token( Create a short-lived single-use ticket for opening a PTY WebSocket connection. Raises: - InvalidRequestError - UnauthorizedError - ForbiddenError - PtyNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ForbiddenError: The server answered 403. + PtyNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/pty/:ptyID/connect-token`` """ @@ -322,6 +323,7 @@ class AsyncPtyResource(AsyncAPIResource): @cached_property def connect(self) -> AsyncPtyConnectResource: + """Operations under ``client.pty.connect``.""" return AsyncPtyConnectResource(self._client) async def list( @@ -338,9 +340,9 @@ async def list( List PTY sessions for a location, including exited sessions retained until removal. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/pty`` """ @@ -379,9 +381,9 @@ async def create( Create a pseudo-terminal session for a location. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``POST /api/pty`` """ @@ -417,10 +419,10 @@ async def get( Get one PTY session, including its exit code once exited. Raises: - InvalidRequestError - UnauthorizedError - PtyNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + PtyNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/pty/:ptyID`` """ @@ -457,10 +459,10 @@ async def update( Update the title or viewport size of one PTY session. Raises: - InvalidRequestError - UnauthorizedError - PtyNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + PtyNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``PUT /api/pty/:ptyID`` """ @@ -496,10 +498,10 @@ async def remove( Terminate and remove one PTY session. Raises: - InvalidRequestError - UnauthorizedError - PtyNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + PtyNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``DELETE /api/pty/:ptyID`` """ diff --git a/src/opencode/resources/reference.py b/src/opencode/resources/reference.py index 11c7211..869efef 100644 --- a/src/opencode/resources/reference.py +++ b/src/opencode/resources/reference.py @@ -35,9 +35,9 @@ def list( List references available in the requested location. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/reference`` """ @@ -75,9 +75,9 @@ async def list( List references available in the requested location. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/reference`` """ diff --git a/src/opencode/resources/rpc.py b/src/opencode/resources/rpc.py index 8d9349d..c00d41f 100644 --- a/src/opencode/resources/rpc.py +++ b/src/opencode/resources/rpc.py @@ -39,11 +39,11 @@ def call( Dispatch a method to the currently registered RPC at the requested location. Raises: - RpcError - InvalidRequestError - UnauthorizedError - LocationNotFoundError - RpcInternalError + RpcError: The server answered 400. + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. + RpcInternalError: The server answered 500. ``POST /api/rpc/:rpcID/:method`` """ @@ -85,11 +85,11 @@ async def call( Dispatch a method to the currently registered RPC at the requested location. Raises: - RpcError - InvalidRequestError - UnauthorizedError - LocationNotFoundError - RpcInternalError + RpcError: The server answered 400. + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. + RpcInternalError: The server answered 500. ``POST /api/rpc/:rpcID/:method`` """ diff --git a/src/opencode/resources/server.py b/src/opencode/resources/server.py index 0f63e3e..e16c9cb 100644 --- a/src/opencode/resources/server.py +++ b/src/opencode/resources/server.py @@ -36,8 +36,8 @@ def info( Return the server identity, connection URLs, paths, and readiness status. Raises: - InvalidRequestError - UnauthorizedError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``GET /api/info`` """ @@ -69,8 +69,8 @@ def pair( Create a short-lived, single-use code for a /auth/connect/:code pairing link. Raises: - InvalidRequestError - UnauthorizedError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``POST /api/pair`` """ @@ -103,8 +103,8 @@ def connect( Redeem a pairing code. Browsers receive a session cookie and a redirect to the web app; requests that accept JSON receive a session token to use as the password. Raises: - InvalidRequestError - UnauthorizedError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``GET /auth/connect/:code`` """ @@ -140,8 +140,8 @@ async def info( Return the server identity, connection URLs, paths, and readiness status. Raises: - InvalidRequestError - UnauthorizedError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``GET /api/info`` """ @@ -173,8 +173,8 @@ async def pair( Create a short-lived, single-use code for a /auth/connect/:code pairing link. Raises: - InvalidRequestError - UnauthorizedError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``POST /api/pair`` """ @@ -207,8 +207,8 @@ async def connect( Redeem a pairing code. Browsers receive a session cookie and a redirect to the web app; requests that accept JSON receive a session token to use as the password. Raises: - InvalidRequestError - UnauthorizedError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``GET /auth/connect/:code`` """ diff --git a/src/opencode/resources/session.py b/src/opencode/resources/session.py index c204f31..47c463b 100644 --- a/src/opencode/resources/session.py +++ b/src/opencode/resources/session.py @@ -80,13 +80,13 @@ def stage( Stage or move a reversible session boundary and optionally apply its file changes. Raises: - InvalidRequestError - UnauthorizedError - MessageNotFoundError - SessionNotFoundError - LocationNotFoundError - SessionBusyError - UnknownError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + MessageNotFoundError: The server answered 404. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + SessionBusyError: The server answered 409. + UnknownError: The server answered 500. ``POST /api/session/:sessionID/revert/stage`` """ @@ -119,12 +119,12 @@ def clear( """Clear staged revert. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError - SessionBusyError - UnknownError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + SessionBusyError: The server answered 409. + UnknownError: The server answered 500. ``DELETE /api/session/:sessionID/revert`` """ @@ -152,11 +152,11 @@ def commit( """Commit staged revert. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError - SessionBusyError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + SessionBusyError: The server answered 409. ``POST /api/session/:sessionID/revert/commit`` """ @@ -190,9 +190,9 @@ def list( List durable enqueued session work not yet delivered, ordered by enqueue sequence. Includes user, synthetic, compaction, and move items. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. ``GET /api/session/:sessionID/inbox`` """ @@ -227,9 +227,9 @@ def cancel( Cancel an inbox item that has not yet been delivered. Unavailable items are a no-op. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. ``DELETE /api/session/:sessionID/inbox/:inboxID`` """ @@ -261,10 +261,10 @@ def update( Change a pending inbox item's delivery mode. Steering wakes session execution. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - ConflictError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + ConflictError: The server answered 409. ``PATCH /api/session/:sessionID/inbox/:inboxID`` """ @@ -301,10 +301,10 @@ def list( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/experimental/session/:sessionID/instructions/entries`` """ @@ -342,11 +342,11 @@ def put( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError - InstructionEntryValueTooLargeError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + InstructionEntryValueTooLargeError: The server answered 413. ``PUT /api/experimental/session/:sessionID/instructions/entries/:key`` """ @@ -380,10 +380,10 @@ def remove( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``DELETE /api/experimental/session/:sessionID/instructions/entries/:key`` """ @@ -405,6 +405,7 @@ class SessionInstructionsResource(SyncAPIResource): @cached_property def entry(self) -> SessionInstructionsEntryResource: + """Operations under ``client.session.instructions.entry``.""" return SessionInstructionsEntryResource(self._client) @@ -426,10 +427,10 @@ def get( Retrieve one projected message owned by the Session. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - MessageNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + MessageNotFoundError: The server answered 404. ``GET /api/session/:sessionID/message/:messageID`` """ @@ -467,10 +468,10 @@ def list( Retrieve pending forms for a session. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/session/:sessionID/form`` """ @@ -508,11 +509,11 @@ def create( Create a form for a session. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError - ConflictError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + ConflictError: The server answered 409. ``POST /api/session/:sessionID/form`` """ @@ -548,11 +549,11 @@ def get( Retrieve a form and its current state for a session. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - FormNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + FormNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/session/:sessionID/form/:formID`` """ @@ -588,13 +589,13 @@ def reply( Submit an answer to a pending form. Raises: - FormInvalidAnswerError - InvalidRequestError - UnauthorizedError - SessionNotFoundError - FormNotFoundError - LocationNotFoundError - FormAlreadySettledError + FormInvalidAnswerError: The server answered 400. + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + FormNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + FormAlreadySettledError: The server answered 409. ``POST /api/session/:sessionID/form/:formID/reply`` """ @@ -627,12 +628,12 @@ def cancel( Cancel a pending form, optionally telling the asker why it was not answered. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - FormNotFoundError - LocationNotFoundError - FormAlreadySettledError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + FormNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + FormAlreadySettledError: The server answered 409. ``DELETE /api/session/:sessionID/form/:formID`` """ @@ -655,22 +656,27 @@ class SessionResource(SyncAPIResource): @cached_property def revert(self) -> SessionRevertResource: + """Operations under ``client.session.revert``.""" return SessionRevertResource(self._client) @cached_property def inbox(self) -> SessionInboxResource: + """Operations under ``client.session.inbox``.""" return SessionInboxResource(self._client) @cached_property def instructions(self) -> SessionInstructionsResource: + """Operations under ``client.session.instructions``.""" return SessionInstructionsResource(self._client) @cached_property def message(self) -> SessionMessageResource: + """Operations under ``client.session.message``.""" return SessionMessageResource(self._client) @cached_property def form(self) -> SessionFormResource: + """Operations under ``client.session.form``.""" return SessionFormResource(self._client) def list( @@ -701,9 +707,9 @@ def list( archived: Filter by archive state. Use true to return only archived sessions or false to exclude them. Omit to include both. Raises: - InvalidCursorError - InvalidRequestError - UnauthorizedError + InvalidCursorError: The server answered 400. + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``GET /api/session`` """ @@ -750,8 +756,8 @@ def stats( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``GET /api/experimental/session/stats`` """ @@ -793,9 +799,9 @@ def create( Create a session at the requested location. A parentID creates a linked child session at its parent's location. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. ``POST /api/session`` """ @@ -843,10 +849,10 @@ def import_( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - ConflictError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + ConflictError: The server answered 409. ``POST /api/experimental/session/import`` """ @@ -884,10 +890,10 @@ def export( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - UnknownError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + UnknownError: The server answered 500. ``GET /api/experimental/session/:sessionID/export`` """ @@ -921,8 +927,8 @@ def active( Retrieve foreground Session drains currently owned by this OpenCode process. Sessions absent from the result are inactive. Raises: - InvalidRequestError - UnauthorizedError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``GET /api/session/active`` """ @@ -956,9 +962,9 @@ def get( Retrieve a session by ID. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. ``GET /api/session/:sessionID`` """ @@ -992,9 +998,9 @@ def remove( Delete a session and its child sessions. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. ``DELETE /api/session/:sessionID`` """ @@ -1025,11 +1031,11 @@ def fork( Create a child session by copying projected history before a message. Omit before to copy the full history. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - MessageNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + MessageNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/session/:sessionID/fork`` """ @@ -1065,10 +1071,10 @@ def switch_agent( Switch the agent used by subsequent provider turns. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/session/:sessionID/agent`` """ @@ -1100,10 +1106,10 @@ def switch_model( Switch the model used by subsequent provider turns. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/session/:sessionID/model`` """ @@ -1141,10 +1147,10 @@ def update( archived: Archive the session with true or restore it with false. Repeating the current state is a no-op. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``PATCH /api/session/:sessionID`` """ @@ -1177,9 +1183,9 @@ def move( Move a session to another project directory at the requested delivery boundary. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. ``POST /api/session/:sessionID/move`` """ @@ -1218,11 +1224,11 @@ def prompt( Durably admit one session input and schedule agent-loop execution unless resume is false. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError - ConflictError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + ConflictError: The server answered 409. ``POST /api/session/:sessionID/prompt`` """ @@ -1272,12 +1278,12 @@ def command( Execute a slash command callback immediately. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - CommandNotFoundError - LocationNotFoundError - CommandExecutionError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + CommandNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + CommandExecutionError: The server answered 500. ``POST /api/session/:sessionID/command`` """ @@ -1319,11 +1325,11 @@ def skill( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - SkillNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + SkillNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/experimental/session/:sessionID/skill`` """ @@ -1360,11 +1366,11 @@ def synthetic( Durably admit synthetic session input and schedule execution unless resume is false. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError - ConflictError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + ConflictError: The server answered 409. ``POST /api/session/:sessionID/synthetic`` """ @@ -1408,10 +1414,10 @@ def shell( Execute one shell command in the session's working directory. Emits a shell.started event before execution and a shell.ended event with the merged output after. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/session/:sessionID/shell`` """ @@ -1444,11 +1450,11 @@ def compact( Durably admit a session compaction request. Steers by default: it runs at the next step boundary instead of waiting behind queued prompts. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError - ConflictError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + ConflictError: The server answered 409. ``POST /api/session/:sessionID/compact`` """ @@ -1485,11 +1491,11 @@ def wait( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``POST /api/experimental/session/:sessionID/wait`` """ @@ -1519,10 +1525,10 @@ def context( Retrieve the active context messages for a session (all messages after the last compaction). Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - UnknownError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + UnknownError: The server answered 500. ``GET /api/session/:sessionID/context`` """ @@ -1564,12 +1570,12 @@ def diff( context: Unchanged lines around each hunk. Omit for full-file patches. Raises: - InvalidRequestError - UnauthorizedError - MessageNotFoundError - SessionNotFoundError - LocationNotFoundError - UnknownError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + MessageNotFoundError: The server answered 404. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + UnknownError: The server answered 500. ``GET /api/session/:sessionID/diff`` """ @@ -1605,11 +1611,11 @@ def generate( Generate transient text from the current session context without mutating session history. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``POST /api/session/:sessionID/generate`` """ @@ -1648,9 +1654,9 @@ def log( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. ``GET /api/experimental/session/:sessionID/log`` """ @@ -1682,10 +1688,10 @@ def interrupt( Interrupt active execution owned by this OpenCode process. Returns interrupted=true when an active execution was interrupted and false for the idle no-op. When resume=true, execution resumes pending steering input and next-in-line control items (manual compaction, moves) while queued prompts remain parked. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/session/:sessionID/interrupt`` """ @@ -1719,10 +1725,10 @@ def background( Move active foreground backgroundable tools for this session into background observation. Idle requests are a no-op. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/session/:sessionID/background`` """ @@ -1753,9 +1759,9 @@ def environment( Replace the process environment used by local shell commands for this session. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. ``PUT /api/session/:sessionID/environment`` """ @@ -1787,9 +1793,9 @@ def view( Mark the idle transition observed by the viewer as viewed. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. ``POST /api/session/:sessionID/view`` """ @@ -1826,13 +1832,13 @@ async def stage( Stage or move a reversible session boundary and optionally apply its file changes. Raises: - InvalidRequestError - UnauthorizedError - MessageNotFoundError - SessionNotFoundError - LocationNotFoundError - SessionBusyError - UnknownError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + MessageNotFoundError: The server answered 404. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + SessionBusyError: The server answered 409. + UnknownError: The server answered 500. ``POST /api/session/:sessionID/revert/stage`` """ @@ -1865,12 +1871,12 @@ async def clear( """Clear staged revert. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError - SessionBusyError - UnknownError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + SessionBusyError: The server answered 409. + UnknownError: The server answered 500. ``DELETE /api/session/:sessionID/revert`` """ @@ -1898,11 +1904,11 @@ async def commit( """Commit staged revert. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError - SessionBusyError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + SessionBusyError: The server answered 409. ``POST /api/session/:sessionID/revert/commit`` """ @@ -1936,9 +1942,9 @@ async def list( List durable enqueued session work not yet delivered, ordered by enqueue sequence. Includes user, synthetic, compaction, and move items. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. ``GET /api/session/:sessionID/inbox`` """ @@ -1973,9 +1979,9 @@ async def cancel( Cancel an inbox item that has not yet been delivered. Unavailable items are a no-op. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. ``DELETE /api/session/:sessionID/inbox/:inboxID`` """ @@ -2007,10 +2013,10 @@ async def update( Change a pending inbox item's delivery mode. Steering wakes session execution. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - ConflictError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + ConflictError: The server answered 409. ``PATCH /api/session/:sessionID/inbox/:inboxID`` """ @@ -2047,10 +2053,10 @@ async def list( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/experimental/session/:sessionID/instructions/entries`` """ @@ -2088,11 +2094,11 @@ async def put( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError - InstructionEntryValueTooLargeError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + InstructionEntryValueTooLargeError: The server answered 413. ``PUT /api/experimental/session/:sessionID/instructions/entries/:key`` """ @@ -2126,10 +2132,10 @@ async def remove( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``DELETE /api/experimental/session/:sessionID/instructions/entries/:key`` """ @@ -2151,6 +2157,7 @@ class AsyncSessionInstructionsResource(AsyncAPIResource): @cached_property def entry(self) -> AsyncSessionInstructionsEntryResource: + """Operations under ``client.session.instructions.entry``.""" return AsyncSessionInstructionsEntryResource(self._client) @@ -2172,10 +2179,10 @@ async def get( Retrieve one projected message owned by the Session. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - MessageNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + MessageNotFoundError: The server answered 404. ``GET /api/session/:sessionID/message/:messageID`` """ @@ -2213,10 +2220,10 @@ async def list( Retrieve pending forms for a session. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/session/:sessionID/form`` """ @@ -2254,11 +2261,11 @@ async def create( Create a form for a session. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError - ConflictError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + ConflictError: The server answered 409. ``POST /api/session/:sessionID/form`` """ @@ -2294,11 +2301,11 @@ async def get( Retrieve a form and its current state for a session. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - FormNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + FormNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/session/:sessionID/form/:formID`` """ @@ -2334,13 +2341,13 @@ async def reply( Submit an answer to a pending form. Raises: - FormInvalidAnswerError - InvalidRequestError - UnauthorizedError - SessionNotFoundError - FormNotFoundError - LocationNotFoundError - FormAlreadySettledError + FormInvalidAnswerError: The server answered 400. + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + FormNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + FormAlreadySettledError: The server answered 409. ``POST /api/session/:sessionID/form/:formID/reply`` """ @@ -2373,12 +2380,12 @@ async def cancel( Cancel a pending form, optionally telling the asker why it was not answered. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - FormNotFoundError - LocationNotFoundError - FormAlreadySettledError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + FormNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + FormAlreadySettledError: The server answered 409. ``DELETE /api/session/:sessionID/form/:formID`` """ @@ -2401,22 +2408,27 @@ class AsyncSessionResource(AsyncAPIResource): @cached_property def revert(self) -> AsyncSessionRevertResource: + """Operations under ``client.session.revert``.""" return AsyncSessionRevertResource(self._client) @cached_property def inbox(self) -> AsyncSessionInboxResource: + """Operations under ``client.session.inbox``.""" return AsyncSessionInboxResource(self._client) @cached_property def instructions(self) -> AsyncSessionInstructionsResource: + """Operations under ``client.session.instructions``.""" return AsyncSessionInstructionsResource(self._client) @cached_property def message(self) -> AsyncSessionMessageResource: + """Operations under ``client.session.message``.""" return AsyncSessionMessageResource(self._client) @cached_property def form(self) -> AsyncSessionFormResource: + """Operations under ``client.session.form``.""" return AsyncSessionFormResource(self._client) def list( @@ -2447,9 +2459,9 @@ def list( archived: Filter by archive state. Use true to return only archived sessions or false to exclude them. Omit to include both. Raises: - InvalidCursorError - InvalidRequestError - UnauthorizedError + InvalidCursorError: The server answered 400. + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``GET /api/session`` """ @@ -2496,8 +2508,8 @@ async def stats( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``GET /api/experimental/session/stats`` """ @@ -2539,9 +2551,9 @@ async def create( Create a session at the requested location. A parentID creates a linked child session at its parent's location. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. ``POST /api/session`` """ @@ -2589,10 +2601,10 @@ async def import_( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - ConflictError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + ConflictError: The server answered 409. ``POST /api/experimental/session/import`` """ @@ -2630,10 +2642,10 @@ async def export( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - UnknownError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + UnknownError: The server answered 500. ``GET /api/experimental/session/:sessionID/export`` """ @@ -2667,8 +2679,8 @@ async def active( Retrieve foreground Session drains currently owned by this OpenCode process. Sessions absent from the result are inactive. Raises: - InvalidRequestError - UnauthorizedError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. ``GET /api/session/active`` """ @@ -2702,9 +2714,9 @@ async def get( Retrieve a session by ID. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. ``GET /api/session/:sessionID`` """ @@ -2738,9 +2750,9 @@ async def remove( Delete a session and its child sessions. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. ``DELETE /api/session/:sessionID`` """ @@ -2771,11 +2783,11 @@ async def fork( Create a child session by copying projected history before a message. Omit before to copy the full history. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - MessageNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + MessageNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/session/:sessionID/fork`` """ @@ -2811,10 +2823,10 @@ async def switch_agent( Switch the agent used by subsequent provider turns. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/session/:sessionID/agent`` """ @@ -2846,10 +2858,10 @@ async def switch_model( Switch the model used by subsequent provider turns. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/session/:sessionID/model`` """ @@ -2887,10 +2899,10 @@ async def update( archived: Archive the session with true or restore it with false. Repeating the current state is a no-op. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``PATCH /api/session/:sessionID`` """ @@ -2923,9 +2935,9 @@ async def move( Move a session to another project directory at the requested delivery boundary. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. ``POST /api/session/:sessionID/move`` """ @@ -2964,11 +2976,11 @@ async def prompt( Durably admit one session input and schedule agent-loop execution unless resume is false. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError - ConflictError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + ConflictError: The server answered 409. ``POST /api/session/:sessionID/prompt`` """ @@ -3018,12 +3030,12 @@ async def command( Execute a slash command callback immediately. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - CommandNotFoundError - LocationNotFoundError - CommandExecutionError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + CommandNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + CommandExecutionError: The server answered 500. ``POST /api/session/:sessionID/command`` """ @@ -3065,11 +3077,11 @@ async def skill( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - SkillNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + SkillNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/experimental/session/:sessionID/skill`` """ @@ -3106,11 +3118,11 @@ async def synthetic( Durably admit synthetic session input and schedule execution unless resume is false. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError - ConflictError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + ConflictError: The server answered 409. ``POST /api/session/:sessionID/synthetic`` """ @@ -3154,10 +3166,10 @@ async def shell( Execute one shell command in the session's working directory. Emits a shell.started event before execution and a shell.ended event with the merged output after. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/session/:sessionID/shell`` """ @@ -3190,11 +3202,11 @@ async def compact( Durably admit a session compaction request. Steers by default: it runs at the next step boundary instead of waiting behind queued prompts. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError - ConflictError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + ConflictError: The server answered 409. ``POST /api/session/:sessionID/compact`` """ @@ -3231,11 +3243,11 @@ async def wait( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``POST /api/experimental/session/:sessionID/wait`` """ @@ -3265,10 +3277,10 @@ async def context( Retrieve the active context messages for a session (all messages after the last compaction). Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - UnknownError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + UnknownError: The server answered 500. ``GET /api/session/:sessionID/context`` """ @@ -3310,12 +3322,12 @@ async def diff( context: Unchanged lines around each hunk. Omit for full-file patches. Raises: - InvalidRequestError - UnauthorizedError - MessageNotFoundError - SessionNotFoundError - LocationNotFoundError - UnknownError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + MessageNotFoundError: The server answered 404. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + UnknownError: The server answered 500. ``GET /api/session/:sessionID/diff`` """ @@ -3351,11 +3363,11 @@ async def generate( Generate transient text from the current session context without mutating session history. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``POST /api/session/:sessionID/generate`` """ @@ -3394,9 +3406,9 @@ async def log( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. ``GET /api/experimental/session/:sessionID/log`` """ @@ -3428,10 +3440,10 @@ async def interrupt( Interrupt active execution owned by this OpenCode process. Returns interrupted=true when an active execution was interrupted and false for the idle no-op. When resume=true, execution resumes pending steering input and next-in-line control items (manual compaction, moves) while queued prompts remain parked. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/session/:sessionID/interrupt`` """ @@ -3465,10 +3477,10 @@ async def background( Move active foreground backgroundable tools for this session into background observation. Idle requests are a no-op. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``POST /api/session/:sessionID/background`` """ @@ -3499,9 +3511,9 @@ async def environment( Replace the process environment used by local shell commands for this session. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. ``PUT /api/session/:sessionID/environment`` """ @@ -3533,9 +3545,9 @@ async def view( Mark the idle transition observed by the viewer as viewed. Raises: - InvalidRequestError - UnauthorizedError - SessionNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + SessionNotFoundError: The server answered 404. ``POST /api/session/:sessionID/view`` """ diff --git a/src/opencode/resources/shell.py b/src/opencode/resources/shell.py index 172fb47..9f84f7f 100644 --- a/src/opencode/resources/shell.py +++ b/src/opencode/resources/shell.py @@ -41,9 +41,9 @@ def list( List currently running shell commands for a location. Exited commands are not included. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/shell`` """ @@ -81,9 +81,9 @@ def create( Spawn one non-interactive shell command for a location. Combined stdout/stderr is captured to a file pageable via output. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``POST /api/shell`` """ @@ -119,10 +119,10 @@ def get( Get one shell command, including its status and exit code once exited. Raises: - InvalidRequestError - UnauthorizedError - ShellNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ShellNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/shell/:id`` """ @@ -159,10 +159,10 @@ def output( Page through captured combined output by absolute byte cursor. Raises: - InvalidRequestError - UnauthorizedError - ShellNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ShellNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/shell/:id/output`` """ @@ -197,9 +197,9 @@ def remove( Terminate and remove one shell command and its retained output. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``DELETE /api/shell/:id`` """ @@ -234,9 +234,9 @@ async def list( List currently running shell commands for a location. Exited commands are not included. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/shell`` """ @@ -274,9 +274,9 @@ async def create( Spawn one non-interactive shell command for a location. Combined stdout/stderr is captured to a file pageable via output. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``POST /api/shell`` """ @@ -312,10 +312,10 @@ async def get( Get one shell command, including its status and exit code once exited. Raises: - InvalidRequestError - UnauthorizedError - ShellNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ShellNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/shell/:id`` """ @@ -352,10 +352,10 @@ async def output( Page through captured combined output by absolute byte cursor. Raises: - InvalidRequestError - UnauthorizedError - ShellNotFoundError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ShellNotFoundError: The server answered 404. + LocationNotFoundError: The server answered 404. ``GET /api/shell/:id/output`` """ @@ -390,9 +390,9 @@ async def remove( Terminate and remove one shell command and its retained output. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``DELETE /api/shell/:id`` """ diff --git a/src/opencode/resources/skill.py b/src/opencode/resources/skill.py index f13aff4..37ce7fe 100644 --- a/src/opencode/resources/skill.py +++ b/src/opencode/resources/skill.py @@ -35,9 +35,9 @@ def list( Retrieve currently registered skills. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/skill`` """ @@ -75,9 +75,9 @@ async def list( Retrieve currently registered skills. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/skill`` """ diff --git a/src/opencode/resources/vcs.py b/src/opencode/resources/vcs.py index 6620c96..85365a2 100644 --- a/src/opencode/resources/vcs.py +++ b/src/opencode/resources/vcs.py @@ -43,9 +43,9 @@ def list( List local and remote branches available at the requested location. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/vcs/branch`` """ @@ -71,6 +71,7 @@ class VcsResource(SyncAPIResource): @cached_property def branch(self) -> VcsBranchResource: + """Operations under ``client.vcs.branch``.""" return VcsBranchResource(self._client) def init( @@ -88,12 +89,12 @@ def init( Initialize a repository using the selected VCS provider in a markerless project's directory and refresh its location services. Omitting provider defaults to git; built-in git and hg providers support initialization. An unknown provider returns 400; a registered provider without init returns 501. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError - ConflictError - VcsInitNotSupportedError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. + ConflictError: The server answered 409. + VcsInitNotSupportedError: The server answered 501. + ServiceUnavailableError: The server answered 503. ``POST /api/vcs/init`` """ @@ -124,9 +125,9 @@ def get( Get current and default branch information for the requested location. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/vcs`` """ @@ -160,10 +161,10 @@ def base( Infer a local review base from named branch creation history, or the repository default only when currently on that branch. Returns null before the first commit or when the provider lacks base metadata; ambiguous Git history requires an explicit base on diff requests. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``GET /api/vcs/base`` """ @@ -197,9 +198,9 @@ def status( List uncommitted working-copy changes relative to the requested location. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/vcs/status`` """ @@ -236,10 +237,10 @@ def diff( Diff HEAD to the working copy (working), the base merge-base to the working copy (branch), or the base merge-base to HEAD (committed). Omitting base preserves repository-default comparison; supplying it overrides the comparison without saving it. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``GET /api/vcs/diff`` """ @@ -279,9 +280,9 @@ async def list( List local and remote branches available at the requested location. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/vcs/branch`` """ @@ -307,6 +308,7 @@ class AsyncVcsResource(AsyncAPIResource): @cached_property def branch(self) -> AsyncVcsBranchResource: + """Operations under ``client.vcs.branch``.""" return AsyncVcsBranchResource(self._client) async def init( @@ -324,12 +326,12 @@ async def init( Initialize a repository using the selected VCS provider in a markerless project's directory and refresh its location services. Omitting provider defaults to git; built-in git and hg providers support initialization. An unknown provider returns 400; a registered provider without init returns 501. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError - ConflictError - VcsInitNotSupportedError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. + ConflictError: The server answered 409. + VcsInitNotSupportedError: The server answered 501. + ServiceUnavailableError: The server answered 503. ``POST /api/vcs/init`` """ @@ -360,9 +362,9 @@ async def get( Get current and default branch information for the requested location. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/vcs`` """ @@ -396,10 +398,10 @@ async def base( Infer a local review base from named branch creation history, or the repository default only when currently on that branch. Returns null before the first commit or when the provider lacks base metadata; ambiguous Git history requires an explicit base on diff requests. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``GET /api/vcs/base`` """ @@ -433,9 +435,9 @@ async def status( List uncommitted working-copy changes relative to the requested location. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. ``GET /api/vcs/status`` """ @@ -472,10 +474,10 @@ async def diff( Diff HEAD to the working copy (working), the base merge-base to the working copy (branch), or the base merge-base to HEAD (committed). Omitting base preserves repository-default comparison; supplying it overrides the comparison without saving it. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``GET /api/vcs/diff`` """ diff --git a/src/opencode/resources/voice.py b/src/opencode/resources/voice.py index 4835bd8..b823009 100644 --- a/src/opencode/resources/voice.py +++ b/src/opencode/resources/voice.py @@ -40,10 +40,10 @@ def session( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``POST /api/experimental/voice/session`` """ @@ -86,10 +86,10 @@ async def session( This endpoint is experimental in OpenCode and may change without notice. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``POST /api/experimental/voice/session`` """ diff --git a/src/opencode/resources/websearch.py b/src/opencode/resources/websearch.py index 7d21d04..707f3ea 100644 --- a/src/opencode/resources/websearch.py +++ b/src/opencode/resources/websearch.py @@ -37,10 +37,10 @@ def providers( Return the registered web search providers. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``GET /api/websearch/provider`` """ @@ -76,10 +76,10 @@ def query( Run one web search through the selected provider. Specify a provider to override the configured default. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``POST /api/websearch`` """ @@ -118,10 +118,10 @@ async def providers( Return the registered web search providers. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``GET /api/websearch/provider`` """ @@ -157,10 +157,10 @@ async def query( Run one web search through the selected provider. Specify a provider to override the configured default. Raises: - InvalidRequestError - UnauthorizedError - LocationNotFoundError - ServiceUnavailableError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + LocationNotFoundError: The server answered 404. + ServiceUnavailableError: The server answered 503. ``POST /api/websearch`` """ diff --git a/src/opencode/resources/worktree.py b/src/opencode/resources/worktree.py index df4cd23..986ac95 100644 --- a/src/opencode/resources/worktree.py +++ b/src/opencode/resources/worktree.py @@ -37,9 +37,9 @@ def list( Return the project's saved worktree inventory without loading configuration or running discovery. Raises: - InvalidRequestError - UnauthorizedError - ProjectNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ProjectNotFoundError: The server answered 404. ``GET /api/worktree`` """ @@ -77,10 +77,10 @@ def create( Load the project's canonical configuration, create a local worktree using its selected strategy, then run the project's setup script. Raises: - WorktreeError - InvalidRequestError - UnauthorizedError - ProjectNotFoundError + WorktreeError: The server answered 400. + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ProjectNotFoundError: The server answered 404. ``POST /api/worktree`` """ @@ -122,10 +122,10 @@ def remove( Load the project's canonical configuration and remove a saved worktree using its recorded strategy. Raises: - WorktreeError - InvalidRequestError - UnauthorizedError - ProjectNotFoundError + WorktreeError: The server answered 400. + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ProjectNotFoundError: The server answered 404. ``DELETE /api/worktree`` """ @@ -156,10 +156,10 @@ def refresh( Load the project's canonical configuration, discover worktrees across known checkout roots using all available strategies, and reconcile saved state. Raises: - WorktreeError - InvalidRequestError - UnauthorizedError - ProjectNotFoundError + WorktreeError: The server answered 400. + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ProjectNotFoundError: The server answered 404. ``POST /api/worktree/refresh`` """ @@ -194,9 +194,9 @@ async def list( Return the project's saved worktree inventory without loading configuration or running discovery. Raises: - InvalidRequestError - UnauthorizedError - ProjectNotFoundError + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ProjectNotFoundError: The server answered 404. ``GET /api/worktree`` """ @@ -234,10 +234,10 @@ async def create( Load the project's canonical configuration, create a local worktree using its selected strategy, then run the project's setup script. Raises: - WorktreeError - InvalidRequestError - UnauthorizedError - ProjectNotFoundError + WorktreeError: The server answered 400. + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ProjectNotFoundError: The server answered 404. ``POST /api/worktree`` """ @@ -279,10 +279,10 @@ async def remove( Load the project's canonical configuration and remove a saved worktree using its recorded strategy. Raises: - WorktreeError - InvalidRequestError - UnauthorizedError - ProjectNotFoundError + WorktreeError: The server answered 400. + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ProjectNotFoundError: The server answered 404. ``DELETE /api/worktree`` """ @@ -313,10 +313,10 @@ async def refresh( Load the project's canonical configuration, discover worktrees across known checkout roots using all available strategies, and reconcile saved state. Raises: - WorktreeError - InvalidRequestError - UnauthorizedError - ProjectNotFoundError + WorktreeError: The server answered 400. + InvalidRequestError: The server answered 400. + UnauthorizedError: The server answered 401. + ProjectNotFoundError: The server answered 404. ``POST /api/worktree/refresh`` """ diff --git a/tests/test_docs_coverage.py b/tests/test_docs_coverage.py new file mode 100644 index 0000000..9c8242b --- /dev/null +++ b/tests/test_docs_coverage.py @@ -0,0 +1,256 @@ +"""Fails when the public API and the documentation drift apart. + +Checks, in both directions: + +- every resource class and method reachable from the client is rendered in the API reference; +- every name in ``opencode.__all__`` and ``opencode.types`` is rendered or mentioned in ``docs/``; +- every resource group on the client is listed in ``docs/guides/index.md``; +- guides only reference methods and types that exist. + +The API reference pages for resources and types are generated by ``docs/hooks/types_reference.py`` at build time, +so these tests load that hook and check its output, plus the hand-written pages. +""" + +from __future__ import annotations + +import builtins +import importlib.util +import inspect +import re +from pathlib import Path +from types import ModuleType +from typing import Any + +import pytest + +import opencode +from opencode import resources as opencode_resources, types as opencode_types +from opencode._resource import AsyncAPIResource, SyncAPIResource + +ROOT = Path(__file__).resolve().parents[1] +DOCS = ROOT / "docs" +HOOK = DOCS / "hooks/types_reference.py" +GUIDE_INDEX = DOCS / "guides/index.md" + +DIRECTIVE = re.compile(r"^::: (\S+)((?:\n {4}.*)*)", re.M) +MEMBERS_OPTION = re.compile(r"members:\s*\[([^\]]*)\]") + + +def _load_hook() -> ModuleType: + spec = importlib.util.spec_from_file_location("docs_hook", HOOK) + assert spec is not None + assert spec.loader is not None + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + return module + + +HOOK_MODULE = _load_hook() + + +def _hand_written_pages() -> dict[str, str]: + return {str(path.relative_to(DOCS)): path.read_text() for path in sorted(DOCS.rglob("*.md"))} + + +def _generated_pages() -> dict[str, str]: + pages = {"reference/resources.md (generated)": HOOK_MODULE.resources_page()} + for title, names in HOOK_MODULE.type_groups().items(): + pages[f"reference/types/{title} (generated)"] = HOOK_MODULE.type_page(title, names) + return pages + + +HAND_WRITTEN = _hand_written_pages() +ALL_PAGES = {**HAND_WRITTEN, **_generated_pages()} + + +def _directives() -> dict[str, list[str] | None]: + """Maps each ``:::`` target to its ``members`` option, or ``None`` when all members are rendered.""" + found: dict[str, list[str] | None] = {} + for text in ALL_PAGES.values(): + for match in DIRECTIVE.finditer(text): + members = MEMBERS_OPTION.search(match.group(2)) + found[match.group(1)] = ( + [m.strip().strip("'\"") for m in members.group(1).split(",") if m.strip()] if members else None + ) + return found + + +DIRECTIVES = _directives() + + +def _client() -> opencode.Opencode: + return opencode.Opencode("http://127.0.0.1:1", password="") + + +def _resources(obj: object, path: str) -> list[tuple[str, SyncAPIResource]]: + found: list[tuple[str, SyncAPIResource]] = [] + for name in dir(type(obj)): + if name.startswith("_"): + continue + value = getattr(obj, name) + if isinstance(value, SyncAPIResource): + found.append((f"{path}.{name}", value)) + found += _resources(value, f"{path}.{name}") + return found + + +RESOURCES = _resources(_client(), "client") + + +def _public_methods(cls: type) -> list[str]: + return [ + name + for name, value in vars(cls).items() + if not name.startswith(("_", "model_")) and (inspect.isfunction(value) or isinstance(value, property)) + ] + + +def _source(obj: object) -> str: + path = inspect.getsourcefile(obj) # type: ignore[arg-type] + return str(Path(path).relative_to(ROOT)) if path else "its module" + + +def _target(cls: type) -> str: + return f"{cls.__module__}.{cls.__qualname__}" + + +@pytest.mark.parametrize(("path", "resource"), RESOURCES, ids=[path for path, _ in RESOURCES]) +def test_resource_is_rendered(path: str, resource: SyncAPIResource) -> None: + cls = type(resource) + assert _target(cls) in DIRECTIVES, ( + f"`{path}` ({_target(cls)}) is not in the API reference. Resource pages are generated by " + f"docs/hooks/types_reference.py from src/opencode/resources/; check that hook still finds {cls.__name__}." + ) + for name in _public_methods(cls): + method = getattr(cls, name) + assert inspect.getdoc(method), ( + f"`{path}.{name}()` has no docstring, so its reference entry is empty. Add one in codegen/render.py " + "(generated resources) and run `uv run python -m codegen`." + ) + + +@pytest.mark.parametrize(("path", "resource"), RESOURCES, ids=[path for path, _ in RESOURCES]) +def test_async_resource_matches_sync(path: str, resource: SyncAPIResource) -> None: + """The docs only render sync resources and say the async twin has the same methods; keep that true.""" + sync_cls = type(resource) + module = inspect.getmodule(sync_cls) + async_cls = getattr(module, f"Async{sync_cls.__name__}", None) + assert async_cls is not None, f"`{path}` has no async twin Async{sync_cls.__name__}" + assert issubclass(async_cls, AsyncAPIResource) + assert set(_public_methods(sync_cls)) == set(_public_methods(async_cls)), ( + f"`{path}`: {sync_cls.__name__} and {async_cls.__name__} expose different methods, but the docs say they match." + ) + + +def _mentioned(name: str) -> bool: + pattern = re.compile(rf"`{re.escape(name)}(?:\(\))?`|\bopencode\.{re.escape(name)}\b") + return any(pattern.search(text) for text in HAND_WRITTEN.values()) + + +@pytest.mark.parametrize("name", opencode.__all__) +def test_top_level_export_is_documented(name: str) -> None: + obj = getattr(opencode, name) + target = f"opencode.{name}" + if inspect.isclass(obj) or inspect.isfunction(obj): + assert target in DIRECTIVES, ( + f"`{target}` is exported but not rendered in the docs. Add `::: {target}` to the matching page under " + "docs/reference/ (clients.md, server.md, pagination.md or exceptions.md)." + ) + members = DIRECTIVES[target] + if members is not None and inspect.isclass(obj): + missing = [m for m in _public_methods(obj) if m not in members] + assert not missing, ( + f"`{target}` is rendered with a `members:` list that leaves out {missing}. Add them to the " + f"`::: {target}` directive in docs/reference/." + ) + else: + assert target in DIRECTIVES or _mentioned(name), ( + f"`{target}` is exported but never mentioned in docs/. Render it with `::: {target}` or mention " + f"`{name}` in a guide." + ) + + +@pytest.mark.parametrize("name", [n for n in opencode.__all__ if inspect.isclass(getattr(opencode, n))]) +def test_top_level_class_has_docstrings(name: str) -> None: + """Ruff's D1 rules skip private modules, so the hand-written runtime (``_client.py``, ``_server.py``, ...) is + checked here: every exported class and each of its own public methods and properties needs a docstring.""" + cls = getattr(opencode, name) + assert cls.__doc__, f"`opencode.{name}` has no docstring. Add one in {_source(cls)}." + missing = [m for m in _public_methods(cls) if not inspect.getdoc(vars(cls)[m])] + assert not missing, f"`opencode.{name}` members without a docstring: {missing}. Add them in {_source(cls)}." + + +def test_every_type_is_rendered() -> None: + rendered = {name for names in HOOK_MODULE.type_groups().values() for name in names} + exported = {name for name in dir(opencode_types) if not name.startswith("_") and name[0].isupper()} + missing = sorted(exported - rendered) + assert not missing, ( + f"These types are exported from opencode.types but not in the type reference: {missing}. The pages are " + "generated by docs/hooks/types_reference.py from src/opencode/types/_generated.py; update the hook if " + "types now live elsewhere." + ) + + +def test_guide_index_lists_every_resource_group() -> None: + text = GUIDE_INDEX.read_text() + top_level = [path for path, _ in RESOURCES if path.count(".") == 1] + missing = [path for path in top_level if f"`{path}`" not in text] + assert not missing, ( + f"Resource groups missing from docs/guides/index.md: {missing}. Add a row for each, linking its " + "reference entry (and a guide, if it needs one)." + ) + listed = re.findall(r"^\| `(client\.\w+)`", text, re.M) + stale = [path for path in listed if path not in top_level] + assert not stale, f"docs/guides/index.md lists groups the client no longer has: {stale}. Remove those rows." + + +# ---------- Stale references in hand-written pages ---------- + +CALL = re.compile(r"\bclient((?:\.\w+)+)\(") +FROM_IMPORT = re.compile(r"from opencode(\.types)? import ([\w ,]+)") +QUALIFIED = re.compile(r"\bopencode\.([A-Z]\w+)") +# Only CamelCase words with two or more humps, so `GET`, `DEBUG` or `Authorization` are not taken for types. +BACKTICK_TYPE = re.compile(r"`([A-Z][a-z0-9]+(?:[A-Z][a-z0-9]*)+)`") + +# CamelCase names in prose that are not part of this package. +EXTERNAL_NAMES = {"ClientApi", "HttpApi", "OpenCode", "TypeScript"} + + +def _exists(name: str) -> bool: + return ( + hasattr(opencode, name) + or hasattr(opencode_types, name) + or hasattr(opencode_resources, name) + or hasattr(builtins, name) + ) + + +def _stale_references() -> list[str]: + client = _client() + problems: list[str] = [] + for page, text in HAND_WRITTEN.items(): + for match in CALL.finditer(text): + obj: Any = client + for attr in match.group(1).strip(".").split("."): + if not hasattr(obj, attr): + problems.append(f"{page}: `client{match.group(1)}()` does not exist (no `{attr}`)") + break + obj = getattr(obj, attr) + for match in FROM_IMPORT.finditer(text): + module: ModuleType = opencode_types if match.group(1) else opencode + for name in (n.strip() for n in match.group(2).split(",")): + if name and not hasattr(module, name): + problems.append(f"{page}: `{name}` is imported from {module.__name__} but does not exist") + for match in QUALIFIED.finditer(text): + if not hasattr(opencode, match.group(1)): + problems.append(f"{page}: `opencode.{match.group(1)}` does not exist") + for match in BACKTICK_TYPE.finditer(text): + name = match.group(1) + if name not in EXTERNAL_NAMES and not _exists(name): + problems.append(f"{page}: `{name}` is not a name in opencode or opencode.types") + return problems + + +def test_guides_reference_only_existing_api() -> None: + problems = _stale_references() + assert not problems, "Docs reference API that does not exist. Fix or remove:\n" + "\n".join(problems) diff --git a/uv.lock b/uv.lock index cf8f27a..4489fd5 100644 --- a/uv.lock +++ b/uv.lock @@ -3,7 +3,8 @@ revision = 3 requires-python = ">=3.10" resolution-markers = [ "python_full_version >= '3.15'", - "python_full_version < '3.15'", + "python_full_version >= '3.11' and python_full_version < '3.15'", + "python_full_version < '3.11'", ] [[package]] @@ -102,6 +103,58 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl", hash = "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309", size = 67548, upload-time = "2026-03-19T14:22:23.645Z" }, ] +[[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]] +name = "backrefs" +version = "8.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/68/bc/c4b75b0279b2cf9e208c7dea5755a452d158a32abe1b7330824ff1127e86/backrefs-8.1.tar.gz", hash = "sha256:f86d9312df3ebae1241758af80809a319cafa1d8f32189edfb242c9aa55573b6", size = 6999089, upload-time = "2026-10-10T13:29:24.051Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/da/17/7be730f397b9239be5044a147f0cdfbd9605111b07af053c737b21d79d16/backrefs-8.1-py310-none-any.whl", hash = "sha256:438bd38dc7fa0cded52786a1351a2dad9efc2cda95d047284c41d916a22312a8", size = 380382, upload-time = "2026-10-10T13:29:12.764Z" }, + { url = "https://files.pythonhosted.org/packages/fd/d1/d25387b14119b7062fead6c9b2e87c2ab286beb346df79c6a649c095e979/backrefs-8.1-py311-none-any.whl", hash = "sha256:11f61846e446fa8637af2f5c073f1083aa58dbb7460b019fd51689f564e44f7e", size = 392180, upload-time = "2026-10-10T13:29:14.729Z" }, + { url = "https://files.pythonhosted.org/packages/7d/63/4c3078fcbb3956c55b24472d8375a1b7ad67203d4a1917512eee34d4fbee/backrefs-8.1-py312-none-any.whl", hash = "sha256:b472c76082769f86a97ffccfd1f2599b2b706610c6154955664fffe67e909035", size = 398092, upload-time = "2026-10-10T13:29:16.364Z" }, + { url = "https://files.pythonhosted.org/packages/df/22/60f30c9b8e497ca4bbac23991a726ebc267e23771a1b9d9c04b3a3c16dd6/backrefs-8.1-py313-none-any.whl", hash = "sha256:db577dbae1c61187534d35fc9bfbd0c01158fff6239a66fecf7590e5b17879a9", size = 400050, upload-time = "2026-10-10T13:29:18.09Z" }, + { url = "https://files.pythonhosted.org/packages/45/c7/80fa46ecb47717845ab9c07bce8651ef8f80aac5ec698e212d02ed2a9963/backrefs-8.1-py314-none-any.whl", hash = "sha256:1e857c32e91b8fe46ddb359ac21021a37b090fa4239566a61e9856123e334041", size = 411908, upload-time = "2026-10-10T13:29:19.876Z" }, + { url = "https://files.pythonhosted.org/packages/05/32/a57c5a5b7461b8c88266244014aa38052d76f64b064451b1d5342eb09bf4/backrefs-8.1-py315-none-any.whl", hash = "sha256:9c8fe3e2eaae4301a9ce787341d986e5ba25a887d89da6de0de5d58eca26a949", size = 417589, upload-time = "2026-10-10T13:29:21.821Z" }, +] + +[[package]] +name = "cairocffi" +version = "1.7.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/70/c5/1a4dc131459e68a173cbdab5fad6b524f53f9c1ef7861b7698e998b837cc/cairocffi-1.7.1.tar.gz", hash = "sha256:2e48ee864884ec4a3a34bfa8c9ab9999f688286eb714a15a43ec9d068c36557b", size = 88096, upload-time = "2024-06-18T10:56:06.741Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/93/d8/ba13451aa6b745c49536e87b6bf8f629b950e84bd0e8308f7dc6883b67e2/cairocffi-1.7.1-py3-none-any.whl", hash = "sha256:9803a0e11f6c962f3b0ae2ec8ba6ae45e957a146a004697a1ac1bbf16b073b3f", size = 75611, upload-time = "2024-06-18T10:55:59.489Z" }, +] + +[[package]] +name = "cairosvg" +version = "2.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cairocffi" }, + { name = "cssselect2" }, + { name = "defusedxml" }, + { name = "pillow", version = "12.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "pillow", version = "13.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "tinycss2" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c6/80/db62c0a96d2e55282c83524f6b1d02f09c7fd7f612e93bf83e30de1dc75c/cairosvg-2.9.1.tar.gz", hash = "sha256:861bc28ad97ce4f537d50eb3d6ee97a7afcccec9c61ac25c4e7d073fe409aec7", size = 41256, upload-time = "2026-09-07T10:35:09.563Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/51/8041c2e70649e5b7f2a0aedbbbd0609ac099cfaa0cbde2014279c9c05756/cairosvg-2.9.1-py3-none-any.whl", hash = "sha256:f91c5628e834be024a0ed4544d76261cd84016a4c73bcdf26c386495825c05a1", size = 46165, upload-time = "2026-09-07T10:35:07.952Z" }, +] + [[package]] name = "certifi" version = "2026.10.19" @@ -120,37 +173,279 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/9e/ef/008a1939e372c06329a3fce4279c02f328488f3526744906eeec3da7ad5f/cffi-2.1.1.tar.gz", hash = "sha256:dd31f52ea1086513bb9df30f8fcee9b8918323ae067a3d5b78bc826a000712be", size = 530807, upload-time = "2026-08-03T21:21:18.939Z" } wheels = [ + { url = "https://files.pythonhosted.org/packages/b6/d2/2cde336b375f55c76ca670f0be3978cc048e31e24f3b4d7ce8473150a388/cffi-2.1.1-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:baed1e86cc735622097354b9d1281406caf42ff42a886d29faa8e8d1630333be", size = 183779, upload-time = "2026-08-03T21:19:15.602Z" }, + { url = "https://files.pythonhosted.org/packages/94/1a/4b2f7c92293ba05cbd4a9a1b28faaf0326272d9488e6354657571c48a7aa/cffi-2.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ca82be1a1d406ecfe1d25dc16cb33488e5a16bf4438c9fb590484ea29d92478b", size = 184178, upload-time = "2026-08-03T21:19:16.67Z" }, + { url = "https://files.pythonhosted.org/packages/17/0b/ba385d8ccedf926c3cd06e8e2f327027da5afe5f0eb30f1f7bc43ac55125/cffi-2.1.1-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:42e2f76b9455f5a9a844f770bf3e200ed3da0e15f5df3db9c31fe80b04b3d004", size = 211037, upload-time = "2026-08-03T21:19:17.705Z" }, + { url = "https://files.pythonhosted.org/packages/a3/b9/0f2e58b2cefa33255bff36935d42b13180fe559bba82596540eb404bde7d/cffi-2.1.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5a59cc1c4442bc3d5c703bf720b51138d0bfc173618807c9ee2490a7541dd3d9", size = 218652, upload-time = "2026-08-03T21:19:18.735Z" }, + { url = "https://files.pythonhosted.org/packages/37/15/180e0dab27b9312c7479003d14c9e547634b7dcb934e2cc4650e1b131a7a/cffi-2.1.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:9f8d177621de5cb38ee3e731eda45d421db093ec0739f46a5594babda7987a98", size = 205422, upload-time = "2026-08-03T21:19:19.96Z" }, + { url = "https://files.pythonhosted.org/packages/18/d4/03026f0c850cbbaa9030750490225b4a7f4d524ea4df72c3cc740a90f4ef/cffi-2.1.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:75f80557d1389eddbd0de2681f6a390a0c5338c31ddaa821381c203fc3fd50d9", size = 205444, upload-time = "2026-08-03T21:19:21.246Z" }, + { url = "https://files.pythonhosted.org/packages/75/77/60bebf6f818bec84210ac5b6979ce4eeadce6fbbaabc9c7ab23e506d1ce5/cffi-2.1.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:194cffa889098ced9976c3fc6340305e43f6303657d298da55366907c05c22d6", size = 218742, upload-time = "2026-08-03T21:19:22.523Z" }, + { url = "https://files.pythonhosted.org/packages/b0/ae/679bf47e73fd77b352171727f07de559a003f14de5d02b904a6ec1fa73ca/cffi-2.1.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5bb4e7ea95dcd6a014a6fef62e62467d67d8e582326443f3d68e71d6320a9fcf", size = 221054, upload-time = "2026-08-03T21:19:23.694Z" }, + { url = "https://files.pythonhosted.org/packages/09/b8/eefc0e06913b70aa153bf74c946094a18f58fd4aff11b7f372bfdfdca050/cffi-2.1.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3d22a20b1fb1632cc72c22f95f7b0d2961c3e1c235f245ba4c606c4771035659", size = 213489, upload-time = "2026-08-03T21:19:24.922Z" }, + { url = "https://files.pythonhosted.org/packages/6f/13/4e56852824a03cdf68523a35686f1c28eacd4bd30a7b0a78e682e6e6e1d3/cffi-2.1.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1dea0e4d7d4f11f619fe8c1d76caf49e24405b4b5743c0e3be16a500ecd930c9", size = 220241, upload-time = "2026-08-03T21:19:26.214Z" }, { url = "https://files.pythonhosted.org/packages/99/7f/040f9e163e4acac3ee3d85b02d00b2576e7ca980d8785f0a3a5f1a9bf7f5/cffi-2.1.1-cp310-cp310-win32.whl", hash = "sha256:7ce713ace7c0e4520535b42b77eaa742c16dab813978064913e5a3cf82973b41", size = 174578, upload-time = "2026-08-03T21:19:27.338Z" }, { url = "https://files.pythonhosted.org/packages/ba/0b/644a2ec1a4eaba49c2939410bb1eb1d25b09d6d0582f5d2f95c537043725/cffi-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:a48d62ab9d6f4f98c983223a547af44be6ca3691074c31cecced6facd3ba2dc1", size = 185082, upload-time = "2026-08-03T21:19:28.409Z" }, + { url = "https://files.pythonhosted.org/packages/70/d2/16d99a0c4948febc0ebd133a13b2f688ff7f8cb04da971e1128872ce0c03/cffi-2.1.1-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:c8d2c9fd1f2d16f780d15127abb050d13d1a76c03a4bd87d7e4980e45e511e12", size = 183838, upload-time = "2026-08-03T21:19:29.637Z" }, + { url = "https://files.pythonhosted.org/packages/cd/95/31b535a9f0220ae9f357de4a08d57ce89cb417653c2fd9f075f50822a388/cffi-2.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:398aff33cee2767e3e781d2554c54bd0dff386bb437581e0d8011fde1a942ec1", size = 184168, upload-time = "2026-08-03T21:19:30.764Z" }, + { url = "https://files.pythonhosted.org/packages/ad/5a/4707a0dc1f203f5dde5a907b0d4e3c25d71120241048bd5bc6f1bb9d4e71/cffi-2.1.1-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:154852545011f779917b11c78db2358d095da62a9a172b78ad0a583ee5adc0d0", size = 211805, upload-time = "2026-08-03T21:19:31.867Z" }, + { url = "https://files.pythonhosted.org/packages/ad/66/c19feabb28485b6e0bbaaafa90837a1ef5d302e90f2178bd33f17a49879b/cffi-2.1.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3311ed60d36f83378794e1009ac6258bafbf81f7888b4caa7b35a521e3f95813", size = 218716, upload-time = "2026-08-03T21:19:32.896Z" }, + { url = "https://files.pythonhosted.org/packages/a7/92/500760486c8baab49a7a8a58ba7fc3355ec3974b454b8a09e528efde9e1d/cffi-2.1.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6e192623c49c94421616a5778fba35cf0d5a8d000650c1967ef4448ee5cdd990", size = 205569, upload-time = "2026-08-03T21:19:34.142Z" }, + { url = "https://files.pythonhosted.org/packages/a5/a7/a67c733254d6e7373f7822f8082d8d6beade791e0cf12a7611f376fa61c7/cffi-2.1.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:a6e721d4b0e45d5b65e87534470e67b18dcd092c83f68fba09f152b9cbc061af", size = 204907, upload-time = "2026-08-03T21:19:35.174Z" }, + { url = "https://files.pythonhosted.org/packages/f7/a4/4399daaf8f7dfee9d7c3327fdb0426ee041cc63edc358b93911ceb2bfc7a/cffi-2.1.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:34e261f78cb6ceaaa36f42f2613f4380d94d9c759a9c73c769ee6e0247364632", size = 217807, upload-time = "2026-08-03T21:19:36.286Z" }, + { url = "https://files.pythonhosted.org/packages/28/f7/dabe6da2466ecbd82dc62e7342dc6b1065dad990c06f00f0ede9ebf2a0ed/cffi-2.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7225e4514edb64eb6740324353e0da0711954fd8d7da4576755b1c6e09b697cd", size = 221252, upload-time = "2026-08-03T21:19:37.416Z" }, + { url = "https://files.pythonhosted.org/packages/ce/87/616202d8e51342c07d2534c510111c4cc37201775ce8f60802c9335d1edd/cffi-2.1.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df913725b79db7bcf03448f36b7bf8815363417d5b58deecf9305e3e30f0f21a", size = 214214, upload-time = "2026-08-03T21:19:38.507Z" }, + { url = "https://files.pythonhosted.org/packages/b4/c6/ab025d75d2c26c19b087c0124e75ee31cb65032f4fe345d356d8c507ab97/cffi-2.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f5cfbc5fe74540d335175b656c725d74d90e3730c626d92575eea35029d9afaa", size = 219408, upload-time = "2026-08-03T21:19:39.809Z" }, { url = "https://files.pythonhosted.org/packages/db/e2/7e8109f65445bdc673a7b54f02c677de462db75674220fd1335efc8eb598/cffi-2.1.1-cp311-cp311-win32.whl", hash = "sha256:f8ec5e643a9a937f64e1999eb9f75d072263751912dc5cd06d3c85f8f44be7c3", size = 174470, upload-time = "2026-08-03T21:19:41.246Z" }, { url = "https://files.pythonhosted.org/packages/73/c0/77ba02423c2f7d7091143c45cd49e0e6575c4c1967394bb542bd923a9b74/cffi-2.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:42f6930c31dc7f50732c9ae793c2786c7b6b044195967bbdde40bb9be81c4cc0", size = 185096, upload-time = "2026-08-03T21:19:42.615Z" }, { url = "https://files.pythonhosted.org/packages/7c/47/9f1f85f9672ceda4984dc6c4f8824e8558992a2972c3d3c81fb8eb28d4ba/cffi-2.1.1-cp311-cp311-win_arm64.whl", hash = "sha256:c7659f22557c5a0bc4855cd635f55edec690cc008a40768527762cb9fb263455", size = 179941, upload-time = "2026-08-03T21:19:43.747Z" }, + { url = "https://files.pythonhosted.org/packages/10/69/43965eccfdead3b9220015fd1320e117be8c6ed01a62ffab76eeb752f5d5/cffi-2.1.1-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:c8c69575568085ba0b1b10c0249d779a214aea6f6522e949a0fc9fb0fcb449d0", size = 184821, upload-time = "2026-08-03T21:19:44.887Z" }, + { url = "https://files.pythonhosted.org/packages/54/7d/16e5a096677b5e313ca80cd5e5170efa3ea44624a82bb111925522da64b1/cffi-2.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f81b3b8f3d4e343550fa4baa0e479bba9f2d29ce9c2e9b51d1ce1718d7442fcf", size = 184719, upload-time = "2026-08-03T21:19:46.129Z" }, + { url = "https://files.pythonhosted.org/packages/56/e6/8941622732edec876dd17d0453dce07317ae96db34f2ec1436c9d3785986/cffi-2.1.1-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:811bd1e21d32de12efca32393a0ab3f5133b54fce9bd44b8bd77ab07da14bf6a", size = 214799, upload-time = "2026-08-03T21:19:47.218Z" }, + { url = "https://files.pythonhosted.org/packages/44/de/f98430906df1545ffde0d543dd124a7a439bc2cd32b36b9c53f805df7333/cffi-2.1.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:68e62fe11f30d5ca8289242866f0a5291402d8529ca2178ab8afc5c9694ae890", size = 222389, upload-time = "2026-08-03T21:19:48.331Z" }, + { url = "https://files.pythonhosted.org/packages/6a/5b/717f1526b9957b34456313c31645c5b82b8fb5c3fe9e4752999be7128bfc/cffi-2.1.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:4a7c934f7360e8cd64fe9efadcbd10c7c6364f531e432b9a4bf5ccbc9e0e8b50", size = 210249, upload-time = "2026-08-03T21:19:49.543Z" }, + { url = "https://files.pythonhosted.org/packages/64/b3/f8aa4f3e34986c7e4ec45072d1b1b9dd295b6b18007b45518d79726dd725/cffi-2.1.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:3143d81e29e1e20a9ce10901ec369012947876596f75a222235965f2b7ae832e", size = 208775, upload-time = "2026-08-03T21:19:50.918Z" }, + { url = "https://files.pythonhosted.org/packages/b1/db/dceb9dd5b231e1da801793f8acc9f3c52a7e1afe40bb1aae37e02b0faad5/cffi-2.1.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c1453022f490d2459a11819d83ad1d586e9ff65a12ac3e705ffebd46d3685dcf", size = 221822, upload-time = "2026-08-03T21:19:52.054Z" }, + { url = "https://files.pythonhosted.org/packages/a0/d2/6cd24ae3be000a634109c247d1475d62e5616d0dc78c82770942ec384248/cffi-2.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:208f941bb9d18e768138677f0a6d2ce01f590df56043dda1df1535ac57c88517", size = 225232, upload-time = "2026-08-03T21:19:53.109Z" }, + { url = "https://files.pythonhosted.org/packages/cb/52/3fa190537004dd7f0ab860a6dc7c0175b8667f68d1e618a46f5498d30250/cffi-2.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:210019b6c7cf07f081b4c54635c8cf744377001350e29cc0f81c4377b4797735", size = 223597, upload-time = "2026-08-03T21:19:54.515Z" }, { url = "https://files.pythonhosted.org/packages/80/fb/0bb75b7039588c074b37ae99f40d9bfddf990ecb2fbc346ebccd2e56b9be/cffi-2.1.1-cp312-cp312-win32.whl", hash = "sha256:046bfc24911b37851ee1b51aab8bffe713d89c68c6a057b09484ce9fd5f69b4e", size = 175292, upload-time = "2026-08-03T21:19:55.566Z" }, { url = "https://files.pythonhosted.org/packages/d9/79/615cc094e2fb508cade7de88d3b4f6c4ec2bab695c97bce9153dc65aadf5/cffi-2.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:f53e442b08449d42821fa4a4fba000095af9f62742a500f978a9f557ec44339a", size = 185919, upload-time = "2026-08-03T21:19:56.89Z" }, { url = "https://files.pythonhosted.org/packages/70/c6/d0ea84713fe46b243a436a18fcd47d639732747e21635c8a27191b06dc30/cffi-2.1.1-cp312-cp312-win_arm64.whl", hash = "sha256:7bde5e4cc5c10140859842b9d383af292b22639a4dffb725314baf45968cef80", size = 180093, upload-time = "2026-08-03T21:19:58.155Z" }, { url = "https://files.pythonhosted.org/packages/9d/f4/035513d4117049066b4779dc3b7c0c0fdad175fa13731c9f4003f1cd1478/cffi-2.1.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:b5bdfd1c873d4e093aabc0ca84c4ca6dbc4f752afb5c86f146d9742580c9da2e", size = 194248, upload-time = "2026-08-03T21:19:59.399Z" }, { url = "https://files.pythonhosted.org/packages/76/af/2aeb4dbb5fc41a04161ae9ff1518de7cec08e164f44a8ce6a4cf7fd2cd1d/cffi-2.1.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:31348097ff5bbe827ccc41795d4dd099d9f0625e7def00ee653c137a490c2a6c", size = 196908, upload-time = "2026-08-03T21:20:00.746Z" }, + { url = "https://files.pythonhosted.org/packages/a7/46/2e5fdde8555706dd98139a910ca11be02809f3f605ce956f655d0214e100/cffi-2.1.1-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:9d2055050ea716bd38b7f7f1579c275386646b4894c155a3e2f3cd62ed41b7c6", size = 184805, upload-time = "2026-08-03T21:20:02.02Z" }, + { url = "https://files.pythonhosted.org/packages/55/41/4c7042f317b9217502988f0873af87e16ad606dc20f84e546e3e6ce9764c/cffi-2.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19ee6127ee34de7d83ce3d371ebc5ed91addbdcc39f9ab15ce4eb35a4e534971", size = 184764, upload-time = "2026-08-03T21:20:03.141Z" }, + { url = "https://files.pythonhosted.org/packages/43/1f/1c3d90d91811c8f86ced9ed637956c54bfe5b79ca98fe976d7f8c8979f6b/cffi-2.1.1-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:6a8dddef476fab96d066d578fc88526767b836ab5ab21754e1d5bf3879c31c7c", size = 214722, upload-time = "2026-08-03T21:20:04.377Z" }, + { url = "https://files.pythonhosted.org/packages/37/6f/3b5ce4c3b2192d250f04908f2bfd91ef34552ec8f7716a5d4abdb8d67bb2/cffi-2.1.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f16c709686a78c727bbbf059f92b0bf41c6fc60deec706d2dc19f529175a6125", size = 222369, upload-time = "2026-08-03T21:20:05.544Z" }, + { url = "https://files.pythonhosted.org/packages/02/10/4b3c75dde3d9663c9e02ba05c2668b954f671d4bbe346413ca8c696b295a/cffi-2.1.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:fcd22650c908d7b7da162bbfaab594a1227a15d1643a98c68b122ac642fa2264", size = 210175, upload-time = "2026-08-03T21:20:06.75Z" }, + { url = "https://files.pythonhosted.org/packages/df/62/14f74b9543e605d17701dc797b815958b8bb70b7624ce1b832ddad48ed6c/cffi-2.1.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:aa9511c62d14da7aacc9b4bf51f3f697a621e83b2d6919008243c3aad168eea3", size = 208670, upload-time = "2026-08-03T21:20:08.04Z" }, + { url = "https://files.pythonhosted.org/packages/95/95/86342356ff5953b3fb06f7ef7c5bee212d45e770abc7218d451b9148313c/cffi-2.1.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a931079504ecc49efed7744c476a5c343a92fabf66dec2db95edb1b2fdc770e2", size = 221824, upload-time = "2026-08-03T21:20:09.274Z" }, + { url = "https://files.pythonhosted.org/packages/eb/ff/7b3429ff53aafe931ed8a5fc69f481bbef7ba6de87ddcbb63d08f483f613/cffi-2.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a2d7755bef5a12ed488f4ef1f1b69ee9191d7396083b755a5d2295f6edb4768b", size = 225148, upload-time = "2026-08-03T21:20:10.7Z" }, + { url = "https://files.pythonhosted.org/packages/34/34/a95870b9221e09cf4f2ce3178b1a210abdfe63a1bd357da940418d7b8d15/cffi-2.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e0bcb7e0f677f543555d2adff3bf19c05f66cdb4796e5ff602442ab2fe3c4ef7", size = 223564, upload-time = "2026-08-03T21:20:12.165Z" }, { url = "https://files.pythonhosted.org/packages/70/ea/839b50531021a647fb5e929f72cf97bc1ff702b5472166164b5b6e76b851/cffi-2.1.1-cp313-cp313-win32.whl", hash = "sha256:334644fbac4eff73d985a17a91226df55d0f394160c4cfb880e084c8f7161cac", size = 175263, upload-time = "2026-08-03T21:20:13.559Z" }, { url = "https://files.pythonhosted.org/packages/60/a6/8b149b2c3f2e11aaa1618ef64500b45f50f22c57a977a4dff1aff1f91042/cffi-2.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:1aa5645c30469b09530c4ebca77ebf8f17618293c58f8549cb1a543a50236e7d", size = 185688, upload-time = "2026-08-03T21:20:14.69Z" }, { url = "https://files.pythonhosted.org/packages/01/9a/11f687cb39d6a3504060d5242f04f48c735afb4d3d533958a20594890cb2/cffi-2.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:63bbfd5ded17c4840ac07cd8f1c21ba9d9708141f840b324f422f41b207e3973", size = 180078, upload-time = "2026-08-03T21:20:15.917Z" }, { url = "https://files.pythonhosted.org/packages/d3/7b/d6bbf82b8b96e7391438898c42f5bd96dd02030fd5b64937d248220003e2/cffi-2.1.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:7dbb61fe3a7699468030f71bbe5f8a0e326a151daa91beb11a6fc1f980c55e1c", size = 194064, upload-time = "2026-08-03T21:20:17.148Z" }, { url = "https://files.pythonhosted.org/packages/94/e6/bcc91b283be94735e268487a054004f0aa19947b6348fa367db53230abc8/cffi-2.1.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:f24fb43132a4c6b4cb4eb029492919b2db645be6808d738f244fd146c03c32cb", size = 196720, upload-time = "2026-08-03T21:20:18.268Z" }, + { url = "https://files.pythonhosted.org/packages/d9/99/c4b0c17cacdc9c3b8f280026286a9826d6a208c0f047591a3c3ce99b91fd/cffi-2.1.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d28630f5854ab07ab1fd4aba756de52326c82e6be15d414b12793f1975048b54", size = 184964, upload-time = "2026-08-03T21:20:19.708Z" }, + { url = "https://files.pythonhosted.org/packages/b3/a9/9db617d05d7367c1ad0ab00b3aa6e6f9281edd689b4ee9ea0e5a84e89c97/cffi-2.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:661c298b4821edebead0c91edd2b00374d67ad7c5a1f7a91d4442633b79d6a72", size = 184962, upload-time = "2026-08-03T21:20:20.833Z" }, + { url = "https://files.pythonhosted.org/packages/67/b8/b42132ca113dc567d37684437b46ca1dafc885902b02a110a02d5b511857/cffi-2.1.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:58acb8ab8e295e6c5ea12f888cbb13cf21511ef2a3303a23f4325c29d17fe5c1", size = 222328, upload-time = "2026-08-03T21:20:22.118Z" }, + { url = "https://files.pythonhosted.org/packages/80/10/c5c0cbf0a657aecf59ef511409734230bf556f05a0d6c9eed7aa5c0a0166/cffi-2.1.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:456a61fa52d579ebf9df2e9552ead5129855dbaff6c1e5a9b1bc408809bdc062", size = 209985, upload-time = "2026-08-03T21:20:23.401Z" }, + { url = "https://files.pythonhosted.org/packages/d5/6c/bfa0b87b03b9238148beca990292843c9396ba069b54496596594173de7b/cffi-2.1.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:a4f00aa42f75d6e4595e8866e748cc1705adc0cddfeb2ca86d0d03993d63ba03", size = 208530, upload-time = "2026-08-03T21:20:24.628Z" }, + { url = "https://files.pythonhosted.org/packages/e9/02/4e7d553a7ac4b4238b38b3c1b80d486e9d4436f8d2acbf87a0997fe3f402/cffi-2.1.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b0431303acaea1089ad4b3e9ce4e6518193def1118d4073ca848635ee4ea2e96", size = 221525, upload-time = "2026-08-03T21:20:25.758Z" }, + { url = "https://files.pythonhosted.org/packages/82/1d/a4aaf9babd75acb4d5f223bff71533bee748dd770a382619a798960ee9ba/cffi-2.1.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:64faea20f4e2613363a1a9b9c7dd73058f3ecd00133a511e72ad7c511658f527", size = 225053, upload-time = "2026-08-03T21:20:26.985Z" }, + { url = "https://files.pythonhosted.org/packages/81/10/5dc0e7bdd18e22107054288283380fc97a06ae3f1656a106908d666a3c88/cffi-2.1.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5c58fe613dc5e5336357eff555824a314d8e43282600435c8d1cb6a7a2fedd13", size = 223213, upload-time = "2026-08-03T21:20:28.277Z" }, { url = "https://files.pythonhosted.org/packages/0b/e9/d0061c364cde06ee43168a0d076ac1da512cbc380d44767b844ba34fe2b6/cffi-2.1.1-cp314-cp314-win32.whl", hash = "sha256:1a18a57b58cfb21fc28d72e876acf10eaed67a1ed96226f92af4df681d571c4c", size = 177682, upload-time = "2026-08-03T21:20:44.288Z" }, { url = "https://files.pythonhosted.org/packages/a7/06/1c3e01e3ba14c39f6d10bfbac52753b7e22259e38088e5cfe1d704918690/cffi-2.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:3222ba5d678f80a030e6afbcc33dc1ae5cb45facabb61cee2c7016b8432fde48", size = 187949, upload-time = "2026-08-03T21:20:45.623Z" }, { url = "https://files.pythonhosted.org/packages/87/5b/da4e39efe18eeb89cf580ea9cfc66b6a7c3eadb808fc0cc1d3a295cb5a5d/cffi-2.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:ab36d55f9ed2d067327667c2fea18dda018eb628dd6347aa01dda6cf1f5d3836", size = 182947, upload-time = "2026-08-03T21:20:46.955Z" }, + { url = "https://files.pythonhosted.org/packages/23/59/40338bf421c5accea1d45158170c87006ef1cd371b05c077e76476949728/cffi-2.1.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7750c6449dff7864bb9bb27ddfb0267756189201a3afc911d82b3caacd70dfc3", size = 188504, upload-time = "2026-08-03T21:20:29.495Z" }, + { url = "https://files.pythonhosted.org/packages/7d/47/5ecf1023850036e674c77ec4de86182d309ae344e39e7cba984b7df5d647/cffi-2.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0beceaabe56af686895136a2de78db54ecd8e4046b236b8fd6d6cb61389e9bf2", size = 188259, upload-time = "2026-08-03T21:20:31.291Z" }, + { url = "https://files.pythonhosted.org/packages/2a/9c/92934c3bea9f785b23eba304538c0b4d37a2a96d2431eb3a1bc87a11aa19/cffi-2.1.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:49cbc70e6542d4ccccb936558d1064a8012541e78f821f955cff24e357776c94", size = 223864, upload-time = "2026-08-03T21:20:32.571Z" }, + { url = "https://files.pythonhosted.org/packages/4d/45/ba4c93527bc38616a8bd36488acb69a2212d60486794f0c1f318949bbb76/cffi-2.1.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:e2d65b31f36619cda3999b78b2aa9632e76b78448e7a56fc4240824200e7c4fc", size = 211538, upload-time = "2026-08-03T21:20:33.808Z" }, + { url = "https://files.pythonhosted.org/packages/80/e9/b6ef565e452acb932fb0cb5443f44a78efbd1233e566f02b5a83855e9115/cffi-2.1.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:28907ab9bfb6aa13184cfc17c6b8e1023c5ab6fd7076d8c20a35e59fe04f8f29", size = 210688, upload-time = "2026-08-03T21:20:34.974Z" }, + { url = "https://files.pythonhosted.org/packages/9a/95/eff5f0cee78d2eabc7eebffec40d3fc1876b5f3c95582e018bb4b99601f2/cffi-2.1.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:51b31d1c98274844cfd7838ce00bfc27c7423a4dc00fc0772fc3331c2cc90676", size = 223803, upload-time = "2026-08-03T21:20:36.564Z" }, + { url = "https://files.pythonhosted.org/packages/fa/01/579d39fb8bef00a335a23d83757b44feb24cd6345a2c451b64cb67b9c362/cffi-2.1.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e7cecbaadb83884793e05828cee59b210b24583b9c7425d0ba6a754fe22eb4e", size = 226763, upload-time = "2026-08-03T21:20:37.816Z" }, + { url = "https://files.pythonhosted.org/packages/8d/b0/0b44f47c60b01b57b6e2bbd92343f13a85a1d93bc46ccf6e47e244acd99c/cffi-2.1.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:25792eac27877609e7bb06d42ff88278a6624fff2ba9bbb523c09616b117e80f", size = 225688, upload-time = "2026-08-03T21:20:38.959Z" }, { url = "https://files.pythonhosted.org/packages/eb/d2/3b7176cb570a1d3e27faf67b72f591af508036e0d8b2be2ef9af9e8c84bb/cffi-2.1.1-cp314-cp314t-win32.whl", hash = "sha256:8ef53b2de9bcb9197d31854256575d59dbac0cba72ac627bb291ef5eceb74be4", size = 182868, upload-time = "2026-08-03T21:20:40.388Z" }, { url = "https://files.pythonhosted.org/packages/56/78/31f00c1bcd97c9bbf55f1bfdf5bc809a5de8887473e90bb9960dca825e80/cffi-2.1.1-cp314-cp314t-win_amd64.whl", hash = "sha256:616f097f2fe415bc92a247f02e11f634e1f9e9a83d327e3c915c15089c87869e", size = 194104, upload-time = "2026-08-03T21:20:41.725Z" }, { url = "https://files.pythonhosted.org/packages/7b/1b/58496f2ed0a35de575250c02a43ab3cc2c04d494a88fed31c1cabc0fd176/cffi-2.1.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ad2c86c495b899d862ea0f4b42891b8713a3bd45dd4105c7fd51c2a72f39f3a5", size = 186402, upload-time = "2026-08-03T21:20:43.042Z" }, { url = "https://files.pythonhosted.org/packages/c1/8f/9ebe220eab48a093d1a5a5e339ab0dc7316eef3bb04d63c42f0251b61f50/cffi-2.1.1-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:dddad92b554513a31f272570678ba307fb9f618f05e3d4a5eacafff9eae03e1d", size = 194043, upload-time = "2026-08-03T21:20:48.179Z" }, { url = "https://files.pythonhosted.org/packages/ff/69/844bad3ece306c4782c2ecb93597035b6690d48704b803914c199da1e8b3/cffi-2.1.1-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:da0e573f9f97159390c89d9f1a9e41908b66d408cc5b58d08cf3847d844c531b", size = 196737, upload-time = "2026-08-03T21:20:49.457Z" }, + { url = "https://files.pythonhosted.org/packages/1b/8a/af668013284634733f02d683458a0728739c7d6ddb5e14cb0c20832266fe/cffi-2.1.1-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:fb92203a88b3d3053034db775110081c49d28be6551923805e039924093761e4", size = 184933, upload-time = "2026-08-03T21:20:50.639Z" }, + { url = "https://files.pythonhosted.org/packages/0c/75/2f5207ff6d1a613133b23a5203cc0c2a628313b5eb3974d7956ae3c57950/cffi-2.1.1-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:2ae64be792b8966f2c69538199728b290e34726562896df1e5dc8ffd8d8188e8", size = 185002, upload-time = "2026-08-03T21:20:52.173Z" }, + { url = "https://files.pythonhosted.org/packages/e2/31/9e1313b0a6e30e91b3b3d3fff51ae99c857c07738e3afcce1f7334e1b7ab/cffi-2.1.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:507a24c282e0f42f8ed737cf048572cbf580468da5555764a8331735e9c736b6", size = 222271, upload-time = "2026-08-03T21:20:53.462Z" }, + { url = "https://files.pythonhosted.org/packages/50/e3/f6234a833e6e08c7007003074723c406559eecf9b48dfc97471e5a8eb7a0/cffi-2.1.1-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:246fa40ce8645a614ff682e0b70f37134e460eaf93a775e0cbe3cca585a67a80", size = 209919, upload-time = "2026-08-03T21:20:54.783Z" }, + { url = "https://files.pythonhosted.org/packages/0d/fc/5f74e293fced6edb51af3a46c4ccf6c23c9943774ecb375ddbd522c76add/cffi-2.1.1-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:471cee653ae88de62096552e6d24ccb4a5adb8c8c9f10b5054d0122c15bf2779", size = 208529, upload-time = "2026-08-03T21:20:56.066Z" }, + { url = "https://files.pythonhosted.org/packages/44/16/29e6d01b388bef055ecd6ca8244b3f4d336bd09e92d5d892187b9601084e/cffi-2.1.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aeae0e330c9f6acd681f647d46cefd30c29f93e3392882e792e82080c9691399", size = 221630, upload-time = "2026-08-03T21:20:57.336Z" }, + { url = "https://files.pythonhosted.org/packages/a4/18/fa7f1f6857d5eb88a4ca99ffcbfb7c387a287ccc154c64a73e86314745d7/cffi-2.1.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:42a494cee34437f05546455144f2b5d9ac09b1face62bcfce597d2e521066688", size = 225134, upload-time = "2026-08-03T21:20:58.675Z" }, + { url = "https://files.pythonhosted.org/packages/e0/9f/e8e3dfa04a1b4c241f8c91faacad872b4d4efd051d49764ad4e2fd4b9fea/cffi-2.1.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:cc572dace3f60ef98d7b12ff411d20f5362feb31a0439eab0085bbfd349982d7", size = 223197, upload-time = "2026-08-03T21:20:59.968Z" }, { url = "https://files.pythonhosted.org/packages/f8/7e/8debeb04f1ab9fe2a6963964cd6f1aaf7192627b83926586a6a4e089c9fa/cffi-2.1.1-cp315-cp315-win32.whl", hash = "sha256:4f42141fc14250de6dde5ee7ea4432be017252d91f19c5ad043c084cea629cac", size = 177683, upload-time = "2026-08-03T21:21:14.901Z" }, { url = "https://files.pythonhosted.org/packages/e0/31/5158704cc474ab65c1647932e88be78dc0873f47130e253be38bcaf13d01/cffi-2.1.1-cp315-cp315-win_amd64.whl", hash = "sha256:e6e8cff14d6fb0be70a09c0bdc58096f501952d04624ebf867e0e56da2df8960", size = 187897, upload-time = "2026-08-03T21:21:16.108Z" }, { url = "https://files.pythonhosted.org/packages/cc/4b/b3a2da8570c704ffc0f9762cdc3ec0f02c8573798e0b5cf7f11c82bbb70f/cffi-2.1.1-cp315-cp315-win_arm64.whl", hash = "sha256:27350daa11d4f10c540e6e89dada4c54feb7256ad03e9a4dc075ebad7ba360d1", size = 182935, upload-time = "2026-08-03T21:21:17.271Z" }, + { url = "https://files.pythonhosted.org/packages/d0/ef/5443574510a1207e6f6bc38ba6e1f1de36cb48fef07b2728bb896a21f430/cffi-2.1.1-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:c26608d2222fb1e94487e4a387d85f13eb55d5ed725cb25a0c589ac4ee60e7bc", size = 188464, upload-time = "2026-08-03T21:21:01.163Z" }, + { url = "https://files.pythonhosted.org/packages/7e/ae/a56fa8c4686ad50e148fcbc8d3ae0d03915ff5c30d795058988c24118cef/cffi-2.1.1-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:4be96343e422f2dfcd12ab5c9f5aebe03f82f737c6bffeca6830b3875cb44aab", size = 188262, upload-time = "2026-08-03T21:21:02.382Z" }, + { url = "https://files.pythonhosted.org/packages/53/b2/6187f46f2912276a3ae284076109cc5c8680482f11f766ccf26db4a86427/cffi-2.1.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:937c0052c05a31ca1daf18de3158eed4dbfcb9cc107adbea227728d647be701e", size = 223779, upload-time = "2026-08-03T21:21:03.553Z" }, + { url = "https://files.pythonhosted.org/packages/8a/f6/c3ad28bd19f77047a03084424fbd4cbe997303267c14423737324be0385d/cffi-2.1.1-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:df423d40ee8654634421812bc3b196da3f9bd7d32929da813f8394c4348a5358", size = 211520, upload-time = "2026-08-03T21:21:04.863Z" }, + { url = "https://files.pythonhosted.org/packages/a0/cd/ccac9013a5bd9fd764de118674ab9c805b5ca10c19270d90ee273f8b2240/cffi-2.1.1-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:a730a083190634c65cca36ba5f489531576ebd79bcd5c8e172130f6453127231", size = 210673, upload-time = "2026-08-03T21:21:06.223Z" }, + { url = "https://files.pythonhosted.org/packages/52/86/2976131c639aead931c5bee5aba67e4b09fbeb8018b6f282f70803f923a7/cffi-2.1.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:363e05fa78e15116c3c32c210ee36884fd6b9afa6d440e47112c3bd511d64cb6", size = 223835, upload-time = "2026-08-03T21:21:07.539Z" }, + { url = "https://files.pythonhosted.org/packages/ac/0c/33a7aeab2f9c76918c52e084beb39c570db3588133412929e8ec06fab90b/cffi-2.1.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:770de9db11e84213beec501cfcaa013b019820ca881e03344dea5844f7876d94", size = 226705, upload-time = "2026-08-03T21:21:08.774Z" }, + { url = "https://files.pythonhosted.org/packages/e3/26/2cde30fdde421130bfc18f70395731a6e6b2053c6a1978a5258ff04e72fa/cffi-2.1.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:7da0c5eff80f0197f3b3d1232ec5a682a9325f4ae9016a78f5f5ca35f9ced1f5", size = 225539, upload-time = "2026-08-03T21:21:09.911Z" }, { url = "https://files.pythonhosted.org/packages/6d/cd/a361394c94b2129d604bb846f624a8e88255a3ee33129c434a00d715e64f/cffi-2.1.1-cp315-cp315t-win32.whl", hash = "sha256:06c72bb76605a4b0cd0aad6930b69d4baf7dd5d806cfc409b824191099700e66", size = 182707, upload-time = "2026-08-03T21:21:11.226Z" }, { url = "https://files.pythonhosted.org/packages/9b/b5/ba2b299993c26577d529b6ae29841f9e15b9fcf004d65f423f4fcf94ade9/cffi-2.1.1-cp315-cp315t-win_amd64.whl", hash = "sha256:d9c275eaacd24aa73f94ffd6de08fc3f932424d8b6c376f4bed7cde376fe7bc3", size = 193772, upload-time = "2026-08-03T21:21:12.39Z" }, { url = "https://files.pythonhosted.org/packages/aa/29/35e016098c814cd93de9cd320c66b5bfba14dc6ecedd3cb518fa7c408c69/cffi-2.1.1-cp315-cp315t-win_arm64.whl", hash = "sha256:d18e5ac0f2f03f4f518d3e23db0f0cad7faa1da8620e9c09461d443bbf6e6692", size = 186360, upload-time = "2026-08-03T21:21:13.636Z" }, ] +[[package]] +name = "charset-normalizer" +version = "3.5.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/33/1c/f41d4e74c28ab327ff3acd36053f7ea506c55872d7a90b0fa71aa3ab0c89/charset_normalizer-3.5.2.tar.gz", hash = "sha256:39de2a259fc954455c57274dc94c79d5842774e1247a016aff30bc0efed0f4ef", size = 172659, upload-time = "2026-09-30T04:39:23.398Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/98/77/46e87bcfc45d25ab4db7cfc9bb544bfa3ffd302289ed31ae93f5433eb899/charset_normalizer-3.5.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:195c26fb65950f8fce54e26349852b7bdd7c5f120aeefbcc440b8a20faaed4a3", size = 373348, upload-time = "2026-09-30T04:34:42.843Z" }, + { url = "https://files.pythonhosted.org/packages/52/fc/e518013affcc43c9f919c3ba41bffe9b4ee4aceb0a6462a6243efcca5f2d/charset_normalizer-3.5.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9373ad13ef0d2c0fb761e04e55bfdee5a08b52cef2c882c8fbe9935b1517152e", size = 260860, upload-time = "2026-09-30T04:34:44.817Z" }, + { url = "https://files.pythonhosted.org/packages/d5/ad/2a895c945ee61988dfd9ccee64f0b78dc09f29c9b34d1dd545246d78e0ad/charset_normalizer-3.5.2-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ddf19c062bea7a0cc80f519243d2c01dd091be0cf952a0750d4ad576709559f5", size = 246491, upload-time = "2026-09-30T04:34:46.227Z" }, + { url = "https://files.pythonhosted.org/packages/c9/05/5d958bc8ea503e26be25ada5430fd409cfb45dc22ff33f9f96e649613c99/charset_normalizer-3.5.2-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3d14b50de6bf4d0edf857a9386836846f982b8f524e188e2e68b96d702bcf4aa", size = 290875, upload-time = "2026-09-30T04:34:47.691Z" }, + { url = "https://files.pythonhosted.org/packages/55/e2/06bad57dfdb49cad92c0ba85b6b4fa5827a67df37897287cfef0553843c2/charset_normalizer-3.5.2-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:28a15fdad492a99b6eccfaaed66ef3f74050680545ea61ec8b2f4c538f1f1320", size = 286987, upload-time = "2026-09-30T04:34:49.356Z" }, + { url = "https://files.pythonhosted.org/packages/c4/9f/9f52d2886d52645987d603425482c63c5045a3005db1354a7097e5ed1ae9/charset_normalizer-3.5.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8a893cc101149f80a653f82062ebc95b34525a2614382e1da5458fe7c6997249", size = 271105, upload-time = "2026-09-30T04:34:50.957Z" }, + { url = "https://files.pythonhosted.org/packages/4a/41/e05e19578b7b87e7db2c3ecb884bd09d065274ab41e1f535542e8bae9b06/charset_normalizer-3.5.2-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:619799369eeef6366ed3e8755a5670f4f2f0fb6b30a0fd7264dc0fdc2357058e", size = 269833, upload-time = "2026-09-30T04:34:52.623Z" }, + { url = "https://files.pythonhosted.org/packages/c2/cd/fc7152414561ff78f9c61a4a627025f65fd244abaefc99ac4e75c6169b33/charset_normalizer-3.5.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:447441e76ec720b15e64418d32e092297340387053047c7c694f579efb0ee1d9", size = 263048, upload-time = "2026-09-30T04:34:54.013Z" }, + { url = "https://files.pythonhosted.org/packages/71/71/fb379e399b1013962716a059d551e03bd80b3e02f05d81246886af6c0958/charset_normalizer-3.5.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:62588a277bfb59def052abd940703fa35107152bf479781a878617d60faf8fb5", size = 249237, upload-time = "2026-09-30T04:34:55.373Z" }, + { url = "https://files.pythonhosted.org/packages/33/4f/aeadccd6d20882909eb2597ec40eccc05d505e2262f14dc76d7620700657/charset_normalizer-3.5.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:44bd4fbb29dfbeba60e7d2bd000c59e4b21ddb3cc53912b14048d37092706d7c", size = 290756, upload-time = "2026-09-30T04:34:56.867Z" }, + { url = "https://files.pythonhosted.org/packages/b9/7b/e8a92613236b257d3b75d532496eb21f68ad8231d7d56df94497e460112e/charset_normalizer-3.5.2-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:30fcd120b732aa79317f08dee04d7de0847822e4cf7ee0e9f445bb958832252c", size = 269026, upload-time = "2026-09-30T04:34:58.278Z" }, + { url = "https://files.pythonhosted.org/packages/ff/ac/21d5c6b972285c5f095ff78afdc99f3539e3985dfcf7ff1cfbe9e772f529/charset_normalizer-3.5.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:50e3adfb96fc189eb27b1cf62d3b598b89b4bb0420d93a3d3e42e137409011be", size = 287601, upload-time = "2026-09-30T04:34:59.703Z" }, + { url = "https://files.pythonhosted.org/packages/59/72/263491ec1494a194b16fcbff88a0220f2af633738c79e92b4d7189226322/charset_normalizer-3.5.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b736353c0a625bbd5fcec108576e2385db3496f4f771f785ff32e108d3c3bc45", size = 272660, upload-time = "2026-09-30T04:35:01.26Z" }, + { url = "https://files.pythonhosted.org/packages/38/7a/81f1186c57e406233969ae96b5fd0c907254ab8b6e47da8ae24cd20fb9d7/charset_normalizer-3.5.2-cp310-cp310-win32.whl", hash = "sha256:f5833ad231be5eb6553de524a70f48d71b2c8563101750531e0b80184e175cd4", size = 187301, upload-time = "2026-09-30T04:35:02.659Z" }, + { url = "https://files.pythonhosted.org/packages/ae/ab/fb8b5178fdf7bf68efa61cbe892286bc9f73846f26147d4725fb89388475/charset_normalizer-3.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:1461ac396c4fdb983a675f20aa555624f0ee18ac83d832b9244ffff3d8055275", size = 215446, upload-time = "2026-09-30T04:35:04.011Z" }, + { url = "https://files.pythonhosted.org/packages/36/40/e270b74e0d3f583d78d902960845a149e80eb7c737ee5613ccc6efc7264b/charset_normalizer-3.5.2-cp310-cp310-win_arm64.whl", hash = "sha256:c6708715abcf3c73b99508253e961a9967f02fe536532834149574eda6de0d1c", size = 203389, upload-time = "2026-09-30T04:35:05.577Z" }, + { url = "https://files.pythonhosted.org/packages/22/67/6a0b94a7960d5e1b5eacd2fb529f3fccc47db4644f7f0a7cfdcfc3be578a/charset_normalizer-3.5.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3d21b8b13c7592db2ac5e544a6d83187b995257472b0c9e8351b6d507ae37ed6", size = 370642, upload-time = "2026-09-30T04:35:06.91Z" }, + { url = "https://files.pythonhosted.org/packages/fb/94/01009e13b94041599004edf32e56e382c24e570f60f79bab8efe45cfe1eb/charset_normalizer-3.5.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d760fe2a4d7c3b226cb9026d6a842868d52a7901bd98420e1baf14e80da85cf5", size = 259280, upload-time = "2026-09-30T04:35:08.448Z" }, + { url = "https://files.pythonhosted.org/packages/66/85/3b5358f60a13210f0b67d3755c168ef758701b021e655d88d4da28554467/charset_normalizer-3.5.2-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c9790464842f85f437dbbb54417eda1e0e6bfc52dd8d22d6fd1c994b73b2dc74", size = 245335, upload-time = "2026-09-30T04:35:10.104Z" }, + { url = "https://files.pythonhosted.org/packages/74/75/77c1c479b09ecd751d1e767b251ea5c14d4d50ff757bf404afab2692f600/charset_normalizer-3.5.2-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4685902cf26edf013ed7a3da0f426ebba7a00ebb9541386d835afbf002c11cab", size = 291707, upload-time = "2026-09-30T04:35:11.575Z" }, + { url = "https://files.pythonhosted.org/packages/0b/0d/363f78cacb70f58f15f4b083961bbd9d292f335d3f5c66fc4f1cfe69cb90/charset_normalizer-3.5.2-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4495c5002a7b28557e7e222e77e0b661183e432b7d6d2e788101e3f240e05b8c", size = 286747, upload-time = "2026-09-30T04:35:13.022Z" }, + { url = "https://files.pythonhosted.org/packages/e4/ed/cf505d3011ffceb12c2067a7a5d3cfe92b875d4d44bb0ff0d69375e2c184/charset_normalizer-3.5.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:211d5a3eb6af8f513b8d4ca19a8c1b7accab1b5f0d3175f9826b03c1a920dc1f", size = 269972, upload-time = "2026-09-30T04:35:14.606Z" }, + { url = "https://files.pythonhosted.org/packages/15/d8/f0a93a431d170e7ca681d4f6650fee3de934d18560e474e7267eb4b0f987/charset_normalizer-3.5.2-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ef4fcbf3327382cd4c9f540babd61248208af7b93eec4de397b4d5f58a09e288", size = 269339, upload-time = "2026-09-30T04:35:16.087Z" }, + { url = "https://files.pythonhosted.org/packages/86/bd/9b2bd1c5b7af02462c9752d33994834ff972a96b4c483eefde9e594488e2/charset_normalizer-3.5.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bd16aabe4a02a297c23417aa17ac6299dbd8c49f673bcd645b4929b11f5a4400", size = 261683, upload-time = "2026-09-30T04:35:17.488Z" }, + { url = "https://files.pythonhosted.org/packages/76/a5/cac540ab0fd61f3fec88ad3dbb64509e71424593d73cfdfff5ab3e4db279/charset_normalizer-3.5.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:fb9e68df06293761f9fe66ade60a9bc6d0f5e42b8acf2939a9158af86ab0e5bd", size = 248143, upload-time = "2026-09-30T04:35:18.849Z" }, + { url = "https://files.pythonhosted.org/packages/71/7a/ff467301deef2089fad87f72df9e000a26a78fec7acbb18e1999371b8369/charset_normalizer-3.5.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:59f63901b0031c3136cf64704dcb21de0bbae62ce2c9529bc39d27665463de37", size = 292358, upload-time = "2026-09-30T04:35:20.326Z" }, + { url = "https://files.pythonhosted.org/packages/ad/77/22d7e785d1e210afc2e2f58600dd1799d17a35665faf84383f002826c5f8/charset_normalizer-3.5.2-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:304d5463e65a35d7bb0850550e0780395395f6fcf452f04db7d5ca7cecc425ac", size = 268766, upload-time = "2026-09-30T04:35:21.72Z" }, + { url = "https://files.pythonhosted.org/packages/ae/91/e8e946267f1c2d9e2bd651726e2fbd2addf02c4d36cea5069e32ca9d7bb5/charset_normalizer-3.5.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:9cf9b1a857e25c4baceeb3624e92a56df3668f398c4acba74e174d81fb4d1d3a", size = 287432, upload-time = "2026-09-30T04:35:23.273Z" }, + { url = "https://files.pythonhosted.org/packages/4e/88/7561d8a88d555e7df6623abe7c0070b4baf47549b9408783a2ae0a1a6cf7/charset_normalizer-3.5.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:114e4d0c92d618409ed82a99e22b5c5e768fe995f2973f78265f4524f49d4640", size = 272470, upload-time = "2026-09-30T04:35:24.655Z" }, + { url = "https://files.pythonhosted.org/packages/35/7e/578c702301ec036f01455f30744a08d2b42f6ab35b9b2d4bf8cae0ef2a80/charset_normalizer-3.5.2-cp311-cp311-win32.whl", hash = "sha256:2625388c6c754520c37abaf3b41eb34d1cc4a373f457898f08606c8e362b891d", size = 186688, upload-time = "2026-09-30T04:35:26.225Z" }, + { url = "https://files.pythonhosted.org/packages/e8/fc/fdf8cf52ff21cd5bf158f20978991cf985325842f74283eb6df26c8a39d8/charset_normalizer-3.5.2-cp311-cp311-win_amd64.whl", hash = "sha256:87e50a3e7cb90af586b6c5faf23e302a970415ac73bd7bd90a515a04b427ef96", size = 214932, upload-time = "2026-09-30T04:35:27.796Z" }, + { url = "https://files.pythonhosted.org/packages/97/66/3e45a506d8110b632541faf9a9470185aa9878f1ed44020f31346c1c5e5b/charset_normalizer-3.5.2-cp311-cp311-win_arm64.whl", hash = "sha256:254eb48b9fa5ee9898a3c445825a1f340fe53712a098904b39b0bddba8ea3cb1", size = 202828, upload-time = "2026-09-30T04:35:29.259Z" }, + { url = "https://files.pythonhosted.org/packages/e7/c8/693809898870237d82785a03f3b2b58fe4c9f14669f84a7d4e623c92a59e/charset_normalizer-3.5.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ed2a239c0ea213acc1908150a3037257083c7c083128f1a4cec2ec4b97dca491", size = 367780, upload-time = "2026-09-30T04:35:30.888Z" }, + { url = "https://files.pythonhosted.org/packages/c9/87/2fea8c13dc24b3ca9c6f803a5b2dfdeae73eb4f9e12c7885ed908ff0433c/charset_normalizer-3.5.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b91363207bd9dc966a691e959bb47f64b30f7ac4b072be9968b366982f7db77c", size = 246730, upload-time = "2026-09-30T04:35:32.286Z" }, + { url = "https://files.pythonhosted.org/packages/a8/9e/09efac30b937722f46d3110ba30b875b24b2e3a266ed746cc4e376a94d80/charset_normalizer-3.5.2-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:38a873987f3be698494da8b2e3085e29da02da7b633dce73e79c699a113d7bf0", size = 237707, upload-time = "2026-09-30T04:35:33.709Z" }, + { url = "https://files.pythonhosted.org/packages/9e/18/70d76670b13686237863a379928d60bd10e021f17d243ab3d7014c4a5f4e/charset_normalizer-3.5.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:355ad8011081dec5412240c087a9a0c9d4d5039f3ed11a3f13e18c2b29b56c51", size = 273050, upload-time = "2026-09-30T04:35:35.138Z" }, + { url = "https://files.pythonhosted.org/packages/54/e2/77a8b09d5adc013ed07b95b01b8b8fa5441c4e810e83ee7e4aae2fa4d91a/charset_normalizer-3.5.2-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ee21e28f0430bd6dc9086c6e525d5e818a44a5ad19720c8a0ef766792f3eb5e5", size = 270345, upload-time = "2026-09-30T04:35:36.502Z" }, + { url = "https://files.pythonhosted.org/packages/7f/c5/38806a25ab5e65fc178f39affeda20858efafede2fce1ffc2556cfc9fe73/charset_normalizer-3.5.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3d31298449090ab8d47b7b1b2a555ff73cac7ed438a08b7ac160980c7ebed649", size = 257601, upload-time = "2026-09-30T04:35:37.919Z" }, + { url = "https://files.pythonhosted.org/packages/ae/8d/213565184708fdb263ae55e2c04ee1ff748129dd65d48ed0e3502da9c85a/charset_normalizer-3.5.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5cde776b7cc66e4f6c99612cea4aa7269aa65863f7a15841b2c264f103822f4e", size = 252222, upload-time = "2026-09-30T04:35:39.544Z" }, + { url = "https://files.pythonhosted.org/packages/7e/24/76d2cefc25472531e4c5c7dfff68865eb1c39b78482f0fdc15b46f047830/charset_normalizer-3.5.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ae4f5fea5b8b8ccff88238cc8569303e5ee95efae67fa62922a311397a71f346", size = 248482, upload-time = "2026-09-30T04:35:41.088Z" }, + { url = "https://files.pythonhosted.org/packages/7d/dc/65a801b66ab4c197e22c433ab25e7ac24324ac6f45a2269aca42cce309bf/charset_normalizer-3.5.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:f7d486c83842422badd511868fd8a9a20e9407ace71564b6af47ce7e60a336c1", size = 241206, upload-time = "2026-09-30T04:35:42.59Z" }, + { url = "https://files.pythonhosted.org/packages/a7/95/ca9b5eabde673002c6f1e7ada1b223916fe18f6d661da7aabd4d643718f1/charset_normalizer-3.5.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:11a4d68a6ecda3292cb1e50239e111543ba5d709bb62a6b4ea1afcfa729d8875", size = 273190, upload-time = "2026-09-30T04:35:44.347Z" }, + { url = "https://files.pythonhosted.org/packages/2d/8b/803b4d2a3f6e1740f63f1e87b04d14b42f3d4fdfe6ed7d4db2d34102b14f/charset_normalizer-3.5.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d6734d2ef8a50fbf8445c139477da401f50d62a0606bf00e20ec6d87773fefb1", size = 253527, upload-time = "2026-09-30T04:35:45.915Z" }, + { url = "https://files.pythonhosted.org/packages/a9/55/93c0e5dbd085ae0471346026abbe7e0db9ea2d6fea74e51f0b5a46f233a7/charset_normalizer-3.5.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a815775b6c38d4e0ff7bcffbeba67feded90202bb6a226b8dd35f1c855217413", size = 271285, upload-time = "2026-09-30T04:35:47.49Z" }, + { url = "https://files.pythonhosted.org/packages/95/69/0dbd0e0b9b16cfa816cdfcb3e2e3854a1f680dc07fb1245ea125e7448060/charset_normalizer-3.5.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:23851fb4e1b85ed3f6c2a27b777cdfe2e19fb5b38429a8faf38c7542b7665869", size = 260010, upload-time = "2026-09-30T04:35:48.996Z" }, + { url = "https://files.pythonhosted.org/packages/58/9d/e7b88e7b1bf403590c3b573277b5e1e488c68c7a6fbacca310a2c324e90c/charset_normalizer-3.5.2-cp312-cp312-win32.whl", hash = "sha256:db19d07e2e0129e974a0e65d0064fc222a446cd5122c2fd4184d2af9fc734a9e", size = 184125, upload-time = "2026-09-30T04:35:50.777Z" }, + { url = "https://files.pythonhosted.org/packages/eb/e6/e6e083884cbcfd49c64865af05027fe7011be7b2d9179524f099a1b611f3/charset_normalizer-3.5.2-cp312-cp312-win_amd64.whl", hash = "sha256:780fbe7cab297b81dad9fb8dc5eb003c0468ffb0d9e5f65068c53a34661a96bc", size = 207486, upload-time = "2026-09-30T04:35:52.194Z" }, + { url = "https://files.pythonhosted.org/packages/c4/e3/017aea0911ada7405a825c7d937eb3a13009664e2f5b38e8c4bbf2abf894/charset_normalizer-3.5.2-cp312-cp312-win_arm64.whl", hash = "sha256:e2af3aad578aa6bd1384bcf4750fc285e5a9de53f40b7d41e5a0bf748edeb2b3", size = 196734, upload-time = "2026-09-30T04:35:53.636Z" }, + { url = "https://files.pythonhosted.org/packages/c5/34/68292d68512768591aaff07c59bb53ee31341c87759433a859c4641a50c2/charset_normalizer-3.5.2-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:ed905975ab14056a2e5eb1c376cb2e1ebc5396baf84163939c518556fccde9f5", size = 225946, upload-time = "2026-09-30T04:35:55.313Z" }, + { url = "https://files.pythonhosted.org/packages/e3/80/bee0b01b90ccd5322ae1d0abb33fab1bd95b7c2eadaf02aeccf22e04ee83/charset_normalizer-3.5.2-cp313-cp313-android_24_x86_64.whl", hash = "sha256:a66c3bc5ab1f0ff2164fc9965ddd611ff0802173f4b9d24554c563f6ab7e1d6e", size = 238619, upload-time = "2026-09-30T04:35:56.863Z" }, + { url = "https://files.pythonhosted.org/packages/78/6e/60ce52a85a7fd631ae8482ae6d74521014ca2f255892679484dc04d7ef56/charset_normalizer-3.5.2-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:d2374b62878abb00cd8309b32af6c0b715cd02dec0ca74ef12e5069bdc64144a", size = 206701, upload-time = "2026-09-30T04:35:58.639Z" }, + { url = "https://files.pythonhosted.org/packages/36/8c/71aafad23f971afc84c2b295bc0c560739ce1dac558aad9fec22e39f3639/charset_normalizer-3.5.2-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:d376bbd28b3a8999db1a103b3b388aee6f1ddeb3e51bc2172993efdcd86e064d", size = 210506, upload-time = "2026-09-30T04:36:00.147Z" }, + { url = "https://files.pythonhosted.org/packages/91/da/3c5a7798c046df7d2d68ad653cf5b6c5a8bfee225055a843c6f2f42aac1a/charset_normalizer-3.5.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6045373d5a89a5ec71afde535db987ca28e76dfa276c2d4c818265b375d4b055", size = 366626, upload-time = "2026-09-30T04:36:01.77Z" }, + { url = "https://files.pythonhosted.org/packages/e1/16/710ac3de2ee354e2bd1a9c94efe45a2d27b5c6ad39b2d6a905be2c094b6c/charset_normalizer-3.5.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:849df64e889b2e17230d58410a03dba311a65b163508fd33679b2b737d4b7858", size = 244624, upload-time = "2026-09-30T04:36:03.389Z" }, + { url = "https://files.pythonhosted.org/packages/d6/39/45c7439f5b63d24f7d5b2a1d760f34af7628782d7144b4cc8ded45c2d4bc/charset_normalizer-3.5.2-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:15c44f7edfd477b06f517a5cc317fc1707edb9de2c865f43d4b6513907473234", size = 235731, upload-time = "2026-09-30T04:36:04.987Z" }, + { url = "https://files.pythonhosted.org/packages/4d/34/38f3154785ce92e9f56eb226f4d35bdfae6b008480dd055f58837a89c810/charset_normalizer-3.5.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a89012d6d5476ee112d20d998570ed58df2260a852afb1758809cd6900411d21", size = 270352, upload-time = "2026-09-30T04:36:06.412Z" }, + { url = "https://files.pythonhosted.org/packages/04/f3/859f74e7babc977705026b30593b3be04049632a522fb7000f83c033d747/charset_normalizer-3.5.2-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0c951d5e6dd9c2ff60609476752bee49da4206adde960ebc247766937f72e718", size = 267393, upload-time = "2026-09-30T04:36:07.865Z" }, + { url = "https://files.pythonhosted.org/packages/4b/85/41d27f234b82e47c167a5f6c0f62501dc0c640585ff4aba79e08a390336a/charset_normalizer-3.5.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7218e8f32b0956cfcd048fd42d9d5779809745ca1d86113ca56f66e7ae1549c4", size = 254660, upload-time = "2026-09-30T04:36:09.248Z" }, + { url = "https://files.pythonhosted.org/packages/58/ca/5d1a997587febe5b26d8daffe363b5c1a091cece19828eec6502fd09c5ef/charset_normalizer-3.5.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a19a731138fc27d5682277d3b9df22855cea1239bce7fcec5f78f42ef2d1f3c3", size = 249996, upload-time = "2026-09-30T04:36:10.73Z" }, + { url = "https://files.pythonhosted.org/packages/b3/1f/d1e78246f7ed60c8c8d606b4ac27f66ce49cc3e95f24893ccbeba9f77302/charset_normalizer-3.5.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:62603db9a7caa0802eaa28c1c46fecd7b3a263a774069c24c3c28c302448721c", size = 247028, upload-time = "2026-09-30T04:36:12.294Z" }, + { url = "https://files.pythonhosted.org/packages/8e/37/eba316edd4f0c4d3a5d945924c4eeeae59abac4056aa815d8a4268f863a2/charset_normalizer-3.5.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:b6856554c4f44d79fc2307d5768854310a8f0096e501c75637542c82292b0429", size = 240562, upload-time = "2026-09-30T04:36:13.887Z" }, + { url = "https://files.pythonhosted.org/packages/c8/8e/aaa037d40ca9ef045977f1a661048b1aa33f223adfce3452fe9be9f79d14/charset_normalizer-3.5.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1bc0baf5ef96b6ede57d47f4b8fe4d9d84019c3bfcbeb20a41edc6a6ee341f1f", size = 271699, upload-time = "2026-09-30T04:36:15.41Z" }, + { url = "https://files.pythonhosted.org/packages/26/19/1c1c9f75974adf523b87f34b8a2adc5a435cd65916812bcbd0dfa45f9a29/charset_normalizer-3.5.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:56bc200a365efb37383b7852e4cc5898d3b2da5987289b543956cf8cad71018a", size = 252030, upload-time = "2026-09-30T04:36:16.839Z" }, + { url = "https://files.pythonhosted.org/packages/bc/90/0660ef18e18df0a4d2a1a0edff7dfbba42d4e50ef2425557a5bb7051f77b/charset_normalizer-3.5.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:2c9ad19a6cfcd5ea5c0d41161d22f9df1dcc277e9bef2751391334546a314c00", size = 268565, upload-time = "2026-09-30T04:36:18.468Z" }, + { url = "https://files.pythonhosted.org/packages/79/ba/57adc269824e8658f1a0f97a9e514c247445a9632b3419b97e0ba37f16dc/charset_normalizer-3.5.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e243bd13217235fc7290c621941c3f5cc8b66e4872495be821d7436ba2fb838d", size = 257627, upload-time = "2026-09-30T04:36:19.938Z" }, + { url = "https://files.pythonhosted.org/packages/9a/85/33abd4315c052d3d4f54c92b1ee49bfbc0dc7115a981e462a793b6d2ab87/charset_normalizer-3.5.2-cp313-cp313-pyemscripten_2025_0_wasm32.whl", hash = "sha256:a090bb2c68df85450502e3e20d665e3a5af9c65a84d6508ed477badd49166fd3", size = 143407, upload-time = "2026-09-30T04:36:21.376Z" }, + { url = "https://files.pythonhosted.org/packages/4f/de/6435e18d1aaa5d910b896d551411c96af1f42a0c56c29afc2016c61ccc2e/charset_normalizer-3.5.2-cp313-cp313-win32.whl", hash = "sha256:2b7b3bbfb4fe8ef40600792d762fbaa9057559f9d3fad209525b7a22b99e91fd", size = 183207, upload-time = "2026-09-30T04:36:22.776Z" }, + { url = "https://files.pythonhosted.org/packages/9c/76/b8ec57f4e9ee3253541abf95e4a462c0175fe8032dcd070f1f2421240942/charset_normalizer-3.5.2-cp313-cp313-win_amd64.whl", hash = "sha256:78456a747de8dc58360ffa581f30a002baf5aa28cb262536545e91f113ed7639", size = 206489, upload-time = "2026-09-30T04:36:24.306Z" }, + { url = "https://files.pythonhosted.org/packages/3e/60/c647c6ae47480221e875ea5d743ff94946f7416e3c69415ab772928e8d32/charset_normalizer-3.5.2-cp313-cp313-win_arm64.whl", hash = "sha256:11912e4bb14baae7c5d8791aa55ba0a3a03ec6729073307b0f57270abaa713d3", size = 195501, upload-time = "2026-09-30T04:36:25.846Z" }, + { url = "https://files.pythonhosted.org/packages/58/ca/7aa91362a2f77ac8e9e28a9b902a74f7d0e11a851ef0d27a74308da8cd90/charset_normalizer-3.5.2-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:1afb975bd5d68d5ce9f6b6d44fdf2f7e34b895a35e95708a7a91b20a3b51d187", size = 226010, upload-time = "2026-09-30T04:36:27.669Z" }, + { url = "https://files.pythonhosted.org/packages/a8/cf/ac8878d0322cf88a1aad4c7b147db32ca0bd806eb0060957b2e31486dbe6/charset_normalizer-3.5.2-cp314-cp314-android_24_x86_64.whl", hash = "sha256:bbbfc8e28816f19d7c0f1816664980c0a9875d01b27cdf8eedddb639d9e108ad", size = 239266, upload-time = "2026-09-30T04:36:29.434Z" }, + { url = "https://files.pythonhosted.org/packages/c9/6d/9a08d7e0b29b7208e2c6c01dc56c8e0520e7c7beadbbfb024b58fd69c8a5/charset_normalizer-3.5.2-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:7967d08cf06dee78443b874f98c98036f624f3a4e73e11f9f64f5be4d25393cf", size = 206783, upload-time = "2026-09-30T04:36:30.872Z" }, + { url = "https://files.pythonhosted.org/packages/82/44/b0aa350280e6ff5a5492d17cf10460dd39d5ee848f872f7ba2df10607f60/charset_normalizer-3.5.2-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:4c2b5031f63e331e3839b40aed2dd6f191e9c07edbde303e7876846ea1946995", size = 210449, upload-time = "2026-09-30T04:36:32.625Z" }, + { url = "https://files.pythonhosted.org/packages/7c/8a/40db9aa9f5907bb0e6f8b6d64064bf8852fb33d4b813ff9414911df7647c/charset_normalizer-3.5.2-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:fcff63213e8e6e47770541a4607175404f47cbb3ebea7b6058cc82d524a0e424", size = 367815, upload-time = "2026-09-30T04:36:34.197Z" }, + { url = "https://files.pythonhosted.org/packages/7f/72/9c5e7707b57c8ddfa9ddf7b0b1d009d7fbab9e9e887d5b721060f37e307d/charset_normalizer-3.5.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8d86d6fc60743dc916eb79e2eb1ec4818e21e427731543af40a3021851174a13", size = 247095, upload-time = "2026-09-30T04:36:35.803Z" }, + { url = "https://files.pythonhosted.org/packages/83/09/71e453691e927de4ddf792770cfaab3f49d494e222f66ea5e404bbd5e39c/charset_normalizer-3.5.2-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7a881931aa470808df94a8c380eed2bbbc76cd9dc622310f99665658c821eb6d", size = 233942, upload-time = "2026-09-30T04:36:37.407Z" }, + { url = "https://files.pythonhosted.org/packages/9f/86/85c84e4da8b27dd409577d9437926ff581c5f9d3c66038dc68c1a526de51/charset_normalizer-3.5.2-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8024d00c3faf3fc0c16e07a69f4405e8eac7cc0ab15f65fe6cf43827c4cf72b4", size = 273762, upload-time = "2026-09-30T04:36:38.904Z" }, + { url = "https://files.pythonhosted.org/packages/92/08/564955a4b5f2ccb410ab480bbe8c6a18063ff27f2d35458731c4a5335df9/charset_normalizer-3.5.2-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4d48f2d08b9de5864e2c8744d4461b862fb149a18274abc8b698c45975573438", size = 269514, upload-time = "2026-09-30T04:36:40.469Z" }, + { url = "https://files.pythonhosted.org/packages/18/24/bad3ac4271589df29cf5ce2f5ae490518a5739358052bd0d61209e6fea54/charset_normalizer-3.5.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34276fd796040bf0993ab33a369aa572e6979c7aab225a88893667ad8eac8f7a", size = 255056, upload-time = "2026-09-30T04:36:42.02Z" }, + { url = "https://files.pythonhosted.org/packages/d6/3e/350d89ad49916b86554d6f5f2d03ec1152148f87e5ff735106c6a03b1a36/charset_normalizer-3.5.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0521c5665880b33d603717defa76c094048900010897909952397feb3039da56", size = 251311, upload-time = "2026-09-30T04:36:43.577Z" }, + { url = "https://files.pythonhosted.org/packages/56/5b/4970a2d154df502e133402906dd04e3ae7cada7b3011283c88d0479a2585/charset_normalizer-3.5.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:eff0ac9dbe711a4aee69bf04a83896aa9b85f19641264053a9f6d48573abb7dd", size = 250190, upload-time = "2026-09-30T04:36:45.185Z" }, + { url = "https://files.pythonhosted.org/packages/88/8c/f1a91bddc8fb47c2889e29ea7ea49a194eb0d9868675d786806519c00d76/charset_normalizer-3.5.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:1503bccbeb36d5527790c3930327704c39af22de3112f1b1666a9f3ce15ee204", size = 237098, upload-time = "2026-09-30T04:36:46.689Z" }, + { url = "https://files.pythonhosted.org/packages/24/0e/bb5dace3cc7e79068425386a6589c19b5a2ab5fefc2a46abea6919683332/charset_normalizer-3.5.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:52aa6992700996af31f375de0c6bacd402b0097fe40b53c426b9f51a90ebabc7", size = 274228, upload-time = "2026-09-30T04:36:48.31Z" }, + { url = "https://files.pythonhosted.org/packages/9d/79/b849ad523017ea9f5a45581bbebed91439e0cf42fd2860a6f64e358eb5a6/charset_normalizer-3.5.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e09a3942ecbdee5cce73ea9d42da82b81b72ac1bf031ce069b93b5adf4eac8cd", size = 252401, upload-time = "2026-09-30T04:36:50.091Z" }, + { url = "https://files.pythonhosted.org/packages/89/8c/75469d690cf47200bce8f6cad7655724fc23148e147abfc5ce78b5f65863/charset_normalizer-3.5.2-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:c7c9ab723cde841fefb34efbad91e87f00a674b1fe1cd0784fde742bf2c154dc", size = 271846, upload-time = "2026-09-30T04:36:51.719Z" }, + { url = "https://files.pythonhosted.org/packages/26/cd/6d52d3c7437cdcf2e310ce9f28f282e733d4ef60ed19105d1819c356255f/charset_normalizer-3.5.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ddc7dacc8ece3a182e7f15cb862d1fd616b46d076cb1ae9dd232b2c38b655874", size = 258151, upload-time = "2026-09-30T04:36:53.234Z" }, + { url = "https://files.pythonhosted.org/packages/f7/4c/070b38bdb5f49a70199fce923ec0726a49536a63ab262abbfcaaf351110b/charset_normalizer-3.5.2-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:ee43c17b173d46a3212baa6ead3ae258eeabdae48c263a01ccf0218c366dd655", size = 143570, upload-time = "2026-09-30T04:36:54.816Z" }, + { url = "https://files.pythonhosted.org/packages/81/84/9ebfc8ed6c8c4fcd8e726ff6bf220cc8deb3966e31dce9be8dd8aa017e64/charset_normalizer-3.5.2-cp314-cp314-win32.whl", hash = "sha256:4f87960d57feabfb618e4e0af6e7371645fa26a277860739d6e5d6e0012c92f0", size = 186412, upload-time = "2026-09-30T04:36:56.643Z" }, + { url = "https://files.pythonhosted.org/packages/d1/78/5ed86f743d4bc350db307e7636419a0a5ee1d91806d30c7f667bd5c80dae/charset_normalizer-3.5.2-cp314-cp314-win_amd64.whl", hash = "sha256:e4e81e09c1578b8df602e3db08b0b3ea0a6947ad612f52bf8dc5ea8d47691f0c", size = 210965, upload-time = "2026-09-30T04:36:58.205Z" }, + { url = "https://files.pythonhosted.org/packages/53/94/a3a7698e9b1a395e1eb99ccd9a324be9347973bff4e72db2a06496d7cd27/charset_normalizer-3.5.2-cp314-cp314-win_arm64.whl", hash = "sha256:80d02b6f04e92601a081dd97b23d3128033098bff5d35d392ddcc0476ea11253", size = 200406, upload-time = "2026-09-30T04:36:59.764Z" }, + { url = "https://files.pythonhosted.org/packages/c1/48/c5dd00d5ef7791f02666de250a5bb6071e29b7e133cf4b835800b6d3bc27/charset_normalizer-3.5.2-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:dca9ab98072a5a54ebacebdc45f53e645336b320c667410b061be1ca588ae709", size = 396871, upload-time = "2026-09-30T04:37:01.543Z" }, + { url = "https://files.pythonhosted.org/packages/12/c8/8379554b42e8368161d898476686947a0fdbd3e8865170d7909dcabfdee8/charset_normalizer-3.5.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f0aa869112ef88429ae17820d99c3dd9504c9e9c671d3c246f3d7442cb051084", size = 249711, upload-time = "2026-09-30T04:37:03.111Z" }, + { url = "https://files.pythonhosted.org/packages/4a/eb/2ddb1035d17320caa9f41682935123a9a250277b261c3efc86b2d2a21343/charset_normalizer-3.5.2-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c0afc6800ba57ccc350374c5bd6150419915d95ce93cdbab2d783d75eaf30ecb", size = 231146, upload-time = "2026-09-30T04:37:04.721Z" }, + { url = "https://files.pythonhosted.org/packages/4a/24/2ecb4bde104322cd7859d6594fcfa74649f8d90b3221c9feecbef149875b/charset_normalizer-3.5.2-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7dcd882da75ef9adf94903b1e3b9419e8aa8fb4c7396822b834b9ef7fb96954f", size = 271552, upload-time = "2026-09-30T04:37:06.295Z" }, + { url = "https://files.pythonhosted.org/packages/3f/98/9d5f6ebc3aee9fef5d30b4aff11fb2ab7a1222b4064f8ef2c7c87cde217a/charset_normalizer-3.5.2-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2e06a3a98f916dd41d27f3105e02e7a40181c98c94b9158733d03a6f80506c09", size = 269810, upload-time = "2026-09-30T04:37:07.905Z" }, + { url = "https://files.pythonhosted.org/packages/09/e1/a3b06a10461b1b7628853c934c644e03bc28e42767116afb52f19a56519b/charset_normalizer-3.5.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6bd128f206a7752ae1f2ab6c61bf8a24ba28913a10df8b14c2637b973ff97a80", size = 259845, upload-time = "2026-09-30T04:37:09.554Z" }, + { url = "https://files.pythonhosted.org/packages/fd/d3/6f561f74a296cf27d61775a1dc665ad13f3bff6a798810ca05907f37a7c4/charset_normalizer-3.5.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c8f3d67aeaf55f017982b73683f0e7342ba2f6635a78f69ce89ebb26aa411e5c", size = 252825, upload-time = "2026-09-30T04:37:11.274Z" }, + { url = "https://files.pythonhosted.org/packages/26/9f/69e13ca3b18f43e0eafcd34c04a45b732ae22a43b54a5fc9e119103356eb/charset_normalizer-3.5.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:fe9753dfee015c570d73df76f899f18444d41388bffcde097deba51c4fadbb9f", size = 252659, upload-time = "2026-09-30T04:37:12.941Z" }, + { url = "https://files.pythonhosted.org/packages/73/a9/ace29806a0dae18939919c76ba526472d83214afa101105fabff2cf30625/charset_normalizer-3.5.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:92888bb3187c5ba50500b00b3b310c9f2c651709d28036077680cb5255450a03", size = 238819, upload-time = "2026-09-30T04:37:14.659Z" }, + { url = "https://files.pythonhosted.org/packages/f8/c1/6116d52a2e3311ec80f21f5fb5e17b27405f10b9608af8f6e69516841a1b/charset_normalizer-3.5.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:d008d90a7f2471519aef0c90dfbe73b3e6e4d5e66ac48e19154c17e89e98b604", size = 272973, upload-time = "2026-09-30T04:37:16.346Z" }, + { url = "https://files.pythonhosted.org/packages/19/aa/9955c7e93bba10a9c7e8f7a5031b7ced66f3a1883a55c00712b8d5850ff3/charset_normalizer-3.5.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:31f3930700408d211f13378ccbe1c40845d8da54bd0681fac3a9b5aae81c7aa8", size = 253692, upload-time = "2026-09-30T04:37:18.212Z" }, + { url = "https://files.pythonhosted.org/packages/bb/33/2a6ae7fdc1b10cb581cef91addd8cdfc5f40d50abb5702309369d5834579/charset_normalizer-3.5.2-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:2a925889534b3748302dae5dead07cc13480de1dac3aea80a941b729b471ef93", size = 268757, upload-time = "2026-09-30T04:37:19.877Z" }, + { url = "https://files.pythonhosted.org/packages/a2/22/80992720a0282cd39bba1db35868e6b9c22f41281160143a836544bc1d8a/charset_normalizer-3.5.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f5ec61164adcec446f8969a3358ec3f9b26bbda3b9213e5586d219afa8df2915", size = 262220, upload-time = "2026-09-30T04:37:21.583Z" }, + { url = "https://files.pythonhosted.org/packages/92/9f/181fd07e1bffea1d95cd80c84ac537354f50699c22cfc4d3c02b6fc16208/charset_normalizer-3.5.2-cp314-cp314t-win32.whl", hash = "sha256:598a11a2c7ebaa5334bf698bf29568c9c390abac6a154d8170fedecd1cea38c5", size = 197797, upload-time = "2026-09-30T04:37:23.235Z" }, + { url = "https://files.pythonhosted.org/packages/49/1c/25d8415ec1c4f2f41f1680435e4c87cfb378ff2f677d950946f2a45d0632/charset_normalizer-3.5.2-cp314-cp314t-win_amd64.whl", hash = "sha256:7fdde2c9fd9e3eca40631e024664cf2584272cc8f96308cbe5fdfc930f51d8bc", size = 222765, upload-time = "2026-09-30T04:37:24.891Z" }, + { url = "https://files.pythonhosted.org/packages/3e/b4/46b48f013dadfc0d0d33b375438e31bdf5a989dc68389c6bf627054d4df9/charset_normalizer-3.5.2-cp314-cp314t-win_arm64.whl", hash = "sha256:d1befeed746d247c81127bb14de9dc3d30edb6e5976d34f83f86ed262b1d9105", size = 210985, upload-time = "2026-09-30T04:37:26.634Z" }, + { url = "https://files.pythonhosted.org/packages/ca/e9/34e597dee616d0b8ee4b34d29399e85c2204ade174157a48505d42baa4ff/charset_normalizer-3.5.2-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:87475fabc8d9996fd9c27debb395e642e8c838d78a00b6e932227a0e06b81e26", size = 367676, upload-time = "2026-09-30T04:37:28.329Z" }, + { url = "https://files.pythonhosted.org/packages/60/9f/a5d1c91c0263745e2cd344c5a4415d787c575501ab1d449f1148ac6b495d/charset_normalizer-3.5.2-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9409a8bf35cf78353942504b24a57de3d75b708997a1e4bd8db71ac8633ce364", size = 248414, upload-time = "2026-09-30T04:37:30.167Z" }, + { url = "https://files.pythonhosted.org/packages/26/79/e697f77464748a3ee3cf490c83d592459400d4898380d66c38366b03080c/charset_normalizer-3.5.2-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:498dc3188ca05a68231ac3fdbfc7f57eb67e1343c30e0fea17f8218c1599b253", size = 244775, upload-time = "2026-09-30T04:37:31.964Z" }, + { url = "https://files.pythonhosted.org/packages/ca/87/3d42a42e18ea066e2513936fd678a00696e77878b5ae04528976abdbcb83/charset_normalizer-3.5.2-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e242bb1c5e76e97dfa9e7f209a71e93a01d7f19ffdd5cfbb2e2d55b4f08f8ab0", size = 273877, upload-time = "2026-09-30T04:37:33.661Z" }, + { url = "https://files.pythonhosted.org/packages/c3/76/8a28136f3938ba9836f84280ce0c4d61ed1cf15a036b2034900c62634162/charset_normalizer-3.5.2-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:def79fa35ef0cef8d2accec024f4fdc7ead3012ff02f5215c783f39f03ef8cfc", size = 269455, upload-time = "2026-09-30T04:37:35.573Z" }, + { url = "https://files.pythonhosted.org/packages/a0/a1/4fbf5d0f0f1b2a080474c1cf9a2f12c4c6531bb0e8ba591055e846d2b4e9/charset_normalizer-3.5.2-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3df041de8887954562c9b261cba85ca0e9ded74048daf125f45edcfaa4832229", size = 257336, upload-time = "2026-09-30T04:37:37.397Z" }, + { url = "https://files.pythonhosted.org/packages/ba/a2/8b50aa320adb880ad579518e6f718f24944804b42a88b83d267d5d444125/charset_normalizer-3.5.2-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:04851f73ae72b8413dddadb16a49dfee95263553741fd42d546f7d66907e6be5", size = 257584, upload-time = "2026-09-30T04:37:39.522Z" }, + { url = "https://files.pythonhosted.org/packages/a5/57/50e3fed84e175f40349bd0da7a4fce94c87f0378f52d74f511d89e0bdc20/charset_normalizer-3.5.2-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:183b88127acdb4fabe59d951ab424faf1af7b63cdbb5f776186c1ea2ffcaed98", size = 251854, upload-time = "2026-09-30T04:37:41.23Z" }, + { url = "https://files.pythonhosted.org/packages/d6/54/f7fbb3493c9f49091213b9c2d6dd65800696f1ce1a3f196a4205f50417b1/charset_normalizer-3.5.2-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:16fa0eccf81304b79c5cd87f9271c3b85dd9dd99245e4422ae9c0dd45e0f99d3", size = 248767, upload-time = "2026-09-30T04:37:42.883Z" }, + { url = "https://files.pythonhosted.org/packages/d9/37/b3a6385acc5a1e45b39ae9c90bfb9cf838a09b9dd37ef2740ab4c6b4a2eb/charset_normalizer-3.5.2-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:7441d755b7ab94f8d4eb3e43ec05482d760842fd263d003a99102d742cd835e2", size = 274479, upload-time = "2026-09-30T04:37:44.658Z" }, + { url = "https://files.pythonhosted.org/packages/89/44/809913e2cfd279e635a9294fdbbfb1b1dc62a8189d473d561f649fce98d8/charset_normalizer-3.5.2-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:ca403d7e4798f525fdfc78e258820419cbbd0f0ecbab9de7840e3c017cf6b8cf", size = 258310, upload-time = "2026-09-30T04:37:46.529Z" }, + { url = "https://files.pythonhosted.org/packages/af/a2/f28400ab13359d91bd39179df8e149376b9bf36588e739a3a4f9de2b84b2/charset_normalizer-3.5.2-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:df29a0a7107f7011e77f4eebdddec4c7331e24d787a0b21a46d63bdf7445da95", size = 271100, upload-time = "2026-09-30T04:37:48.399Z" }, + { url = "https://files.pythonhosted.org/packages/e9/89/9bab37955edf0adb3b66f8a3a6617d9f2f487e0d56f295a6a286cb640aa6/charset_normalizer-3.5.2-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:f3c96f633825733f735c5a9cf21d21a257d8e1edf0b1cee0a064b9c424ca0f7d", size = 259936, upload-time = "2026-09-30T04:37:50.023Z" }, + { url = "https://files.pythonhosted.org/packages/23/b5/4459e08d45a679f903d50fea08bc52cfa728cca4d7bd02c757b5e5abda2e/charset_normalizer-3.5.2-cp315-cp315-win32.whl", hash = "sha256:281cb91036248400f4cc957495cccd44c275c2e0c5854f7e45ac5cf7dc193847", size = 186301, upload-time = "2026-09-30T04:37:51.722Z" }, + { url = "https://files.pythonhosted.org/packages/98/e8/55d5fd3935b4bce6da4fe0df61898e8c82653e317e677bd58aceb9c60f13/charset_normalizer-3.5.2-cp315-cp315-win_amd64.whl", hash = "sha256:89b53f3cda69831909888e0494f4fa0bcd3537e3e138dabeb620bd6ad946bae8", size = 210858, upload-time = "2026-09-30T04:37:53.427Z" }, + { url = "https://files.pythonhosted.org/packages/a9/5b/974423c2fd8e524c7a7f64318c1e02240ef954912fa2b4d70344107b9c68/charset_normalizer-3.5.2-cp315-cp315-win_arm64.whl", hash = "sha256:6be488a102b8cf28d0391d8c4ba7748938ae28b78ad901f8585520fca33ead1a", size = 200309, upload-time = "2026-09-30T04:37:55.015Z" }, + { url = "https://files.pythonhosted.org/packages/ee/f9/00ee0195db1013d8f7c416fd770fbeb560bb46eb2e36b054d05cb56f6cfa/charset_normalizer-3.5.2-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:915563965d418f986e7e145accc592eae9e1a1be3566ff98a05d7a9ec42a76e1", size = 395343, upload-time = "2026-09-30T04:37:56.743Z" }, + { url = "https://files.pythonhosted.org/packages/04/3a/c00b50e94c964cf934c7899cd47c97952fc11dad71cc5884b3c61795b09b/charset_normalizer-3.5.2-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:65cd72beeeca9d3aaea1201e5923859f308f952f9c71de93f06063c79f0f7a3b", size = 250114, upload-time = "2026-09-30T04:37:58.607Z" }, + { url = "https://files.pythonhosted.org/packages/50/27/d102dc880bbcffd0479ab64dfc1fb96777a854355a55e2bda72a71efadcb/charset_normalizer-3.5.2-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b7fd005a73d9e657273b7a10dc71a9e03c8fb9ee6999798d6918ce095b81ac7f", size = 239997, upload-time = "2026-09-30T04:38:00.511Z" }, + { url = "https://files.pythonhosted.org/packages/a5/4a/bf7ef45794dd293fab5f98a9309817977fbb845b9998f171b8cc5d8437a3/charset_normalizer-3.5.2-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e54da4baf05720032d527874d40b65fa4d7e5c6c6a43d0c3adbeffcaf275a2b3", size = 272313, upload-time = "2026-09-30T04:38:02.509Z" }, + { url = "https://files.pythonhosted.org/packages/e8/ee/008a2837737991474c5754bb3191010007663860979701990982a502cbaf/charset_normalizer-3.5.2-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:124fbf1a8ff966d87ae05bb8bd45a71f966055ed8bba320d0c7cf450bc5f4d0e", size = 269986, upload-time = "2026-09-30T04:38:04.435Z" }, + { url = "https://files.pythonhosted.org/packages/93/ad/bd74a283940dc910c5b14f8e4f80a248082bc9c0fcbe1f54530cb6d9cc5e/charset_normalizer-3.5.2-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:28b4f0d66fb834ff90f28209ac7bce77868c45d8c93e26f906709d9b7c2e1af9", size = 260202, upload-time = "2026-09-30T04:38:06.549Z" }, + { url = "https://files.pythonhosted.org/packages/8a/7b/ed341c66f69f688723501fac752be3d63c7159ca0d0d4174fc611e5710bb/charset_normalizer-3.5.2-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:58ca3755ee7ff7f59b57789ec9833c9de9ea275405cdd240eda1f193112e398a", size = 259083, upload-time = "2026-09-30T04:38:08.311Z" }, + { url = "https://files.pythonhosted.org/packages/cc/9d/e41588b777965e5031a43128a1e96173ebb35ac75fc53ec3b517e7c21cd4/charset_normalizer-3.5.2-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:443eae2bf318abeaf6f15d785138f71fd6de770e99a92158b8b814265e079115", size = 253081, upload-time = "2026-09-30T04:38:10.402Z" }, + { url = "https://files.pythonhosted.org/packages/81/35/b761eb6d8c1eb218b9b42b9b4d5ac902afdc399fb6dac6f9a9aac7bda589/charset_normalizer-3.5.2-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:58f361dcbab699cf8f42db3f47c8e7fd1036f138c23a5d08de9fde5f425a730c", size = 248712, upload-time = "2026-09-30T04:38:12.317Z" }, + { url = "https://files.pythonhosted.org/packages/4d/2c/147169a041b747759f37405c0a97157e8e92de967968373101ff14915cba/charset_normalizer-3.5.2-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:1b4cbc7c3491ccb4aa17fcd8165649d01cf39f76de1696da8631b5f71b85401d", size = 274176, upload-time = "2026-09-30T04:38:14.138Z" }, + { url = "https://files.pythonhosted.org/packages/f0/2d/0ff8db0d373ba8538db686db11cd7e8912031490b9e4f383b41912e8d594/charset_normalizer-3.5.2-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:ba0b1d2620edf869789c3879223f52bf2afc5d31b3cb47cc57b3a12c05e2aa9d", size = 259413, upload-time = "2026-09-30T04:38:15.841Z" }, + { url = "https://files.pythonhosted.org/packages/8a/8e/b4a085fb47c9d3a7e43576a4784fdd8fe23f907514a972de8086edaf7a48/charset_normalizer-3.5.2-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:5e2b6b57e9733d39f0c9fd3185efa6b8e29652c4cd8fe94180272cf6ed9a78c4", size = 269434, upload-time = "2026-09-30T04:38:17.626Z" }, + { url = "https://files.pythonhosted.org/packages/83/1c/d8d8d7322a7c3eecdf3237a4a419cf41d2eaad8e006ce7dfdd9d4c8fa2eb/charset_normalizer-3.5.2-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:51cf45226a9b588d0d2b4880c62d686934b63ab0bd79ca23ab0e9762eb27441b", size = 262716, upload-time = "2026-09-30T04:38:19.214Z" }, + { url = "https://files.pythonhosted.org/packages/a0/16/0e4c6ba9b44e97a2da150e52d331e8f9c968b21b358fbffa6c856cebcd89/charset_normalizer-3.5.2-cp315-cp315t-win32.whl", hash = "sha256:5fb29fb8cd1a46c27a1bf9613ad5ec2599310d46b4025d9556404a6b6a292800", size = 197159, upload-time = "2026-09-30T04:38:21.037Z" }, + { url = "https://files.pythonhosted.org/packages/be/33/e90bc2b1374f7f36ef106f56620de5a783907e19ca857efe2277e31cac3e/charset_normalizer-3.5.2-cp315-cp315t-win_amd64.whl", hash = "sha256:a192e2c40070d92c3ccf777e3a5c4ff515573cd2bb7ed0c537fdadbbec5bbf21", size = 221322, upload-time = "2026-09-30T04:38:22.886Z" }, + { url = "https://files.pythonhosted.org/packages/66/89/dfa6dcb08c200b7830ab56439e8c1890f2971d51aafbb3937894a2e7fcfc/charset_normalizer-3.5.2-cp315-cp315t-win_arm64.whl", hash = "sha256:749e97e1b32313717a565abbe321bc2190bc8b35f1a67e4cdbc7c56c8d8ffe58", size = 209192, upload-time = "2026-09-30T04:38:24.648Z" }, + { url = "https://files.pythonhosted.org/packages/8c/ab/176fbfd5b64939c55d652366aa5b9ef1d767af207a3aa6ebeb0d226c484d/charset_normalizer-3.5.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:4275811936e2f06feff5e598fb42a1b7ae852da8e39605211892b56b81a34efd", size = 331815, upload-time = "2026-09-30T04:38:26.216Z" }, + { url = "https://files.pythonhosted.org/packages/7e/84/371eac6b30bdbcbf2d632a1a01809103459216fcaae61b8b8d922c1bfb8a/charset_normalizer-3.5.2-cp37-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1c50fe28bbc2ced33386f298650d91218076c05420e6cbd790b913adc41659e7", size = 253276, upload-time = "2026-09-30T04:38:28.032Z" }, + { url = "https://files.pythonhosted.org/packages/43/6f/c4fbae58febff71709c51bc7e18fdfa55341dc382704740f9f0cbf03817b/charset_normalizer-3.5.2-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d19fbd981a488e22cd04883659ca6b08f50b5974f9fd7c95655ef6a043e5893f", size = 241239, upload-time = "2026-09-30T04:38:29.732Z" }, + { url = "https://files.pythonhosted.org/packages/61/71/458c3f42164a07d0c5210798e9e704b39e540a6793b05aba67f3a35243a9/charset_normalizer-3.5.2-cp37-abi3-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0fed1d06615f022ee3b13caf5e8b180cfea32bb2c5aded8a9d44277afc040f93", size = 231121, upload-time = "2026-09-30T04:38:31.462Z" }, + { url = "https://files.pythonhosted.org/packages/09/54/ab9e89367076f6331bb6c65c4bf14a5361fa5191cb6561bf534f18504e1b/charset_normalizer-3.5.2-cp37-abi3-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:838dcc90063569a0448120554591a1d6c4a4ffe11babf048908793154ab86ade", size = 260350, upload-time = "2026-09-30T04:38:33.239Z" }, + { url = "https://files.pythonhosted.org/packages/7c/c1/061431ecc688d9d76602502cb57cc01e691e682c18f1beb45f9673b5bbd2/charset_normalizer-3.5.2-cp37-abi3-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2ce45c6627b22c47e390bc91a41c3d13032192e699fa0bea96e9671b373d69b0", size = 255430, upload-time = "2026-09-30T04:38:34.865Z" }, + { url = "https://files.pythonhosted.org/packages/8d/1f/20c8949f0676f7ab811abdeb7f4d7f1cbc6e61ff20bef08b44edeb092bc8/charset_normalizer-3.5.2-cp37-abi3-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0774bf9bf620249fee3e0b8b9fd3065de213be30f3aa94ce2494b3b638949e26", size = 250612, upload-time = "2026-09-30T04:38:36.649Z" }, + { url = "https://files.pythonhosted.org/packages/2b/9e/46f2fa4c431fc98c4ae76a8cb5bdca54e0341e3cfc3fcfd8e82740250818/charset_normalizer-3.5.2-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1db38f4c5496827c1a501846d64d14c3b80c7e6714e406cd7dc36a9899fa1011", size = 242083, upload-time = "2026-09-30T04:38:38.26Z" }, + { url = "https://files.pythonhosted.org/packages/bd/39/559be29a0c0f086e0bba6922babd38916cc5e0b58ced4de13ee01ea05508/charset_normalizer-3.5.2-cp37-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:304d8e4d493af723536393eee0c689eb7813f4a474c8b479dee63f1fdd98f621", size = 232738, upload-time = "2026-09-30T04:38:39.81Z" }, + { url = "https://files.pythonhosted.org/packages/ff/6c/387b0e4f756a282831c1d9fc6aeb6c51ca4507ca202767c8de15ce9b12e2/charset_normalizer-3.5.2-cp37-abi3-musllinux_1_2_ppc64le.whl", hash = "sha256:9b7f416ff0978e2f2249330527f0ad6fa02f4932e6199692d3b52da2048c19e4", size = 260703, upload-time = "2026-09-30T04:38:41.346Z" }, + { url = "https://files.pythonhosted.org/packages/96/92/1fdf015f09ef449f50d3ac4b67c90887c9c318b727daa95cc4f866e6521d/charset_normalizer-3.5.2-cp37-abi3-musllinux_1_2_riscv64.whl", hash = "sha256:01077390b03f7988f11d700a2194e69b119741a86b1a638b1db88891e3eced8e", size = 247622, upload-time = "2026-09-30T04:38:42.937Z" }, + { url = "https://files.pythonhosted.org/packages/dc/3c/8e7b8a5671ad5d433669fb2a76f1a0164df2d9b1718b0206bc2a16d840cc/charset_normalizer-3.5.2-cp37-abi3-musllinux_1_2_s390x.whl", hash = "sha256:7e841fb9010836c992c9f12fcbd43a831de93a5f726fc1ccd8ca1d0268c5014c", size = 257500, upload-time = "2026-09-30T04:38:44.604Z" }, + { url = "https://files.pythonhosted.org/packages/b4/f0/45b579df5cabc1d5d53ea1cc35e8437d3ca768c0acccc7041517cb6fbb32/charset_normalizer-3.5.2-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:9cae88599c7219005d879f98e5ed53341e9a122af585e1091200358a3003d2a0", size = 255100, upload-time = "2026-09-30T04:38:46.289Z" }, + { url = "https://files.pythonhosted.org/packages/31/68/fdec18a343f5fb3f310588dd478b09ac4799e0b187dbade3a8cd776f03ef/charset_normalizer-3.5.2-cp37-abi3-win32.whl", hash = "sha256:01b0c0d2262a9e28e8484a278c7e1b5d650e3ac8cf2683d2967e25899f208bdf", size = 174499, upload-time = "2026-09-30T04:38:47.999Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8a/b618149cc5207943a0242068d7a27897f56a62947b5a039085f2a22029f8/charset_normalizer-3.5.2-cp37-abi3-win_amd64.whl", hash = "sha256:9f56f72050826f63dcee7a7f55b0a77168cb3bfc553fd405e7f8f9ece75a4036", size = 200092, upload-time = "2026-09-30T04:38:49.707Z" }, + { url = "https://files.pythonhosted.org/packages/03/cf/4c66866fa9e2b1c78e3c911516d1de497a677b7ac60f1eceda74ce777ca3/charset_normalizer-3.5.2-cp37-abi3-win_arm64.whl", hash = "sha256:40ab6bffa02ae10a0581e6c198be7d2d8ca5c2a0c64e4ed3465d766df457573e", size = 294363, upload-time = "2026-09-30T04:38:51.312Z" }, + { url = "https://files.pythonhosted.org/packages/fc/ad/d07d7862a62ffa6d79d68074d14823243dd235a77c45262acbf6adeb28bf/charset_normalizer-3.5.2-py3-none-any.whl", hash = "sha256:b6b751274acb69d77b3323d6b7dbaa3c7fdfc1eb829b7eb61d262f32e1af9685", size = 68872, upload-time = "2026-09-30T04:39:21.828Z" }, +] + +[[package]] +name = "click" +version = "8.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/0e/7fa0ef50764b67090eca4114772a2abf8b6148198475e54c660b97caeee6/click-8.5.0.tar.gz", hash = "sha256:ba0d2089de75ea0310e2dde03160e6ca10009947fb95a182f9b54021bb272e34", size = 382235, upload-time = "2026-08-26T13:33:14.56Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/58/50/6c0d534c5f134586a8e1ba4e330569e32f057e33372ae556463212fb4cd3/click-8.5.0-py3-none-any.whl", hash = "sha256:255bc9599cf7748b4b1a446ccc735421bd08a2ae529a8b88597d3de5664ee360", size = 125251, upload-time = "2026-08-26T13:33:12.928Z" }, +] + [[package]] name = "colorama" version = "0.4.6" @@ -293,6 +588,28 @@ toml = [ { name = "tomli", marker = "python_full_version <= '3.11'" }, ] +[[package]] +name = "cssselect2" +version = "0.10.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "tinycss2" }, + { name = "webencodings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/00/2456b6b664c7a770989cbe3c352aac4eb962c938486f03a2e1255ae963c6/cssselect2-0.10.1.tar.gz", hash = "sha256:83b0d820ef589dabaf693289b647c2f5b410f76d285f56deba911ffa75a7b9d1", size = 35653, upload-time = "2026-08-31T21:57:42.59Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/59/6b1daa3b94de8970e2a2787ba73616c2d0675d2f948ef4cad8bef7f21bc6/cssselect2-0.10.1-py3-none-any.whl", hash = "sha256:25cc4494d55985d6a6da359be48da6ce98c28dcbafa2314c383ace3fc32ec868", size = 15489, upload-time = "2026-08-31T21:57:41.162Z" }, +] + +[[package]] +name = "defusedxml" +version = "0.7.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/d5/c66da9b79e5bdb124974bfe172b4daf3c984ebd9c2a06e2b8a4dc7331c72/defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", size = 75520, upload-time = "2021-03-08T10:59:26.269Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61", size = 25604, upload-time = "2021-03-08T10:59:24.45Z" }, +] + [[package]] name = "exceptiongroup" version = "1.3.1" @@ -305,6 +622,43 @@ 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" }, ] +[[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.3.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] +sdist = { url = "https://files.pythonhosted.org/packages/27/af/018c10bc9edd42b6ef6db2e96b09542050d5253f9b195e74bc910b2d13ab/griffelib-2.3.0.tar.gz", hash = "sha256:7b0952caf5bca6afa4bb5ee8c6a2d183fe3f21b62efc5f6c7243cb2b26d2d115", size = 234534, upload-time = "2026-09-04T15:08:17.472Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/63/e876e789525063c840ccfa8857febdabd6523bcef9ce7eb979b9305ea895/griffelib-2.3.0-py3-none-any.whl", hash = "sha256:1b8f9cd525681c26b1d6d574faa1371651e8459ca51d209684f50b8096ae06e0", size = 169423, upload-time = "2026-09-04T15:08:12.956Z" }, +] + +[[package]] +name = "griffelib" +version = "2.4.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.15'", + "python_full_version >= '3.11' and python_full_version < '3.15'", +] +sdist = { url = "https://files.pythonhosted.org/packages/2e/5f/6d93df326cbf8f9f7276be77f83c81a9c061f479abdd81f9bbec197d4b29/griffelib-2.4.0.tar.gz", hash = "sha256:a277a462c56ff4479efe5cbcb4f882dc9a63cfa5ab6404a3e60957c6c8d2f7c9", size = 244488, upload-time = "2026-10-19T16:26:53.583Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/28/bb989a55ac56dabf30765d2e7ea0710c032d9b67d8a7599f91fdcb2e00b1/griffelib-2.4.0-py3-none-any.whl", hash = "sha256:0a7db47b0bdf5123a6ceca2f71aa996742a4f04d9048046778f4a9006772d27f", size = 172791, upload-time = "2026-10-19T16:26:49.511Z" }, +] + [[package]] name = "h11" version = "0.16.0" @@ -360,6 +714,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/56/43/4ca9e49d27a1fcf6bece6f6aec0ea46bb9112489b93d4b688fb415457bdb/iniconfig-2.3.1-py3-none-any.whl", hash = "sha256:9121e2c1fdb355232495be3194c8dfe87ccc2d5dee45947b78e68f499790d7a7", size = 7552, upload-time = "2026-10-06T22:48:36.959Z" }, ] +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, +] + [[package]] name = "librt" version = "0.16.0" @@ -490,6 +856,364 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/36/69/7a5d10ac409c4da0355e054a14371871da9b5557fcc42772cd00181c6cce/librt-0.16.0-cp315-cp315t-win_arm64.whl", hash = "sha256:8ceafb70f2a4f0826f11031942e59c0728fd98da112dc346d4352bde1e486866", size = 116391, upload-time = "2026-09-29T00:55:07.484Z" }, ] +[[package]] +name = "markdown" +version = "3.10.3" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] +sdist = { url = "https://files.pythonhosted.org/packages/29/6f/da4c6aea59b3001f2e8c0ec7497475aadaf3b021c10cab5b2858f0f32b26/markdown-3.10.3.tar.gz", hash = "sha256:3589362618f743188b4d955b874402bc814f4f83f544dc207719f4baa7d9c45f", size = 372596, upload-time = "2026-07-30T19:05:29.005Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/69/4a5af2bc115a9a33fefe51709749de8262be3f9ba063d1753a837cdbc49c/markdown-3.10.3-py3-none-any.whl", hash = "sha256:fa6c92a00a4a3c98b22728c64a935ae1928250ae65058a6ded814d2cc29a4cea", size = 110757, upload-time = "2026-07-30T19:05:27.883Z" }, +] + +[[package]] +name = "markdown" +version = "3.11.2" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.15'", + "python_full_version >= '3.11' and python_full_version < '3.15'", +] +sdist = { url = "https://files.pythonhosted.org/packages/f4/32/0b4d0297064244f04af4331b65de16237cc3cce07474171ee14222a28981/markdown-3.11.2.tar.gz", hash = "sha256:87bf5d90f2d2882e2c02fcda182c2800456b985bff38913867c49706481514b0", size = 491445, upload-time = "2026-10-19T19:41:42.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fe/66/bcab3b677b71ad286b4e607e3427499537c76e13ad2e22584ba7a7d9882c/markdown-3.11.2-py3-none-any.whl", hash = "sha256:f80390747a2a0ff2ba54da074ce4f862f72a6685f608cd2637b646a6d83993f5", size = 114266, upload-time = "2026-10-19T19:41:41.244Z" }, +] + +[[package]] +name = "markupsafe" +version = "3.0.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/38/9b/e422a865e1d5d57d0e509b4e0bf1c1a70a7f6382c29a5aa428df994c8bc8/markupsafe-3.0.4.tar.gz", hash = "sha256:2e9ad7dd851bf45fab9f75cbff4cb493fee9979e8d8c7c9c3ee119022518edd6", size = 153777, upload-time = "2026-10-02T23:07:22.29Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/aa/9a65962e364bf19745f6bec7bde398fb1f5ca53ad2e734258e6198cc32ba/markupsafe-3.0.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dd8ea6ebee7aedbf7c749fa80521d9ccf1ba473e0d1e14805caafbaad281c889", size = 11521, upload-time = "2026-10-02T23:04:20.141Z" }, + { url = "https://files.pythonhosted.org/packages/14/36/927999a34b7d1def6957de89153d327fedc4030061940b5a468584e6c5a8/markupsafe-3.0.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dff05cb7016dff1e9fd68f4122c127b65dfc59de5306cfb7ad92f956f230bee2", size = 12066, upload-time = "2026-10-02T23:04:21.275Z" }, + { url = "https://files.pythonhosted.org/packages/17/54/69e7b0db9bd687bfd83451eed5666384d67cfed3be062bfc59a06a15474e/markupsafe-3.0.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cf63c214fe879a65e69a386f915e36104fc84254ab141240f8854602d8e0be2a", size = 22081, upload-time = "2026-10-02T23:04:22.221Z" }, + { url = "https://files.pythonhosted.org/packages/bd/14/f6f5c97903f7d2db76bbfaced31509a47d360a103b3aaf4849f6536591ec/markupsafe-3.0.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2a6ef68ae94aed8721934072b27a3b654ea2100b97e4ab864cf1489c90926fbc", size = 26079, upload-time = "2026-10-02T23:04:23.346Z" }, + { url = "https://files.pythonhosted.org/packages/d0/04/c3cc9b75f94f8b54d7e503c44cebd4b4a115ec1d6f1b996b999807daba99/markupsafe-3.0.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fd9f8797427910198f95bced71ddfed61130d7e349213bfb8466c9c99e2c46a8", size = 22611, upload-time = "2026-10-02T23:04:24.401Z" }, + { url = "https://files.pythonhosted.org/packages/00/26/c4708ed3b0f08e8e6d7cbce3314ac130cb5352d1f62951b6fef7878f2b1e/markupsafe-3.0.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d1aca03ede943eb80ab3d63bb082c84b7aab85ea83bd0fd0c200260945fb49d9", size = 20712, upload-time = "2026-10-02T23:04:25.386Z" }, + { url = "https://files.pythonhosted.org/packages/d9/b9/f3894d6aae3d7a52c9363317f4baf2fcadc052163d6dbc871266e32639ed/markupsafe-3.0.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0764a13d34cae40db7bbf3a09b7e9b491bf4603e20b263a7a9d6b8e324975d0a", size = 20742, upload-time = "2026-10-02T23:04:26.403Z" }, + { url = "https://files.pythonhosted.org/packages/59/7c/8e248ddbfe286ab6bddb462bdac0851cbb1510d2cbbb815a415fcb0511af/markupsafe-3.0.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9388003072b95f2f1e3fd908604194d653ba21330d811961a78b7da1a77e9e36", size = 21560, upload-time = "2026-10-02T23:04:27.522Z" }, + { url = "https://files.pythonhosted.org/packages/df/26/2353fef7d4bcf2b18e16bad81979fcecff2915156ca6882447917205b8e2/markupsafe-3.0.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:8698d70a8081ee8c090dbb394768b5789a1da8b131b5499f89d071dd3cfaf6be", size = 20973, upload-time = "2026-10-02T23:04:28.573Z" }, + { url = "https://files.pythonhosted.org/packages/67/6f/a9561d98d9a6ee3494b0b970a1c766e58bab128cc84841d56ec009456dbd/markupsafe-3.0.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:bf053da3c97a4bc5ecfbb218cdd2983febd91c617be8367d139882aa11e490aa", size = 22036, upload-time = "2026-10-02T23:04:29.568Z" }, + { url = "https://files.pythonhosted.org/packages/55/83/6217df9192eca95af3ff0cad955c9854a93fa43b288cf7411ae24713eb52/markupsafe-3.0.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:9438a2648b2195980cb2dd8e53ed7b8df91319e2d0b70ae61a9e1d1bc8d3bec9", size = 20314, upload-time = "2026-10-02T23:04:30.881Z" }, + { url = "https://files.pythonhosted.org/packages/35/7c/9cd8081dae70e17fdab3558121fa618d459c7950c8abd8fc10fc024486d7/markupsafe-3.0.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:88d59b473bfb03259722600839af9bbd7fa13a2eb514beefeedb95997882f69a", size = 20780, upload-time = "2026-10-02T23:04:31.975Z" }, + { url = "https://files.pythonhosted.org/packages/44/37/c5f2f45f4d8f0c24e4af7b9dc711640c888044cbf5f7e2ba2c0bb74cbb55/markupsafe-3.0.4-cp310-cp310-win32.whl", hash = "sha256:4a540e2d3192792fc84eced57bef37851ccb2b41f73291bb17408eea77bcd278", size = 14096, upload-time = "2026-10-02T23:04:33.129Z" }, + { url = "https://files.pythonhosted.org/packages/50/50/394a1c61c9b9972cb4f76875c332af7109bd39bdad09d3a0ec5327a339dc/markupsafe-3.0.4-cp310-cp310-win_amd64.whl", hash = "sha256:5c22873ad1f0532ba40fa1727f3c0fc1bbbaab6d373d4cbe3f0dc74b2e2521c7", size = 14329, upload-time = "2026-10-02T23:04:34.168Z" }, + { url = "https://files.pythonhosted.org/packages/d1/9a/86d03d2f32ba41a57baa124a7bcb76d0a6d39b1622e9bd4d550074e8b61a/markupsafe-3.0.4-cp310-cp310-win_arm64.whl", hash = "sha256:3d23795802fc8bd72534836d64489bbf0f67c088959091bdb22e10735a5107bf", size = 14196, upload-time = "2026-10-02T23:04:35.201Z" }, + { url = "https://files.pythonhosted.org/packages/32/55/18dbb4778b30ada5ce071608503cc3edc9e14e13d868c17a6d178fc30f7a/markupsafe-3.0.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9e25feb9e330b63edb0278a0acdf85e50d0cb0fbf49c3084abbe4e24ae195346", size = 11520, upload-time = "2026-10-02T23:04:36.299Z" }, + { url = "https://files.pythonhosted.org/packages/6c/14/0b05f79b4733e264a18d08fe08fa1df7347630ff32a6cb82180d9dccec55/markupsafe-3.0.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7d3391b2188d18737cb2fa147028b1096236eaa7e156446c650a489fa2cadc91", size = 12063, upload-time = "2026-10-02T23:04:37.291Z" }, + { url = "https://files.pythonhosted.org/packages/ca/3a/63ba10b6c1463216b3e4df669a9f0e5a3b0c3071557d2e8229e3968c79fb/markupsafe-3.0.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:849dd2bb0e5e4ab2b71c7191726a4a8d5aa8a610daa584728cbee0b710ddc4ef", size = 24321, upload-time = "2026-10-02T23:04:38.262Z" }, + { url = "https://files.pythonhosted.org/packages/1a/2e/5f015261b76ad633d187ef6f388b413aedd64a8773c4df59e530a0be5525/markupsafe-3.0.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:befb4158af32106b9a93db8d6d1d1cbbd418c0d5aca0cabb7b1780abf0c89169", size = 28845, upload-time = "2026-10-02T23:04:39.295Z" }, + { url = "https://files.pythonhosted.org/packages/33/cf/26e594b26be40c2f1fec63ccf8a8b99d0335a5b2cbe84835c7d82a994375/markupsafe-3.0.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:71f88e749ea29f67f21f3b36433c1dc54c7729ed2a6d9e2da2e0d9e0d7b224eb", size = 24701, upload-time = "2026-10-02T23:04:40.348Z" }, + { url = "https://files.pythonhosted.org/packages/81/a5/a513b76c139a3915b43404324e55c0b7979ae4f0d39eb6f075b0282e90a8/markupsafe-3.0.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6da83a088f8ef93b2d483a8232a4dbf4d69d3d8496b568a03c56becac43e1808", size = 22961, upload-time = "2026-10-02T23:04:41.372Z" }, + { url = "https://files.pythonhosted.org/packages/46/cf/4c66192c100b4542bcbe392ae06696b670f66927be3ac38a213234778ff9/markupsafe-3.0.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8f0fac8b13d14bb06c68195f849371924ae53dd7b1c00fed24650f704383b692", size = 21920, upload-time = "2026-10-02T23:04:42.429Z" }, + { url = "https://files.pythonhosted.org/packages/cb/17/ac3662678bfbad649893117ada2ba44dc30bf56884e84f13154a792b10f1/markupsafe-3.0.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4a7cdc2a420ca01058182da4253329764d4bfa055564d1eced90e6ba1e8b1d3d", size = 23726, upload-time = "2026-10-02T23:04:43.531Z" }, + { url = "https://files.pythonhosted.org/packages/f7/af/fe47cee339180a69ebca3c57fb3483d0f5cbd1e8337d1871fb1d9c1aebee/markupsafe-3.0.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:83b3944fea42a8400edf92fd1770fb8d0d4f7de651353bd2d8525a92dba69a21", size = 22539, upload-time = "2026-10-02T23:04:44.618Z" }, + { url = "https://files.pythonhosted.org/packages/12/32/d55440ba140442800e02d799c9cb5ab597bf6ebdb1177b5ea39a11f797bd/markupsafe-3.0.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:8138eb83940ec7299024d92d4dee45f601b9e6c5ffde9d25f4e35e326203c707", size = 23963, upload-time = "2026-10-02T23:04:45.656Z" }, + { url = "https://files.pythonhosted.org/packages/50/9d/9c86042cb364c2ad4c971e6d1247929effd25f714cd7ee11b05e6316445b/markupsafe-3.0.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:811d02d5122171c1941357efd8f9bf4ffe907b7f0a1a4e729a880e4be3f46e3e", size = 21506, upload-time = "2026-10-02T23:04:46.671Z" }, + { url = "https://files.pythonhosted.org/packages/75/ef/5b824f03ba40c3b3652b6272d083d2fc4fcdd440de519a3a39ba2c3e7262/markupsafe-3.0.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:50b5bedc9ed8a94fc8857a42ef4f84a81ea88f8d4f05dc8705fb23ee6d8dcca7", size = 22955, upload-time = "2026-10-02T23:04:47.698Z" }, + { url = "https://files.pythonhosted.org/packages/1e/e8/44cfcb5ea40e5e43cec7793ef90704ed0c475280839076c4345757eb8e59/markupsafe-3.0.4-cp311-cp311-win32.whl", hash = "sha256:2e5a7cd7fdd14fcb1ae5d7d8bf23d24fbd1daefd1fbca2580132e1ea75f098b5", size = 14094, upload-time = "2026-10-02T23:04:48.788Z" }, + { url = "https://files.pythonhosted.org/packages/91/89/f2b509f7bf79352e40117824c1070dbeafd4df67031d3fa98165a3134228/markupsafe-3.0.4-cp311-cp311-win_amd64.whl", hash = "sha256:fdb4ca07ab75ffadab4a8b135ad59cdbb3156b99310f3d565370da74a15d6bd3", size = 14328, upload-time = "2026-10-02T23:04:49.801Z" }, + { url = "https://files.pythonhosted.org/packages/2b/5a/ccf22672a0f64dc682306e288f0dabcb06c7a201f3bb6e6cbf86d9e8ad03/markupsafe-3.0.4-cp311-cp311-win_arm64.whl", hash = "sha256:569d65055d367e3dcdf30c3f41119467b73d9ee9faf332bdf40402644f5ac08e", size = 14188, upload-time = "2026-10-02T23:04:50.847Z" }, + { url = "https://files.pythonhosted.org/packages/81/09/4c59d56b8461ae8eb0d8ba34bb25b7e618547044679d58a82ef9b2479fc1/markupsafe-3.0.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:61631e08084be9e21a8967ec3139c7616ed7c5e9368e05c86d1b39562c8a57b6", size = 11658, upload-time = "2026-10-02T23:04:51.876Z" }, + { url = "https://files.pythonhosted.org/packages/a2/f0/d6613774d86fbf6d145751d43c59875e47a6f9f17daee0aef173bd36d90e/markupsafe-3.0.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0930db9bdc62d22944e10b066448bb65dc9abe9112880c7cab8da54db4284d5f", size = 12050, upload-time = "2026-10-02T23:04:52.931Z" }, + { url = "https://files.pythonhosted.org/packages/0d/f2/8f18e0b806eb13c1f8d07d917a720831ead54253a6dec011fbc78098a6f8/markupsafe-3.0.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6a45c3d514f2436064db00d7fc8778d888f0236ebfed649b53d13a59e69ad51b", size = 24363, upload-time = "2026-10-02T23:04:53.895Z" }, + { url = "https://files.pythonhosted.org/packages/60/ce/fa07dbe8a5675558fa36dea033e19995bc783de2dec5f540ccb9030b06aa/markupsafe-3.0.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1e1451fab512d1bcc3dc26988ec1edb0b82c2db909132872cd9356070a6b63df", size = 28525, upload-time = "2026-10-02T23:04:54.905Z" }, + { url = "https://files.pythonhosted.org/packages/85/40/be87c01f3868ec217f8a2015089d71c22c8c5a75324822e5ed1cdd87210d/markupsafe-3.0.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bd3ce56ae2cbae3ba82b683bc425cd7e48d2ed8b10f3e818186b6f5646d9271c", size = 24733, upload-time = "2026-10-02T23:04:56.229Z" }, + { url = "https://files.pythonhosted.org/packages/4f/a7/aeedb5140afa41fc74c225e9184ab96723a6e873b6ee1c9fede7283456d8/markupsafe-3.0.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e124f974786f831d6043728e38296969d3579db8896fe004682f5758e613581", size = 22985, upload-time = "2026-10-02T23:04:57.521Z" }, + { url = "https://files.pythonhosted.org/packages/c3/fc/e91352bb08c6a59da3ef0909d457bf95a5f5908fbf151b30a06d9dbcfbb4/markupsafe-3.0.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c02e8f18bdedba082cef725942ac823b9b60656db07f7e265cb31618dfd00d77", size = 22001, upload-time = "2026-10-02T23:04:58.597Z" }, + { url = "https://files.pythonhosted.org/packages/5d/f8/bffee5e7d2a3deb59748a797650a48af7e672025cf641a79344a771ad106/markupsafe-3.0.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9f098115c247e11d138ab83a28fa0323c77015007ea2df73ba5fd714dfefd67c", size = 23793, upload-time = "2026-10-02T23:04:59.686Z" }, + { url = "https://files.pythonhosted.org/packages/ed/59/b853d6628ecb4d658e1d637224846d5e9bb4adf4f8df97f3be9f29dce2ec/markupsafe-3.0.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d5f93ebbeb8032d47e349328ec8662d973d9b05a70b3c35df1f91fe419b84749", size = 22640, upload-time = "2026-10-02T23:05:00.768Z" }, + { url = "https://files.pythonhosted.org/packages/09/b2/1506df394f0f075797c418d0301498f49e43be194e3ffcb49e6fe6ccf022/markupsafe-3.0.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:64511c54db4e4987aef4c41923235927428729e8174c5dba488429be70a998ed", size = 24074, upload-time = "2026-10-02T23:05:01.813Z" }, + { url = "https://files.pythonhosted.org/packages/c7/81/5ed69cda630ac69ef60d06c09ba5a7f84ff66a2e28cf986fd5614ab3c6e6/markupsafe-3.0.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:e1a622f13970d81f95d0c72f9dc090dce9085fccfa4c9f2174377ee32bd15786", size = 21563, upload-time = "2026-10-02T23:05:03.239Z" }, + { url = "https://files.pythonhosted.org/packages/0c/fe/fb1e79be0fea60aa32602ebefc9c35a82bb42b4df157285ab7dfec12341a/markupsafe-3.0.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c9a7f43c0b202b334cc9184af09bb8f21d3a209e038efaf106936fb69e6b026e", size = 23048, upload-time = "2026-10-02T23:05:04.479Z" }, + { url = "https://files.pythonhosted.org/packages/c8/52/7632a53360671a9b750cdbabaf9cdd89f18b42248b8e4cb42c0b0296e459/markupsafe-3.0.4-cp312-cp312-win32.whl", hash = "sha256:f0ec3b750b59375eab5b0fb2b9254810c00a3375be6d789899f1055a1d556237", size = 14108, upload-time = "2026-10-02T23:05:05.513Z" }, + { url = "https://files.pythonhosted.org/packages/3f/bf/62495e180b7000aaf30000fff849e933f74264638057176cf46852500adc/markupsafe-3.0.4-cp312-cp312-win_amd64.whl", hash = "sha256:11935df9bf455ed0c04eb87bcd720f02b1fe5e02128a9430f23aed6f93336fc7", size = 14303, upload-time = "2026-10-02T23:05:06.538Z" }, + { url = "https://files.pythonhosted.org/packages/c5/8e/4c24208776a65878d656996945aacfbfe010d3720d1a98fc0eb8491fc03b/markupsafe-3.0.4-cp312-cp312-win_arm64.whl", hash = "sha256:a4bbd2d87dd233b9fc5812160c3d0ffbe42edc22a26ce0469f58479ede633fe9", size = 14174, upload-time = "2026-10-02T23:05:07.617Z" }, + { url = "https://files.pythonhosted.org/packages/6d/18/4bc5ba32499e87bb2b0ef5b3a9bb9c00a131fa961ddf0be548cb550f548b/markupsafe-3.0.4-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:de8b364c423ef0a4bad9069657d617f9a5d2b2062457a89b1fa16ee199c399c1", size = 12786, upload-time = "2026-10-02T23:05:08.709Z" }, + { url = "https://files.pythonhosted.org/packages/4e/6f/17f0c099bf25f3e31e63cc19244d9f6af861a9a4ab778c203997903cfdd0/markupsafe-3.0.4-cp313-cp313-android_24_x86_64.whl", hash = "sha256:34bdde374c5932765d7dc685c4a1d191a3207852d67e8e0a9eb6ea85156181f1", size = 12510, upload-time = "2026-10-02T23:05:09.93Z" }, + { url = "https://files.pythonhosted.org/packages/11/af/1a141081b905036ee904ec4bd945e1f70b4e1b32d33c4e59e8cf1d58b247/markupsafe-3.0.4-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:6bd9e1788e15bfcf6a9082de42e30387e7b85d211ab21e57a939bb8cfaaf8d96", size = 11583, upload-time = "2026-10-02T23:05:10.884Z" }, + { url = "https://files.pythonhosted.org/packages/e7/0a/a89385ae590232622a03e091805cff12f24fabe6c11e0e8bae096cece81c/markupsafe-3.0.4-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:5066b244f576f91afc8ee3ba029a89f99d39c79b1853fe9d39bea9f0afbec148", size = 11801, upload-time = "2026-10-02T23:05:11.913Z" }, + { url = "https://files.pythonhosted.org/packages/ed/85/ea548dc013962eb73653124bc595635fbf9e0fa41d1f181a967ccb784dfb/markupsafe-3.0.4-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7a83aa6e4805df46fed18e989d3d16f86ef60cb50bbc8d9ce3a6be89165fbf6e", size = 11443, upload-time = "2026-10-02T23:05:12.887Z" }, + { url = "https://files.pythonhosted.org/packages/cc/72/15f2e5ec9cf2eb00d5cdfe968d94e4156a7bd7303832c3f3b2c403a36839/markupsafe-3.0.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2d1b7d9308288661f56672b1b157d75fc536714d3638487bbea17b6318a78248", size = 11665, upload-time = "2026-10-02T23:05:13.829Z" }, + { url = "https://files.pythonhosted.org/packages/ca/e0/4030bea613677e333c8a2c901fd405055f657f9d06acba5b7357984b6ef7/markupsafe-3.0.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:73e77980c7207854f00fc4e71fb1626868d5740ab4012623d55c7a99ad122a72", size = 12061, upload-time = "2026-10-02T23:05:14.807Z" }, + { url = "https://files.pythonhosted.org/packages/f3/a5/28b76a7449eb702966b88bef599e2360b411fbb3afeee8fe560939be06ec/markupsafe-3.0.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7018d4af1cd272e847aa5917983ab5e83e4f6579f9dbfecd4a79c0ca80b144c2", size = 24395, upload-time = "2026-10-02T23:05:15.909Z" }, + { url = "https://files.pythonhosted.org/packages/07/6c/21232811afc3a063b5e934b1ae2efda52f46154ec382f585149c020e61fe/markupsafe-3.0.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c90d5b3d4e944e065a301d741b3c1d784f6bd1f503aa68b4967e32b2ba313d85", size = 27183, upload-time = "2026-10-02T23:05:16.976Z" }, + { url = "https://files.pythonhosted.org/packages/14/38/6ccdfa5b59049cb36fb80cbc80aee9cf1fc9bb77d1335ad435f2070b08cf/markupsafe-3.0.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:18a801868a884f216e784d7d14db2a4077143ce7610440aee2ce8f734e7cfcde", size = 24772, upload-time = "2026-10-02T23:05:18.209Z" }, + { url = "https://files.pythonhosted.org/packages/63/e0/cec6865dfe88cb48fedd4b20aed6af5158e41092adcbf3e028bcc6ec2108/markupsafe-3.0.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:434139499bb20b502ed3baa1f169e618f924a97e7a777fea1a49446d80106cf6", size = 23017, upload-time = "2026-10-02T23:05:19.286Z" }, + { url = "https://files.pythonhosted.org/packages/ee/76/6ed4940bb7648a9aac457c14f870cfdd5105f139a0fb1f29cd61fafa47d1/markupsafe-3.0.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9e227f3dbe6bde7491cf0a9965d00b88c6b1a4a95d11480ddf88bb96d397c19f", size = 22036, upload-time = "2026-10-02T23:05:20.352Z" }, + { url = "https://files.pythonhosted.org/packages/a1/4f/ed476226d4fe46a09090a36025bf319296810028df55eb12f1253b540f3a/markupsafe-3.0.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b8cd1f918b26fd7b1832ece557cc18f2d8747309ff8b3f0ef9d4250c5ad67a39", size = 23786, upload-time = "2026-10-02T23:05:21.576Z" }, + { url = "https://files.pythonhosted.org/packages/9a/35/66ff30450e35ef5fba9ebc930c9411747e537fd9447b65e44f5007e2b84d/markupsafe-3.0.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:a5fcffb37e602b0b3c1638a97746b9b96125caa9bcf6fa41d337a9261de231ee", size = 22672, upload-time = "2026-10-02T23:05:22.922Z" }, + { url = "https://files.pythonhosted.org/packages/32/0b/72f45ce4b4efcbca4b80cf1b06703eff0be8d37e82abb78f66c85a7ead1e/markupsafe-3.0.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:5989cb26b2e1efc6a42216a9f6b5ee495ce5ace2e5b352a9af489976b32d1ee2", size = 24107, upload-time = "2026-10-02T23:05:24.175Z" }, + { url = "https://files.pythonhosted.org/packages/d2/03/71776e5fdcba04614b384cc102e8a4198208579d896fd1394cb7cb9aa900/markupsafe-3.0.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:add96447a86d205ab616665d53b2950ee81083757f56e6ea833c8b2917646b46", size = 21615, upload-time = "2026-10-02T23:05:25.215Z" }, + { url = "https://files.pythonhosted.org/packages/ab/5f/801ce02a02e7aee0f784b1ec7843026178f6adeb9c93ac67eb1992a9a84d/markupsafe-3.0.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2628d3a8cb648ecebb3c5d6b0a1052d400e4d8b7ac0fb786be8d285b50040d17", size = 23076, upload-time = "2026-10-02T23:05:26.423Z" }, + { url = "https://files.pythonhosted.org/packages/4a/85/c43776625428f3bb4a61e8633940400e3efe6409e3c6f5bff26de5e45618/markupsafe-3.0.4-cp313-cp313-win32.whl", hash = "sha256:672d207103e6b16ca098611b0f9efad6bc00afd47c03d6ef62186495ca677dc0", size = 14118, upload-time = "2026-10-02T23:05:27.716Z" }, + { url = "https://files.pythonhosted.org/packages/6f/36/163da64de88a13db79214ef75fa041be7fa13bdb42261cf5b7484de14bfb/markupsafe-3.0.4-cp313-cp313-win_amd64.whl", hash = "sha256:1f1f9477e174582b0a1b583d60b66e1f2cf5d3fe12cee985e4aedf44766600e5", size = 14313, upload-time = "2026-10-02T23:05:28.749Z" }, + { url = "https://files.pythonhosted.org/packages/9f/a8/9b662783ffaa1149221432a923cee562f78b9cbbb8baa3df9b3753e63e1e/markupsafe-3.0.4-cp313-cp313-win_arm64.whl", hash = "sha256:06de8ef6331f6e822c28d577dc8bf43fe398800477c49498f38fc38b67ff33fc", size = 14189, upload-time = "2026-10-02T23:05:29.917Z" }, + { url = "https://files.pythonhosted.org/packages/5c/c3/a944f3b0df22bd129e96915b9f4e98d2eeca6516687d7618304a966c3c74/markupsafe-3.0.4-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:4ed644d75aa94a2baf7ec3a96eaa160ea58c742eb9d27c6506053c5c40fc84ed", size = 12787, upload-time = "2026-10-02T23:05:30.971Z" }, + { url = "https://files.pythonhosted.org/packages/d4/d6/a44863f69d88b6c7e27889108f70d47aed259edf89d5df3c5fca1eac87d6/markupsafe-3.0.4-cp314-cp314-android_24_x86_64.whl", hash = "sha256:6d2a9efe686f9de00d0d1ea32a4a5a86d558a2277501bd78d964214eab625e59", size = 12525, upload-time = "2026-10-02T23:05:32.263Z" }, + { url = "https://files.pythonhosted.org/packages/17/8f/168ba80e532dd6a93f96f8f706f1ad41d7990b6e1aeedc1cc0d211a33497/markupsafe-3.0.4-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:8781a792a070cf2bd1b86d3aa943894115faaba6e88122a7bf32d62072742453", size = 11589, upload-time = "2026-10-02T23:05:33.251Z" }, + { url = "https://files.pythonhosted.org/packages/32/b3/aa2c95a574d3af39403a469b295886eb9b6d448da568cbebb5a2cbfdc2e5/markupsafe-3.0.4-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:971a3bbb75d97ae4e2e8f7d4834236f86f85f0c85e04ab2e191db1123b04f80b", size = 11801, upload-time = "2026-10-02T23:05:34.315Z" }, + { url = "https://files.pythonhosted.org/packages/60/d0/34b810107d83840e768bf485de795893ebbae35b26ab061b487adfa0a692/markupsafe-3.0.4-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:8909c2f1c6dd65e054ac4b573a91c8384d1492281e55d82d159d653f7a13adf6", size = 11447, upload-time = "2026-10-02T23:05:35.302Z" }, + { url = "https://files.pythonhosted.org/packages/6c/ab/2f8488f0f817a39fca068d2b17daf446bf5cdb3eae28c3720af534d873b4/markupsafe-3.0.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:4cf3468d5ec187ffffcaca8e61929a37448f215dafc1386a12c750a72fe53634", size = 11722, upload-time = "2026-10-02T23:05:36.363Z" }, + { url = "https://files.pythonhosted.org/packages/ad/40/e2d117b048d47282ade906fbfd92814cbee5647afc13fda88a3406039372/markupsafe-3.0.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:52704c5d36eb6dda8866493decd61111fff86244c9b1ad225ca01b9e91e5970f", size = 12061, upload-time = "2026-10-02T23:05:37.397Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a8/73a81135e85ba66217f5af7facb03bbb386807e1a729ab64532e4c802652/markupsafe-3.0.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1caa2fa5a6184fb233153b35f654e6687bd555476f6170f29d8ee9be1a8b0af9", size = 24434, upload-time = "2026-10-02T23:05:38.407Z" }, + { url = "https://files.pythonhosted.org/packages/ac/ca/fa9216dd01efee2dfdacafe7df32b4d0170fbac694b0c258a193d6e53999/markupsafe-3.0.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:387d8cd30e69b3f0a72877b9ae717033396404e19095b17fe89753a981fda44f", size = 27183, upload-time = "2026-10-02T23:05:39.581Z" }, + { url = "https://files.pythonhosted.org/packages/fa/4e/a469509e538d37af51103b17b073126973f2b1cbf197ff32c7ddf025cfe5/markupsafe-3.0.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:051417f74bcaaefa316276e0ff723f541616ca51043d070da00249d9bddd3e3c", size = 24813, upload-time = "2026-10-02T23:05:40.671Z" }, + { url = "https://files.pythonhosted.org/packages/8f/db/d7282caf7ab03af44d5d6fdbaa019b35c7d7f1c90588b839c07cba640d6a/markupsafe-3.0.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8e9f292fcda89b324f2f5c91d13f1424a153e40fc2756f38ee23b15835ff300", size = 23049, upload-time = "2026-10-02T23:05:41.864Z" }, + { url = "https://files.pythonhosted.org/packages/30/f3/b6a425206e6964efda6acee544d0eb01d1501784d0b8e2dcc74986f33b17/markupsafe-3.0.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:df1ae86ff54725a01fa1a0510b914ca53a161b7050be74f6204e24aded5971d0", size = 22088, upload-time = "2026-10-02T23:05:43.014Z" }, + { url = "https://files.pythonhosted.org/packages/ea/8a/84d3582fc1f0d5bd466cdf2eebf175e172158a6e70701aacec1de1b35430/markupsafe-3.0.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8965520ac587c94a4ac48b729be3d8b8de00af39699b17585dfb599babe77977", size = 23846, upload-time = "2026-10-02T23:05:44.098Z" }, + { url = "https://files.pythonhosted.org/packages/1c/65/db101cce51b7ba4864ac491a9859d297dd1adf0e55b103fee9db9c47c527/markupsafe-3.0.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:340cbb1957ba99929cbf19a75626d36ba1ae21d1730b287d1cf7f824a20c4fc7", size = 22674, upload-time = "2026-10-02T23:05:45.23Z" }, + { url = "https://files.pythonhosted.org/packages/e0/49/ddee9813d71db0c7a5c9d97c832125e6758a0c844777f1cf076569bb0e22/markupsafe-3.0.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:3a93d9616ddecfb393727a0041a562cf0b15a244e20f2bd25efc7949be4c4f17", size = 24104, upload-time = "2026-10-02T23:05:46.398Z" }, + { url = "https://files.pythonhosted.org/packages/aa/0e/7d8518d726726870a2399d69fd30d0fa36c5e57a2132c336b58d7c491073/markupsafe-3.0.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:d2e56fd3b00222722abfb3f5f0759ddbae4b90811b5ad4343c64030ad1bde70c", size = 21637, upload-time = "2026-10-02T23:05:47.48Z" }, + { url = "https://files.pythonhosted.org/packages/b4/b0/b505e8a361ba557dbf3b3aa7331ea39b00d2022a26e925ff8463b9714bb3/markupsafe-3.0.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:0d9c47709875fdb321452056622e930c52afbc07a7d780762fbb8b4d91ce6fa4", size = 23081, upload-time = "2026-10-02T23:05:48.611Z" }, + { url = "https://files.pythonhosted.org/packages/1c/ea/9cc3cea873f980c75cbdb6f4277ce30ee955de38be0b3d02f14c108e0698/markupsafe-3.0.4-cp314-cp314-win32.whl", hash = "sha256:38fc55594dab834470b6733dead2ee9e3f657fb0608c769dcafa0ba5ab52f45c", size = 14272, upload-time = "2026-10-02T23:05:49.707Z" }, + { url = "https://files.pythonhosted.org/packages/80/f0/5792ff768a410f93ee3f84fc19345295ffc352d2c936b424cb37e514714c/markupsafe-3.0.4-cp314-cp314-win_amd64.whl", hash = "sha256:c1bc67752d5f21013cfe430df4062441714eab79f65a6a05e01505957e9c35fe", size = 14501, upload-time = "2026-10-02T23:05:50.788Z" }, + { url = "https://files.pythonhosted.org/packages/5f/cf/3d074a8edffcc6899355232ff2543ae8d929733239596423b7db79698bc9/markupsafe-3.0.4-cp314-cp314-win_arm64.whl", hash = "sha256:7e1636da3d8dfc220b6dd10264db5f2b165e4888c4518594898fbe381049af8a", size = 14364, upload-time = "2026-10-02T23:05:51.857Z" }, + { url = "https://files.pythonhosted.org/packages/d9/31/87ce42159aae2163cf3bbbd0c44bc87780510eecab1ea3859099aed95dcb/markupsafe-3.0.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:805c8b84534fa10891890f0e4be39f3a99e94615d93e8836bf9fa1fdca2feeb2", size = 11759, upload-time = "2026-10-02T23:05:52.951Z" }, + { url = "https://files.pythonhosted.org/packages/5f/53/b047207eeb7752e960aca3eb1df5fb7eefa7dd4c62ac49bb156456c8a702/markupsafe-3.0.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:fa95848c929b6a75f6848d3c9793e59db365ee436776e57db835cdbfa79ba977", size = 12096, upload-time = "2026-10-02T23:05:54.066Z" }, + { url = "https://files.pythonhosted.org/packages/ee/51/4326c88a13c7b755657d44b4bb986f8c3d9843ecba7e22d98661d87f9a57/markupsafe-3.0.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e916035e3e9930cbdfdd10abf48861340221857f45509565898e012263f7b289", size = 25699, upload-time = "2026-10-02T23:05:55.15Z" }, + { url = "https://files.pythonhosted.org/packages/f2/bb/990581b7474bfcf2cf34bed6ba5ea23bd87adb9d671213d68e88620e7a6b/markupsafe-3.0.4-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b4d12837e0203bbace818ff4a7461afdcd78bcd782351cea148139180d7bcffe", size = 27804, upload-time = "2026-10-02T23:05:56.29Z" }, + { url = "https://files.pythonhosted.org/packages/6b/89/89491878c28e8291f5aa2fffe2c2d57230d10ae366d55dd810b840513d78/markupsafe-3.0.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5086f9975abb1ab531ee6afca1761e4b59a19b446f3f6522ed776963228cfe5a", size = 25912, upload-time = "2026-10-02T23:05:57.416Z" }, + { url = "https://files.pythonhosted.org/packages/30/77/680998b54efdea06fc114565cd739b6d059f826a0279219b218dfa750d29/markupsafe-3.0.4-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b4a635a0487774f841cb1fb62e907e7195cc95bc761e053184b8acc3ceb20733", size = 23623, upload-time = "2026-10-02T23:05:58.557Z" }, + { url = "https://files.pythonhosted.org/packages/ae/75/2709f5ac5de9467b40b10e2bb8f89cc63dfb74582e09aa734b1124a217de/markupsafe-3.0.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb96e6e088d6cf71c1ea977510948320234824cf226e32f6f6e044f7a9c82b34", size = 23301, upload-time = "2026-10-02T23:05:59.94Z" }, + { url = "https://files.pythonhosted.org/packages/a0/c8/39eadc6c5b14c9c7679bfb98f4d4c6a97863b5beb91839aca4d2d6e16e55/markupsafe-3.0.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8b5d563170ff8ba3181caa967c99a3c804d1dedb702c7cb93a6a7c32247da978", size = 24950, upload-time = "2026-10-02T23:06:01.289Z" }, + { url = "https://files.pythonhosted.org/packages/1a/5e/01037f8a43e8ccb0bffb4fbdc5212db05bf080fdd7286cd392332d58128a/markupsafe-3.0.4-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:396ec4e65cc889f69786b3b89478b471cee5a3bcf468b9d9bb03e1a30fb291fc", size = 23330, upload-time = "2026-10-02T23:06:02.441Z" }, + { url = "https://files.pythonhosted.org/packages/d4/f4/23e83ce0596bb0cbe670502d31df8f757bbd01a392aa486fa3b40d1ed399/markupsafe-3.0.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:15ba9e28640feef770374b116a6f019c21f52404aeabe516aa7f800587b98cfc", size = 25239, upload-time = "2026-10-02T23:06:03.579Z" }, + { url = "https://files.pythonhosted.org/packages/88/5b/3708897368073cc683d524750474f41a77d2986152c380dcc55b20fdf340/markupsafe-3.0.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:d920abdfa61279ba1a2ef9484aab07bf03331f8c08a10120fa332353d06e6932", size = 22767, upload-time = "2026-10-02T23:06:04.699Z" }, + { url = "https://files.pythonhosted.org/packages/c6/61/ebda1307864b409e6b3115757a3d4a09cca46cfb6cc65191b5de226b424b/markupsafe-3.0.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a9f54054101545a9a9cccefddf54316aa6e4491611fcbef9e91b3b6bebec04f6", size = 23668, upload-time = "2026-10-02T23:06:05.9Z" }, + { url = "https://files.pythonhosted.org/packages/09/15/98075cceac3b5ba0dbb8e4762a847be967d2befc349a2cf2d0ac77f62c9d/markupsafe-3.0.4-cp314-cp314t-win32.whl", hash = "sha256:12a606a492de952afcb43b59a14aaaaad120e708d3663dd0fdf2d738d427a691", size = 14301, upload-time = "2026-10-02T23:06:07.109Z" }, + { url = "https://files.pythonhosted.org/packages/0b/a3/768b560fcc4156685cb563d922b217810cfa7bc135773367f62f1f9d2078/markupsafe-3.0.4-cp314-cp314t-win_amd64.whl", hash = "sha256:a18f38cafc329bac5e3c2b96c765b4c96d3d103421ed22ab7988c1e3fce27464", size = 14526, upload-time = "2026-10-02T23:06:08.276Z" }, + { url = "https://files.pythonhosted.org/packages/93/63/da554b4c97a6b0ea3229ca7fe8cbfb620be81613d517f482e85958550537/markupsafe-3.0.4-cp314-cp314t-win_arm64.whl", hash = "sha256:eba154571c16e032112afac0dc2dfe9e63c2ceb7aedd07bb7eecf2ce26d4dd4c", size = 14421, upload-time = "2026-10-02T23:06:09.402Z" }, + { url = "https://files.pythonhosted.org/packages/a9/30/54d11c8ca027114898cab97421fb39e4ffd9ddf47cdbc44df2ec76722da9/markupsafe-3.0.4-cp315-cp315-android_24_arm64_v8a.whl", hash = "sha256:737c9c3981998eba27f11786f84fddcbabc74068b72a4a1f454ea02094b57b65", size = 12791, upload-time = "2026-10-02T23:06:10.485Z" }, + { url = "https://files.pythonhosted.org/packages/10/6d/97c913e253a14bd3cd0e15a5c56d13203b823fa7ee32498342896a072dc4/markupsafe-3.0.4-cp315-cp315-android_24_x86_64.whl", hash = "sha256:489505b03f692c3f376394e49194fa7a7f9e8558d6e293a7056a0032b0c38163", size = 12527, upload-time = "2026-10-02T23:06:11.834Z" }, + { url = "https://files.pythonhosted.org/packages/26/f9/b86d032042a4d597d9e1997f0e5f63a3eedaf11258e0a05760b0a0a826ea/markupsafe-3.0.4-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:077293e425f28ec737dbcad442a71752e28f8ae27cde3d68acd1fb212091cd92", size = 11602, upload-time = "2026-10-02T23:06:13.122Z" }, + { url = "https://files.pythonhosted.org/packages/f2/dc/73c14c1eedf0ac5fa3292ba43435e6c49d2c2050f33cebde541f8f4807f1/markupsafe-3.0.4-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:9348cbb300d224fe3b89793262cb093504d4ae927004468463f745188a193e4a", size = 11817, upload-time = "2026-10-02T23:06:14.227Z" }, + { url = "https://files.pythonhosted.org/packages/8f/69/2c2fcaa5fcee22d72c7819c0d536fd181c74a688e6143845419579cd2863/markupsafe-3.0.4-cp315-cp315-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:b807e598953730f82e4eae3bd30f6a122cf6b31c398c6b504c0e04c13c170429", size = 11446, upload-time = "2026-10-02T23:06:15.574Z" }, + { url = "https://files.pythonhosted.org/packages/88/54/9e5ec76c62e6e2834d5a93623018c943e8b3bb41d663e3fd4c03303b9b85/markupsafe-3.0.4-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:799c39bdf5e2f1292fedd3009f7b3c9e760f10b2420cb9638d56920840ff6db8", size = 11719, upload-time = "2026-10-02T23:06:16.701Z" }, + { url = "https://files.pythonhosted.org/packages/96/24/3ec292b44064c16229e064d770b2625bd8ea941aa61f44905a9fa44942c0/markupsafe-3.0.4-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:ae9dcb8fbe244cb82f8a6458b455b927a03685e383d9bacf1ea5ce180b96dc97", size = 12075, upload-time = "2026-10-02T23:06:17.855Z" }, + { url = "https://files.pythonhosted.org/packages/aa/85/b64fdb1f304848518742136983c24e96d967bfb59a0ea160e92736901ab0/markupsafe-3.0.4-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4bced6e2a6dba6a28f7dd3c6ce14df1b2dd495923f16ea484cad03decd463b2b", size = 24656, upload-time = "2026-10-02T23:06:18.963Z" }, + { url = "https://files.pythonhosted.org/packages/9c/18/23997d4c65b355da6390d61cd56e0ab3befd6ba8dda25cb40c602bd0fa6b/markupsafe-3.0.4-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3882fb412298575bae3b9c46868251f15cc69307359f87bb1b382e53d6e5a2c9", size = 27737, upload-time = "2026-10-02T23:06:20.117Z" }, + { url = "https://files.pythonhosted.org/packages/d4/36/35998dead3c6af88c38265a56e58100211f036234ab88eb2283fd4cbce44/markupsafe-3.0.4-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:04e7902ba80ee4bac1d50a549606527a1dcf0476cd81403db41099d3b60ec653", size = 25003, upload-time = "2026-10-02T23:06:21.284Z" }, + { url = "https://files.pythonhosted.org/packages/82/96/ef49135ce260db4ca4a12b119ed468449cd248db6b1468e2112b546d7a2e/markupsafe-3.0.4-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:925f929d6b59a8b3f8b8c6ac363cd0af7eecc81efb3071770b3c6717c450a369", size = 23111, upload-time = "2026-10-02T23:06:22.524Z" }, + { url = "https://files.pythonhosted.org/packages/50/7d/83126e338bd88c17a220668235368ad719fd4638e426739858cbb8508f77/markupsafe-3.0.4-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f68edfc67aabac33708941f26f22a7b8e9f81429bc0cf249fcf7d66b23af8d19", size = 22403, upload-time = "2026-10-02T23:06:23.785Z" }, + { url = "https://files.pythonhosted.org/packages/83/dd/daf7e420de23c8206c365204e7b85e1251d8e19d34196a56336f316e5ed2/markupsafe-3.0.4-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:e5c802729725bd07e2bc3ab7b76dc7e0bbfc53129d8f1eb1c002c24cf774717e", size = 24083, upload-time = "2026-10-02T23:06:25.037Z" }, + { url = "https://files.pythonhosted.org/packages/19/3c/11eecdc06bc44ad5570350085b572ebf049e8f9a38d1ece6d76640b739cd/markupsafe-3.0.4-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:55ffd6ce583d97dc71dc92e930324c8c0d25aea7e3ade6ae54ef77cedb096811", size = 22931, upload-time = "2026-10-02T23:06:26.328Z" }, + { url = "https://files.pythonhosted.org/packages/0d/9e/ac0fd77f2a726e56ecc3ca0235d095feace1358d1b822406c2a2ef26a4dc/markupsafe-3.0.4-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:2cb3dd71fc6be918ad4264346a8ed69485f9b7ed7bf35495d8e22807cd6b8bea", size = 24299, upload-time = "2026-10-02T23:06:27.742Z" }, + { url = "https://files.pythonhosted.org/packages/d7/09/c6bd842ad58ff5b3bc76eeed7e9a42a6f11adc5d090ec697b72c9672731e/markupsafe-3.0.4-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:94f5407f7bc64fa6463906b896f9904beeeb7dd8dc116ee8e9056c8714ff9916", size = 21948, upload-time = "2026-10-02T23:06:29.274Z" }, + { url = "https://files.pythonhosted.org/packages/a3/46/82f586711fed61e86faa1ee1bc317d68cd45a10c8bdbe3f7d1fdf9026ad8/markupsafe-3.0.4-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:2dad610540cb2e6272855c178f08ae9a1c7ac258a7fb71660553a5f104b42741", size = 23150, upload-time = "2026-10-02T23:06:30.583Z" }, + { url = "https://files.pythonhosted.org/packages/19/2d/2dfdce99318abbfa26925195fbc17db188c46a1ec6457be121b6f9cfeb42/markupsafe-3.0.4-cp315-cp315-win32.whl", hash = "sha256:03470d1a8268e692ecf79ecd565593e59d44219377a7ead61f1f1b94c1f7ff6b", size = 14269, upload-time = "2026-10-02T23:06:31.949Z" }, + { url = "https://files.pythonhosted.org/packages/5b/ec/6000fd82e8791e58fcd0456ec20f098957e2b03d5ed02eb73241a577c0ba/markupsafe-3.0.4-cp315-cp315-win_amd64.whl", hash = "sha256:d882a373d8093c2941e01291b7ced96e9cbe4781da9a7751ca7e6c70385e5214", size = 14496, upload-time = "2026-10-02T23:06:33.258Z" }, + { url = "https://files.pythonhosted.org/packages/bc/66/e73bd5016421d5d6e2fb6de7dd609f9de020942ac8c626526bd8c6eeaf82/markupsafe-3.0.4-cp315-cp315-win_arm64.whl", hash = "sha256:353bd63081912ab8cfa6a0c7d185934cdf8426f04c618bba6bc4b394f2069b67", size = 14361, upload-time = "2026-10-02T23:06:34.539Z" }, + { url = "https://files.pythonhosted.org/packages/90/df/cb8c3dc98d313a951df2f8968f44e4cb5643df6d3cab749a530ce2f7d972/markupsafe-3.0.4-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:c61750fadcd119d0825bcb7d7d675dd264dcc89cc05292aab5be68ebdbb374ad", size = 11760, upload-time = "2026-10-02T23:06:35.807Z" }, + { url = "https://files.pythonhosted.org/packages/d6/bb/4af9b3ca0753d654ac75f9531d5bd741bb77ca6e696f36807c475ffc099a/markupsafe-3.0.4-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:1c0df495a977d10460a94941799c72d5b5ab03d3858d949b55b5a66c8f371c99", size = 12108, upload-time = "2026-10-02T23:06:37.089Z" }, + { url = "https://files.pythonhosted.org/packages/3f/d4/b56429313aee5fd59b079c3df5615299959e25e7113eb6d8caadbdd7d38a/markupsafe-3.0.4-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:02fa4acbc6a3fc5c693c34d4dd8c1130b7fe99cc915181b0ddd6f72aeb296002", size = 25762, upload-time = "2026-10-02T23:06:38.419Z" }, + { url = "https://files.pythonhosted.org/packages/65/f5/34c181e891aa4f7d59c918584672e0c5eb7fffe76c1387d1246008bf4081/markupsafe-3.0.4-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:05295589e619b9bed252a86b532b8e27350abc372d18ba89b59375325e91ec1e", size = 28400, upload-time = "2026-10-02T23:06:39.819Z" }, + { url = "https://files.pythonhosted.org/packages/ce/b5/ad14694fd0ac9a5ce30bc6498f2999378f418583dd1679cca5a1b512957e/markupsafe-3.0.4-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:be6cb0c799abb0e2ba3e618e6d28ddddf7e485f6c2ce938dfa237daf3905072c", size = 25946, upload-time = "2026-10-02T23:06:41.381Z" }, + { url = "https://files.pythonhosted.org/packages/d6/a8/26b606445387d0ceb1eb1f21840094b84e4e3c3c3983d80d10b89823b490/markupsafe-3.0.4-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:26e9867520db70d37f7fb421a7f0d8adb40171011fb84ce869afa1a83370dfa8", size = 23634, upload-time = "2026-10-02T23:06:42.748Z" }, + { url = "https://files.pythonhosted.org/packages/39/a2/b8814de672f1f0094d498bf646f2fec9d6356b503d28ef500b71c5095377/markupsafe-3.0.4-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f03460ff076f70ab595bb45a0205ccea1971443575b6920c52e755dec2b3fbfe", size = 23488, upload-time = "2026-10-02T23:06:44.176Z" }, + { url = "https://files.pythonhosted.org/packages/db/c7/287223376fb73335a3cc5d6eb22c6ab01358cf33945a9c39c06b9dac3f4b/markupsafe-3.0.4-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:436e3ffc6310d3c41878c601db29098102fe5d8a467c49da4a4125254e0980f2", size = 25037, upload-time = "2026-10-02T23:06:45.646Z" }, + { url = "https://files.pythonhosted.org/packages/f9/29/4df8355e313426d19e62ba33e0253c009ca12a0894ee77d67fa67255361c/markupsafe-3.0.4-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:4e2c4809c14559aa7ef426f27fb35afbb38104c349a903bf8f3600456764bb38", size = 23543, upload-time = "2026-10-02T23:06:47.264Z" }, + { url = "https://files.pythonhosted.org/packages/71/e5/8377731e8495668dcc768f645e717df18318c841edaf023a99395f6da9b4/markupsafe-3.0.4-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:da2af0d7aebfc2074080d72efa6ab8317c62481ef1f896f65d9999c1c01f4494", size = 25282, upload-time = "2026-10-02T23:06:48.795Z" }, + { url = "https://files.pythonhosted.org/packages/ed/5f/373456e37ceb1478d657d6fe769cbe0a39f0a8dfc1548eeb19c471eefdd9/markupsafe-3.0.4-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:aa2c838cc024642cc04c6854232f32b43e5e22833dd11119c1766c7873b8370d", size = 22993, upload-time = "2026-10-02T23:06:50.31Z" }, + { url = "https://files.pythonhosted.org/packages/d7/93/2cbd5628435afb6f541bbaced4bce0c2edac4b09a142e6e928b8b0da9858/markupsafe-3.0.4-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:b91cc9d336957239ff200f30097e6fea2dc6d6fb3c81e853eaa09eac904fd894", size = 23712, upload-time = "2026-10-02T23:06:51.759Z" }, + { url = "https://files.pythonhosted.org/packages/81/99/157e10966b033b363aeda5263e82596ee232a0b1d082fdbf90aa417ff083/markupsafe-3.0.4-cp315-cp315t-win32.whl", hash = "sha256:e49fb0d1ce92cfa0cb198cc5b1b11cdf9d0638658e2a2db2687e39db7c87fc78", size = 14300, upload-time = "2026-10-02T23:06:53.241Z" }, + { url = "https://files.pythonhosted.org/packages/33/05/55884815414c9706a23deca150b72c25a62109e65b0b6ce232077802c719/markupsafe-3.0.4-cp315-cp315t-win_amd64.whl", hash = "sha256:4f6e0852a0283b1b1fd776eeb7b766a5f440b3e2bd31ab51af3b400585f3965c", size = 14522, upload-time = "2026-10-02T23:06:54.729Z" }, + { url = "https://files.pythonhosted.org/packages/92/f9/ecbde7149e95b8a0f18e16d5d747f7dc06049d5da2e4f77f6f5e4a1f46a8/markupsafe-3.0.4-cp315-cp315t-win_arm64.whl", hash = "sha256:39dbacefc411633db5b4378b066a9aca70a3d7e2922c9e578d825f844026eeba", size = 14417, upload-time = "2026-10-02T23:06:56.246Z" }, +] + +[[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", version = "3.10.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "markdown", version = "3.11.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { 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", version = "3.10.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "markdown", version = "3.11.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { 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", version = "4.12.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "platformdirs", version = "4.13.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { 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.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "babel" }, + { name = "backrefs" }, + { name = "colorama" }, + { name = "jinja2" }, + { name = "markdown", version = "3.10.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "markdown", version = "3.11.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "mkdocs" }, + { name = "mkdocs-material-extensions" }, + { name = "paginate" }, + { name = "pygments" }, + { name = "pymdown-extensions" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f1/cd/c05d3a530ba7934f144fb45f7203cd236adc25c7bdcc34673d202f4b0278/mkdocs_material-9.7.7.tar.gz", hash = "sha256:c0649c065b1b0512d60aad8c10f947f8e455284475239b364b610f2deb4d0855", size = 4097923, upload-time = "2026-07-17T16:21:33.156Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ad/21/17c1bc9e6f47c972ad66fb2ac2568f99f90f1207eeb6fc3b34d094dba7b5/mkdocs_material-9.7.7-py3-none-any.whl", hash = "sha256:8ea9bb1737a5b524a5f9dcf2e1b4ebda8274ae3008aa7845720a97083bef708f", size = 9305438, upload-time = "2026-07-17T16:21:30.017Z" }, +] + +[package.optional-dependencies] +imaging = [ + { name = "cairosvg" }, + { name = "pillow", version = "12.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "pillow", version = "13.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, +] + +[[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.6" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] +dependencies = [ + { name = "jinja2" }, + { name = "markdown", version = "3.10.3", source = { registry = "https://pypi.org/simple" } }, + { name = "markupsafe" }, + { name = "mkdocs" }, + { name = "mkdocs-autorefs" }, + { name = "pymdown-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/53/71/f85bdf13355073ae15a7375f09879375a830553552e58c1c4b7e0bbc5c8b/mkdocstrings-1.0.6.tar.gz", hash = "sha256:a0b8c2bdd29a6416c80d717aa369bbf7831946bd9f23c2a66db1b1dbe7693dbd", size = 100649, upload-time = "2026-07-11T19:38:05.732Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/5b/4c1902e8bdd5c4db63284e9d101dece4038d4025d6d88850ffe0a1578980/mkdocstrings-1.0.6-py3-none-any.whl", hash = "sha256:2703708697487d1b6d6d7b412e176fa436edf120c1bf81dc9e126b12d00893c7", size = 35787, upload-time = "2026-07-11T19:38:04.417Z" }, +] + +[package.optional-dependencies] +python = [ + { name = "mkdocstrings-python", version = "2.0.9", source = { registry = "https://pypi.org/simple" } }, +] + +[[package]] +name = "mkdocstrings" +version = "1.0.8" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.15'", + "python_full_version >= '3.11' and python_full_version < '3.15'", +] +dependencies = [ + { name = "jinja2" }, + { name = "markdown", version = "3.11.2", source = { registry = "https://pypi.org/simple" } }, + { name = "markupsafe" }, + { name = "mkdocs" }, + { name = "mkdocs-autorefs" }, + { name = "pymdown-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/27/cc/e3ed8b16851f5d664dffcf8f55fc60d0d3f736a3edca21d1508105d1255a/mkdocstrings-1.0.8.tar.gz", hash = "sha256:b50fc326230906425c82ee9ec59b80e5db00892b2b593d4d0b841a0d4acf537b", size = 107444, upload-time = "2026-10-19T15:43:02.157Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/19/5e/4df7a2290e97c60a3ba410084966e5ab84aa89d15c8c98c195acbaefa8f4/mkdocstrings-1.0.8-py3-none-any.whl", hash = "sha256:4b03ed2b863009f1153f0d04aacb22a85b92afc28a0636d85717c92eecca638c", size = 42209, upload-time = "2026-10-19T15:43:00.65Z" }, +] + +[package.optional-dependencies] +python = [ + { name = "mkdocstrings-python", version = "2.0.10", source = { registry = "https://pypi.org/simple" } }, +] + +[[package]] +name = "mkdocstrings-python" +version = "2.0.9" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] +dependencies = [ + { name = "griffelib", version = "2.3.0", source = { registry = "https://pypi.org/simple" } }, + { name = "mkdocs-autorefs" }, + { name = "mkdocstrings", version = "1.0.6", source = { registry = "https://pypi.org/simple" } }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/96/11/640067d1ad713ea99c233e53e57a4c300d9885f904a61371d7ef90dea549/mkdocstrings_python-2.0.9.tar.gz", hash = "sha256:ae945637dc0618c6beedbee169f10c0234b77f322c53db3fc9fb4c29b3013038", size = 203006, upload-time = "2026-09-22T13:43:27.712Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/0f/f7f926cfa06317bbdbd3cf0ff82f9e3a91767352eb01519c81499fddf575/mkdocstrings_python-2.0.9-py3-none-any.whl", hash = "sha256:c0233eff3f84d78110df50541918e7ec2bcff8e1614faddea34290a90321a416", size = 105698, upload-time = "2026-09-22T13:43:26.345Z" }, +] + +[[package]] +name = "mkdocstrings-python" +version = "2.0.10" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.15'", + "python_full_version >= '3.11' and python_full_version < '3.15'", +] +dependencies = [ + { name = "griffelib", version = "2.4.0", source = { registry = "https://pypi.org/simple" } }, + { name = "mkdocs-autorefs" }, + { name = "mkdocstrings", version = "1.0.8", source = { registry = "https://pypi.org/simple" } }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fb/43/4783d5606de4f5e4bea10388c8741b0c40d03e7cb9527b94ad35966351f5/mkdocstrings_python-2.0.10.tar.gz", hash = "sha256:5e34ae56b2f20a57807ee479d603ddc5ec7cc6d2252c4c177754627ef2d3b833", size = 207682, upload-time = "2026-10-19T15:58:07.934Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/be/1b/fc924a97a237adda47f15c1b0cc271639e6b181ab3f95500fbf060c79a69/mkdocstrings_python-2.0.10-py3-none-any.whl", hash = "sha256:4a3aaeebb25ba5ae57a8f9e75432fe4571984889602f2b2f7d672faa760e9062", size = 105538, upload-time = "2026-10-19T15:58:06.287Z" }, +] + [[package]] name = "mypy" version = "2.4.0" @@ -595,6 +1319,11 @@ dev = [ { name = "ruff" }, { name = "trio" }, ] +docs = [ + { name = "mkdocs-material", extra = ["imaging"] }, + { name = "mkdocstrings", version = "1.0.6", source = { registry = "https://pypi.org/simple" }, extra = ["python"], marker = "python_full_version < '3.11'" }, + { name = "mkdocstrings", version = "1.0.8", source = { registry = "https://pypi.org/simple" }, extra = ["python"], marker = "python_full_version >= '3.11'" }, +] [package.metadata] requires-dist = [ @@ -614,6 +1343,10 @@ dev = [ { name = "ruff", specifier = ">=0.14" }, { name = "trio", specifier = ">=0.31" }, ] +docs = [ + { name = "mkdocs-material", extras = ["imaging"], specifier = ">=9.6" }, + { name = "mkdocstrings", extras = ["python"], specifier = ">=0.30" }, +] [[package]] name = "outcome" @@ -636,6 +1369,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/63/34/ba1c580383c9eada3711951fef0795c80b829a078d72188184bcab9dd527/packaging-26.3-py3-none-any.whl", hash = "sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c", size = 129956, upload-time = "2026-08-04T18:15:27.159Z" }, ] +[[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]] name = "pathspec" version = "1.1.1" @@ -645,6 +1387,222 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl", hash = "sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189", size = 57328, upload-time = "2026-04-27T01:46:07.06Z" }, ] +[[package]] +name = "pillow" +version = "12.3.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] +sdist = { url = "https://files.pythonhosted.org/packages/1c/3d/bb7fca845737cf9d7dbde16ed1843984665ff2e0a518f5db43e77ec540b9/pillow-12.3.0.tar.gz", hash = "sha256:3b8182a766685eaa002637e28b4ec8d6b18819a0c71f579bf0dbaa5830297cce", size = 47025035, upload-time = "2026-07-01T11:56:38.965Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/25/c2/669d88644cddb1485bd9534e63e8cf476c8e51cb3c3a1297677023505c0e/pillow-12.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:6c0016e7b354317c4e9e525b937ac8596c38d2d232b419529b9cd7a1cd46e39a", size = 5392418, upload-time = "2026-07-01T11:53:27.808Z" }, + { url = "https://files.pythonhosted.org/packages/6b/ba/3762f376a2948e3036488d773a146e0ae6ecc2ca03ac20e2615bd0b2ba02/pillow-12.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bcc33feacfaefce60c12fd500a277533bdc02b10a19f7f6d348763d8140bbba7", size = 4785287, upload-time = "2026-07-01T11:53:29.761Z" }, + { url = "https://files.pythonhosted.org/packages/07/50/b5d688cc9c52d4482f3d5bcab6ce20bc2a74a85d2343841c907444a3be2c/pillow-12.3.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5594fc43d548a7ed94949d139aa1341b270f1863f11cfd37f5a6c8b778a6b67f", size = 6253754, upload-time = "2026-07-01T11:53:32.298Z" }, + { url = "https://files.pythonhosted.org/packages/4e/89/36f4cd76cf4baf05c50ababb976249153f18c959171c7f6ba09a6f217260/pillow-12.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f0606c8bf2cdefea14a43530f7657cbbb7ecf1c4222512492ef4a4434a9501ec", size = 6925605, upload-time = "2026-07-01T11:53:34.487Z" }, + { url = "https://files.pythonhosted.org/packages/eb/c0/4de58cf6633b9e3a6061ef4be6fb91fc3c90b812ece886f531e3c523d777/pillow-12.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:85f998ea1848bc6757289e739cfbdda3a04adfd58b02fc018ce54d754a5ce468", size = 6327788, upload-time = "2026-07-01T11:53:36.433Z" }, + { url = "https://files.pythonhosted.org/packages/87/3c/14d53682a19550dbbaf3b598f807d5457646c510805a44c7d7891cd1cd1a/pillow-12.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:25b9b82bb22e6e2b3cd07b39c68b7b862001226cb3dff7130d1cb914121b39ed", size = 7036288, upload-time = "2026-07-01T11:53:38.712Z" }, + { url = "https://files.pythonhosted.org/packages/38/1d/36279e3c77efe034e4cc2b0393ee74ffdb5a62391dacbf9b916154f5f0b8/pillow-12.3.0-cp310-cp310-win32.whl", hash = "sha256:37dc8f7bbb66efe481bb60defacef820c950c24713fb44962ed6aa2a50966de1", size = 6472396, upload-time = "2026-07-01T11:53:40.781Z" }, + { url = "https://files.pythonhosted.org/packages/48/7c/8fa0039574c476d7c6fa57dd7c32a130436877c6ec1e5ce1cc8ec44878c1/pillow-12.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:300557495eb45ebb8aec96c2da9c4be642fbf7cd937278b4013ba894ea8eb0eb", size = 7226887, upload-time = "2026-07-01T11:53:42.764Z" }, + { url = "https://files.pythonhosted.org/packages/fa/17/e324be141d173c1c919428066c3259f21c1b8982e564e01a4a81e96dbdcf/pillow-12.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:514435a37670e3e5e08f3945b68718b6ed329bb84367777e16f9f4dfe1e61a0f", size = 2568039, upload-time = "2026-07-01T11:53:45.372Z" }, + { url = "https://files.pythonhosted.org/packages/fb/c8/0a78b0e02d7ac54bc03e5321c9220da52f0c2ea83b21f7c40e7f3169c502/pillow-12.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:00808c5e14ef63ac5161091d242999076604ff74b883423a11e5d7bbb38bf756", size = 5392415, upload-time = "2026-07-01T11:53:47.162Z" }, + { url = "https://files.pythonhosted.org/packages/b2/5b/a02d30018abd97ced9f5a6c63d28597694a00d066516b9c1c6de45859fc9/pillow-12.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:37d6d0a00072fd2948eb22bce7e1475f34569d90c87c59f7a2ec59541b77f7a6", size = 4785266, upload-time = "2026-07-01T11:53:49.079Z" }, + { url = "https://files.pythonhosted.org/packages/c8/98/766667a4be768150a202836acd9fad19c06824ca86c4286d3cf6b274964e/pillow-12.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bcb46e2f9feff8d06323983bd83ed00c201fdcab3d74973e7072a889b3979fcd", size = 6263814, upload-time = "2026-07-01T11:53:51.32Z" }, + { url = "https://files.pythonhosted.org/packages/3b/2d/ede717bc1144f63886c21fd349bb95860b0d1a21149ff16f2bb362b612b6/pillow-12.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23d27a3e0307ec2244cc51e7287b919aa68d097504ebe19df4e76a98a3eea5bd", size = 6934408, upload-time = "2026-07-01T11:53:53.487Z" }, + { url = "https://files.pythonhosted.org/packages/a3/48/9c58b685e69d49c31af6c8eb9012055fab7e665785165c84796e2c73ce72/pillow-12.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4f883547d4b7f0495ebe7056b0cc2aea76094e7a4abc8e933540f3271df27d9c", size = 6337160, upload-time = "2026-07-01T11:53:55.457Z" }, + { url = "https://files.pythonhosted.org/packages/ff/fa/dc2a5c0ba6df93f67c31d34b808b7ce440b40cdbf96f0b81cde1d1e6fa93/pillow-12.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:236ff70b9312fb68943c703aa842ca6a758abfa45ac187a5e7c1452e96ef72b5", size = 7045172, upload-time = "2026-07-01T11:53:57.736Z" }, + { url = "https://files.pythonhosted.org/packages/86/a5/444817a4d4c4c2417df00513086ca196f388d8f9ef40c2e4ccd1ad1af54b/pillow-12.3.0-cp311-cp311-win32.whl", hash = "sha256:10e41f0fbf1eec8cfd234b8fe17a4caac7c9d0db4c204d3c173a8f9f6ef3232b", size = 6472232, upload-time = "2026-07-01T11:53:59.767Z" }, + { url = "https://files.pythonhosted.org/packages/63/c6/4bad1b18d132a50b27e1365e1ab163616f7a5bb56d330f66f9d1d9d4f9d4/pillow-12.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:8e95e1385e4998ae9694eeaa4730ba5457ff61185b3a55e2e7bea0880aef452a", size = 7233653, upload-time = "2026-07-01T11:54:02.066Z" }, + { url = "https://files.pythonhosted.org/packages/fd/16/00f91ab7760dc842f5aad55217e80fc4a7067a0604535249bc8a2d6d9870/pillow-12.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:ebaea975e03d3141d9d3a507df75c9b3ec90fa9d2ffd07567b3a978d9d790b26", size = 2568195, upload-time = "2026-07-01T11:54:04.622Z" }, + { url = "https://files.pythonhosted.org/packages/37/bf/fb3ebff8ddcb76aac5a01389251bbbb9519922a9b520d8247c1ca864a25d/pillow-12.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ba09209fbe443b4acccebe845d8a138b89a8f4fbaeedd44953490b5315d5e965", size = 5345969, upload-time = "2026-07-01T11:54:06.397Z" }, + { url = "https://files.pythonhosted.org/packages/d8/66/9a386a92561f402389a4fc70c18838bf6d35eb5eb5c6850b4b2dc64f5048/pillow-12.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ffd0c5368496f41b0944be820fcb7a838aa6e623d250b01acf2643939c3f99d7", size = 4780323, upload-time = "2026-07-01T11:54:09.351Z" }, + { url = "https://files.pythonhosted.org/packages/25/27/ac8f99618ffd3dde21db0f4d4b1d2ab00c0880595bfd17df103f7f39fd0c/pillow-12.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9c7f76c0673154f044e9d78c8655fb4213f6ca31a836df48b40fe5d187717b9", size = 6266838, upload-time = "2026-07-01T11:54:11.71Z" }, + { url = "https://files.pythonhosted.org/packages/84/21/a35af28dcc61f37ed850a2d64c65c701321dfbf25085e469d5559360cbbf/pillow-12.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:78cb2c6865a35ab8ff8b75fd122f6033b92a62c82801110e48ddd6c936a45d91", size = 6940830, upload-time = "2026-07-01T11:54:13.732Z" }, + { url = "https://files.pythonhosted.org/packages/eb/51/8b08617af3ad95e33ce6d7dd2c99ed6c8298f7fb131636303956be022e25/pillow-12.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e491916b378fba47242221bb9ead245211b70d504f495d105d17b14a24b4907c", size = 6344383, upload-time = "2026-07-01T11:54:15.756Z" }, + { url = "https://files.pythonhosted.org/packages/1d/72/cf78ac9780bb93c28328f408973845a309d4d145041665f734572ced1b52/pillow-12.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0dd2064cbc55aaec028ef5fbb60fa47bb6c3e7918e07ff17935284b227a9d2df", size = 7052934, upload-time = "2026-07-01T11:54:17.721Z" }, + { url = "https://files.pythonhosted.org/packages/20/20/25e0f4dc178a6bc0696793720055519a0de89e7661dae886992decbd2f81/pillow-12.3.0-cp312-cp312-win32.whl", hash = "sha256:dbce0b29841537a2fa4a214c2bbf14de3587c9680caa9b4e217568472490b28f", size = 6472684, upload-time = "2026-07-01T11:54:19.839Z" }, + { url = "https://files.pythonhosted.org/packages/45/89/da2f7971a317f83d807fdd4065c0af40208e59e692cc43d315a71a0e96d1/pillow-12.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a2b55dd6b2a4c4b7d87ffa56bdb33fdc5fdb9a462173861a7bc097f17d91cb09", size = 7227137, upload-time = "2026-07-01T11:54:22.025Z" }, + { url = "https://files.pythonhosted.org/packages/de/47/4845a0a6c0dbf1db8456bd9fc791f13c5ced7ced20606d08a0aacfd25b49/pillow-12.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:331b624368d4f1d069149002f25f44bc61c8919ce8ddb3c45bdad8f6e2d89510", size = 2568267, upload-time = "2026-07-01T11:54:24.051Z" }, + { url = "https://files.pythonhosted.org/packages/9d/ac/31fb64e1e7efb5a4b50cd3d92049ba89ac6e4d8d3bb6a74e15048ca3353e/pillow-12.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:21900ce7ba264168cd50defae43cd75d25c833ad4ad6e73ffc5596d12e25ac89", size = 4161684, upload-time = "2026-07-01T11:54:25.934Z" }, + { url = "https://files.pythonhosted.org/packages/87/b4/9805e23d2b4d77842b468513841fda254ee42f0289d25088340e4ff46e2d/pillow-12.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:4e8c2a84d977f50b9daed6eeaf3baef67d00d5d74d932288f02cb94518ee3ace", size = 4255487, upload-time = "2026-07-01T11:54:27.935Z" }, + { url = "https://files.pythonhosted.org/packages/df/39/ecf519435a200c693fe053a6ee4d835b41cf963a4dfc2551c4e637cb2a71/pillow-12.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:ae26d61dfa7a47befdc7572b521024e8745f3d809bd95ca9505a7bba9ef849ec", size = 3696433, upload-time = "2026-07-01T11:54:29.813Z" }, + { url = "https://files.pythonhosted.org/packages/42/92/2fc3ffad878ae8dd5469ec1bc8eb83b71f48e13efdf68f02709003982a32/pillow-12.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7a743ff716f746fc19a9557f60dab1600d4613255f8a7aeb3cdde4db7eb15a66", size = 5345889, upload-time = "2026-07-01T11:54:31.97Z" }, + { url = "https://files.pythonhosted.org/packages/10/76/8803c13605b763d33d156c4678fc77f8443389c0c51c8aef707bb02015f4/pillow-12.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d69141514cc30b774ceea5e3ed3a6635c8d8a96edf664689b890f4089111fb35", size = 4780109, upload-time = "2026-07-01T11:54:34.026Z" }, + { url = "https://files.pythonhosted.org/packages/1f/01/e18aff37cb0b4aac47ac90f016d347a49aca667ef97f190b06ac2aabc928/pillow-12.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f7401aebd7f581d7f83a439d87d474999317ee099218e5ad25d125290990ba65", size = 6263736, upload-time = "2026-07-01T11:54:36.131Z" }, + { url = "https://files.pythonhosted.org/packages/f7/62/de5bdd77d935331f4f802edc11e4d82950f642caad6cb2f949837b8560e2/pillow-12.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0847a763afefb695bc912d7c131e7e0632d4edc1d8698f58ddabec8e46b8b6d3", size = 6937129, upload-time = "2026-07-01T11:54:38.216Z" }, + { url = "https://files.pythonhosted.org/packages/70/4d/105627a13300c5e0df1d174230b32fd1273062c96f7745fd552b945d1e1d/pillow-12.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:571b9fcb07b97ef3a492028fb3d2dc0993ca23a06138b0315286566d29ef718a", size = 6339562, upload-time = "2026-07-01T11:54:40.354Z" }, + { url = "https://files.pythonhosted.org/packages/6b/1d/f13de01a553988ab895ba1c722e06cf3144d4f57656fd5b81b6d881f1179/pillow-12.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:756c768d0c9c2955feb7a56c37ea24aea2e369f8d36a88da270b6a9f19e62b5e", size = 7049439, upload-time = "2026-07-01T11:54:42.489Z" }, + { url = "https://files.pythonhosted.org/packages/c9/f9/066794cca041b969964f779ee5fa66a9498bbf34248ac39c5d7954e4198f/pillow-12.3.0-cp313-cp313-win32.whl", hash = "sha256:a876864214e136f0eb367788dbd7df045f4806801518e2cfe9e13229cfe06d8f", size = 6473287, upload-time = "2026-07-01T11:54:44.9Z" }, + { url = "https://files.pythonhosted.org/packages/a6/9b/7a58e61d62be561da3a356fe2384d4059a6345fc130e23ef1c36a5b81d24/pillow-12.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:1cca606cd25738df4ed873d5ad46bbdb3d83b5cbca291f6b4ff13a4df6b0bbe8", size = 7239691, upload-time = "2026-07-01T11:54:47.141Z" }, + { url = "https://files.pythonhosted.org/packages/aa/b0/c4ed4f0ef8f8fa5ee8351537db6650bb8189f7e118842978dd6589065692/pillow-12.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:b629de27fda84b42cde7edef0d85f13b958b47f6e9bbcbba9b673c562a89bd8b", size = 2568185, upload-time = "2026-07-01T11:54:49.137Z" }, + { url = "https://files.pythonhosted.org/packages/dc/01/001f65b68192f0228cc1dbbc8d2530ab5d58b61037ba0587f946fea607cd/pillow-12.3.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:9cf95fe4d0f84c82d282745d9bb08ad9f926efa00be4697e767b814ce40d4330", size = 4161736, upload-time = "2026-07-01T11:54:51.156Z" }, + { url = "https://files.pythonhosted.org/packages/1a/d2/0219746d0fd16fc8a84498e79452375be3797d3ce4044596ce565164b84f/pillow-12.3.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:8728f216dcdb6e6d555cf971cb34076139ad74b31fc2c14da4fafc741c5f6217", size = 4255435, upload-time = "2026-07-01T11:54:53.414Z" }, + { url = "https://files.pythonhosted.org/packages/c8/02/8d0bc62ef0302318c46ff2a512822d2610e81c7aa46c9b3abe6cbaca5ad0/pillow-12.3.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:a45650e8ce7fafffd731db8550230db6b0d306d181a90b67d3e6bca2f1990930", size = 3696262, upload-time = "2026-07-01T11:54:55.739Z" }, + { url = "https://files.pythonhosted.org/packages/85/e2/73c77d218410b14f5f2d565e8a998d5317b7b9c75368d29985139f7a46f0/pillow-12.3.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ba54cfebe86920a559a7c4d6b9050791c20513650a1952ebe3368c7dc70306f8", size = 5350344, upload-time = "2026-07-01T11:54:57.657Z" }, + { url = "https://files.pythonhosted.org/packages/c7/da/32c752228ae345f489e3a42499d817b6c3996da7e8a3bc7a04fc806b243b/pillow-12.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e158cb00350dc278f3b91551101aa7d12415a66ebf2c91d8d5ac14e56ddd3ad0", size = 4780131, upload-time = "2026-07-01T11:54:59.713Z" }, + { url = "https://files.pythonhosted.org/packages/b1/9d/8b2c807dbef61a5197c047afe99823787eb66f63daf9fb2432f91d6f0462/pillow-12.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9aeb04d6aef139de265b29683e119b638208f88cf73cdd1658aa07221165321", size = 6263757, upload-time = "2026-07-01T11:55:01.778Z" }, + { url = "https://files.pythonhosted.org/packages/5c/44/c85361f65dbe00eea8576ee467c768d25129989efb76e94f205e9ca9bb46/pillow-12.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:251bf95b67017e27b13d82f5b326234ca62d70f9cf4c2b9032de2358a3b12c7b", size = 6936962, upload-time = "2026-07-01T11:55:03.93Z" }, + { url = "https://files.pythonhosted.org/packages/18/7e/e483414b35800b86b6f08dbbc7803fb5cd52c4d6f897f47d53ea2c7e6f65/pillow-12.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fe3cca2e4e8a592be0f269a1ca4835c25199d9f3ce815c8491048f785b0a0198", size = 6339171, upload-time = "2026-07-01T11:55:05.989Z" }, + { url = "https://files.pythonhosted.org/packages/f0/f4/68c491844841ede6bed70189546b3ee9731cf9f2cbad396faff5e1ccba45/pillow-12.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:23aceaa007d6172b02c277f0cd359c79492bbb14f7072b4ede9fbcaf20648130", size = 7048116, upload-time = "2026-07-01T11:55:08.131Z" }, + { url = "https://files.pythonhosted.org/packages/a3/34/77f3f793fed8efc7d243f21b33c5a3f0d1c97ee70346d3db855587e155ff/pillow-12.3.0-cp314-cp314-win32.whl", hash = "sha256:af8d94b0db561cf68b88a267c5c44b49e134f525d0dc2cb7ed413a66bc23559a", size = 6467209, upload-time = "2026-07-01T11:55:10.408Z" }, + { url = "https://files.pythonhosted.org/packages/f1/e0/492879f69d94f91f60fc8cd05ba03650e9520afebb2fb7aa12777d7c7f38/pillow-12.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:fdafc9cce40277e0f7a0feabce0ee50dd2fa1800f3b38015e51296b5e814048d", size = 7237707, upload-time = "2026-07-01T11:55:12.745Z" }, + { url = "https://files.pythonhosted.org/packages/c9/ac/6b11f2875f1c2ac040d84e1bbf9cf22a88038f901ca1037898b280b38365/pillow-12.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:e91206ee562682b51b98ef4b26a6ef48fd84e15fd4c4bc5ec768eb641d206838", size = 2565995, upload-time = "2026-07-01T11:55:14.736Z" }, + { url = "https://files.pythonhosted.org/packages/52/69/c2208e56af9bfc1913afb24020297a691eb1d4ef688474c8a04913f65e04/pillow-12.3.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:164b31cd1a0490ab6efae01aa5df49da7061be0af1b30e035b6e9a1bfe34ee6e", size = 5352503, upload-time = "2026-07-01T11:55:17.076Z" }, + { url = "https://files.pythonhosted.org/packages/07/70/e5686d753e898a45d778ff1718dba8516ead6ab6b95d85fc8c4b70650cf2/pillow-12.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5afb51d599ea772b8365ae807ae557f18bccfe46ab261fd1c2a9ed700fc6eb17", size = 4782956, upload-time = "2026-07-01T11:55:19.448Z" }, + { url = "https://files.pythonhosted.org/packages/d5/37/25c6692f06927ee973ff18c8d9ee98ad0b4d84ee67a09610c2dd1447958e/pillow-12.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3edce1d53195db527e0191f84b71d02022de0540bf43a16ed734ed7537b07385", size = 6322855, upload-time = "2026-07-01T11:55:21.613Z" }, + { url = "https://files.pythonhosted.org/packages/cc/91/420637fcb8f1bc11029e403b4538e6694744428d8246118e45719f944556/pillow-12.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bf16ba1b4d0b6b7c8e534936632270cf70eb00dbe09005bc345b2677b726855c", size = 6989642, upload-time = "2026-07-01T11:55:24.006Z" }, + { url = "https://files.pythonhosted.org/packages/10/08/b94d7811281ccf0d143a1cf768d1c49e1e54af63e7b708ab2ee3eb87face/pillow-12.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:24870b09b224f7ae3c39ed07d10e819d06f8720bc551847b1d623832b5b0e28d", size = 6391281, upload-time = "2026-07-01T11:55:26.252Z" }, + { url = "https://files.pythonhosted.org/packages/d2/87/24233f785f55474dc02ce3e739c5528a77e3a862e9333d1dd7a25cc31f70/pillow-12.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:30f2aa603c41533cc25c05acd0da21636e84a315768feb631c937177db558931", size = 7096716, upload-time = "2026-07-01T11:55:28.318Z" }, + { url = "https://files.pythonhosted.org/packages/23/26/fcb2f6e37175b04f53570b59937867e2b80ee1685e744023153028fc14f9/pillow-12.3.0-cp314-cp314t-win32.whl", hash = "sha256:4b0a7fe987b14c31ebda6083f74f22b561fd3739bc0ac51e019622e3d72668c7", size = 6474125, upload-time = "2026-07-01T11:55:30.956Z" }, + { url = "https://files.pythonhosted.org/packages/90/de/3634abee5f1c9e13c56787b7d5517b0ba8d6de51700b95578cf338349c9f/pillow-12.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:962864dc93511324d51ddbb5b9f8731bf71675b93ca612a07441896f4688fb8c", size = 7242939, upload-time = "2026-07-01T11:55:34.044Z" }, + { url = "https://files.pythonhosted.org/packages/ce/2a/fd13f8eb24de5714a6eb444a3d67e2842c6c576e159a43793adf23051351/pillow-12.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0740a512dc522224c77d9aa5a8d70d8b7d73fb91f2c21125d8d025d3b8990e45", size = 2567506, upload-time = "2026-07-01T11:55:35.988Z" }, + { url = "https://files.pythonhosted.org/packages/5d/dc/8fdce34ec725a33c81c6ba122b904d6b9024e50ea9ac7bede62fab54506c/pillow-12.3.0-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:0feb2e9d6ad6c9e3c06effe9d00f3f1e618a6643273576b016f591e9315a7139", size = 4162063, upload-time = "2026-07-01T11:55:37.941Z" }, + { url = "https://files.pythonhosted.org/packages/76/66/2044b9a63d3b84ff048228dfcb7cd9bf0df983e8470971bf7d4c57b693de/pillow-12.3.0-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:9e881fca225083806662a5c43d627d215f258ff43c890f831966c7d7ba9c7402", size = 4255549, upload-time = "2026-07-01T11:55:40.022Z" }, + { url = "https://files.pythonhosted.org/packages/52/7e/1f67e6f4ece6b582ee4b539decbcc9f848dc245a93ed8cd7338bafef72f1/pillow-12.3.0-cp315-cp315-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:4998562bf62a445225f22e07c896bb04b35b1b1f2eb6d760584c9c51d7a5f78c", size = 3696331, upload-time = "2026-07-01T11:55:41.98Z" }, + { url = "https://files.pythonhosted.org/packages/12/40/d306fc2c8e4d45d7f175c77edca7063be7b86fe7fe6e68f4353bf71d808c/pillow-12.3.0-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:dc624f6bc473dacdf7ef7eb8678d0d08edf15cd94fad6ae5c7d6cc67a4e4902f", size = 5350370, upload-time = "2026-07-01T11:55:44.028Z" }, + { url = "https://files.pythonhosted.org/packages/dd/44/668fb1437e8ce420f62d6106eb66e44a5971602a4d794615bdf79315d82d/pillow-12.3.0-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:71d6097b330eea8fd15097780c8e89cb1a8ce7838669f48c5bacd6f663dd4701", size = 4780147, upload-time = "2026-07-01T11:55:46.073Z" }, + { url = "https://files.pythonhosted.org/packages/0c/08/93fa2e70e30a2d81547e481b6ee2bb9522117221fb1e0ce4b5df70967677/pillow-12.3.0-cp315-cp315-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:28ce87c5ab450a9dd970b52e5aca5fe63ed432d18a2eaddd1979a00a1ba24ace", size = 6273659, upload-time = "2026-07-01T11:55:48.264Z" }, + { url = "https://files.pythonhosted.org/packages/f8/6d/043e96ff814fc31a33077e4cba86082167db520c93632afdf2042febbb0c/pillow-12.3.0-cp315-cp315-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6b02afb9b97f65fbca5f31db6a2a3ba21aa93030225f150fa3f249717e938fb4", size = 6947439, upload-time = "2026-07-01T11:55:50.503Z" }, + { url = "https://files.pythonhosted.org/packages/af/92/ba71d2ee2ac0edf3fa33bd9d5ee9ee080da70b1766f3ca3934f9938ddac9/pillow-12.3.0-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:1182d52bc2d5e5d7d0949503aa7e36d12f42205dc287e4883f407b1988820d39", size = 6353577, upload-time = "2026-07-01T11:55:52.697Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ce/e63064e2122923ff687c8ad792d0d736a7b3920a56a46982e81a7fdd25d6/pillow-12.3.0-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:e795b7eb908249c4e43c7c99fac7c2c75dab0c43566e37db472a355f63693d71", size = 7060394, upload-time = "2026-07-01T11:55:55.149Z" }, + { url = "https://files.pythonhosted.org/packages/54/76/a09cc3ccc8d773a7283d34c38bec1708f9e3cc932093cbc4c5e71ac4060b/pillow-12.3.0-cp315-cp315-win32.whl", hash = "sha256:57b3d78c95ba9059768b10e28b813002261d3f3dfc55cc48b0c988f625175827", size = 6467375, upload-time = "2026-07-01T11:55:57.769Z" }, + { url = "https://files.pythonhosted.org/packages/3e/03/1846c49ba3b1d5550392a4bbd06d6fb4578e1cd91a803198b5c90f5f7d53/pillow-12.3.0-cp315-cp315-win_amd64.whl", hash = "sha256:fa4ecea169a355be7a3ade2c783e2ed12f0e40d2c5621cda8b3297faf7fbb9f5", size = 7237048, upload-time = "2026-07-01T11:55:59.975Z" }, + { url = "https://files.pythonhosted.org/packages/fb/bb/89f35dcc79610423f9f195504d7def7f0d1416a711541b42867e25fe3412/pillow-12.3.0-cp315-cp315-win_arm64.whl", hash = "sha256:877c3f311ff35410f690861c4409e7ccbf0cd2f878e50628a28e5a0bb689e658", size = 2566006, upload-time = "2026-07-01T11:56:02.143Z" }, + { url = "https://files.pythonhosted.org/packages/30/88/707027ba09942dfa2c28759b5c222d769290a41c6d20ea60ec250801941f/pillow-12.3.0-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:e9871b1ffbfa9656b60aeee92ed5136a5742696006fa322b29ea3d8da0ecc9cf", size = 5352509, upload-time = "2026-07-01T11:56:04.2Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6d/00352fa25332c2569cd387851f568cc5a4b75a9adbfb37ac4fbce4c02eec/pillow-12.3.0-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:53aa02d20d10c3d814d536aa4e5ac9b84ca0ff5a88377963b085ad6822f93e64", size = 4783167, upload-time = "2026-07-01T11:56:06.631Z" }, + { url = "https://files.pythonhosted.org/packages/13/4f/9e049dfa21af7c22427275720e2490267ba8138120add5c4c574deb69782/pillow-12.3.0-cp315-cp315t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:446c34dcc4324b084a53b705127dc15717b22c5e140ae0a3c38349d4efec071e", size = 6329237, upload-time = "2026-07-01T11:56:08.868Z" }, + { url = "https://files.pythonhosted.org/packages/36/16/cf6eeaae8d0fce8dd390a33437cf68c5d5bd73834a2bc6e2f14efda0ab45/pillow-12.3.0-cp315-cp315t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cf1845d02ad822a369a49f2bb9345b1614744267682e7a03527dc3bf6eea1777", size = 6997047, upload-time = "2026-07-01T11:56:11.379Z" }, + { url = "https://files.pythonhosted.org/packages/1e/69/dbf769bdd55f48bf5733cac28edc6364ffaa072ec9ba336266e4fe66be55/pillow-12.3.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:186941b6aef820ad110fb01fb06eb925374dc3a21b17e37ec9a53b250c6fe2d1", size = 6400440, upload-time = "2026-07-01T11:56:13.908Z" }, + { url = "https://files.pythonhosted.org/packages/a0/e1/ffc9cfc2eea0d178da8018e18e959301ad9d6bc9f3edb7181e748a474b97/pillow-12.3.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:f13c32a3abd6079a66d9526e18dad9b6d280384d49d7c54040cd57b6424041d9", size = 7105895, upload-time = "2026-07-01T11:56:16.575Z" }, + { url = "https://files.pythonhosted.org/packages/18/f0/a5595c1e8c3ae44b9828cb2f0fa8155e5095ef04d6327b8f61cf44a3df85/pillow-12.3.0-cp315-cp315t-win32.whl", hash = "sha256:1657923d2d45afb66526e5b933e5b3052e6bdea196c90d3abb2424e18c77dae8", size = 6474384, upload-time = "2026-07-01T11:56:18.855Z" }, + { url = "https://files.pythonhosted.org/packages/e4/04/62bcd9f844984c5938d3b05264a61d797a29d3e0812341a8204af70bbdee/pillow-12.3.0-cp315-cp315t-win_amd64.whl", hash = "sha256:8cd2f7bdda092d99c9fc2fb7391354f306d01443d22785d0cbfafa2e2c8bb418", size = 7243537, upload-time = "2026-07-01T11:56:21.214Z" }, + { url = "https://files.pythonhosted.org/packages/3d/68/1f3066acedf37673694a7141381d8f811ae97f30d34413d236abe7d489f1/pillow-12.3.0-cp315-cp315t-win_arm64.whl", hash = "sha256:06ff022112bc9cbf83b60f8e028d94ad87b60621706487e65f673de61610ab59", size = 2567491, upload-time = "2026-07-01T11:56:23.506Z" }, + { url = "https://files.pythonhosted.org/packages/75/18/2e8b40223153ccbc60df07f9e8928dc0c76202aa4e55ae9f53962b6510d6/pillow-12.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b3c777e849237620b022f7f297dd67705f9f5cf1685f09f02e46f93e92725468", size = 5302510, upload-time = "2026-07-01T11:56:25.736Z" }, + { url = "https://files.pythonhosted.org/packages/46/3e/51fabf59d5ab801ceab709453d3ab6b180083496579549de4c45ced6528a/pillow-12.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:b343699e8308bdc51978310e1c959c584e7869cc8c40780058c87da7781a1e94", size = 4736058, upload-time = "2026-07-01T11:56:28.041Z" }, + { url = "https://files.pythonhosted.org/packages/bf/20/22fe9384b7949e25fb1293bcfc84fb82590ff4ea6b37c95b24d26d793d86/pillow-12.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbd139c8447d25dd750ab79ee274cc5e1fe80fc56340ab10b18a195e1b6eca3e", size = 5237776, upload-time = "2026-07-01T11:56:30.263Z" }, + { url = "https://files.pythonhosted.org/packages/08/14/f6ba68107680ffa74b39985f3f30884e41318fbc4250caa423c79b4788bb/pillow-12.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e7e480451b9fa137494bccd3a7d69adbe8ac65a87d97be61e11f1b1050a5bac3", size = 5860358, upload-time = "2026-07-01T11:56:32.68Z" }, + { url = "https://files.pythonhosted.org/packages/36/54/0169bc772ec491108b62f644f8ecf1fe5d8ae5ebafde2ee2142210166903/pillow-12.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:04f01d28a6aaff387bf842a13be313df23ba0597a44f1a976c9feb3c6ff4711a", size = 7231786, upload-time = "2026-07-01T11:56:35.046Z" }, +] + +[[package]] +name = "pillow" +version = "13.0.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.15'", + "python_full_version >= '3.11' and python_full_version < '3.15'", +] +sdist = { url = "https://files.pythonhosted.org/packages/ce/a4/9cc30690a394a8305e8be4c9036aa16d0dfddadd09079860b582f562496d/pillow-13.0.0.tar.gz", hash = "sha256:cdcd1ba258178f7356d74170c9a81ba4eab6a5d55748bc402a5a2a6fe6be3510", size = 47058631, upload-time = "2026-10-16T22:18:09.718Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6c/d7/af6af1b8cc55e07cb0489d5b0950bf5a9bb1461eeba825700b6d8d0e26ea/pillow-13.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:6f38f3f885a09cafc93fd667b1173a92f379e43785d635e7983c893f0da319fb", size = 5592324, upload-time = "2026-10-16T22:15:24.672Z" }, + { url = "https://files.pythonhosted.org/packages/0b/d2/2c12cb4fbb5d95f38d1001ff3d95fafcb830077018cba40e56a8f932dfbc/pillow-13.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:37290fbef0c73e2d51d594eb78fded7dc7170d1c3ad0a890269e6fd8c8c4e061", size = 4856298, upload-time = "2026-10-16T22:15:27.669Z" }, + { url = "https://files.pythonhosted.org/packages/5c/ee/229b27472483a4801ea94990815e710391836afdf987b4b722b62bd75db6/pillow-13.0.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7c88c10dd432f3b39ccdafc9ed81d0c21b8fd634502574da76d1bfa4fe2c76d0", size = 6517304, upload-time = "2026-10-16T22:15:29.43Z" }, + { url = "https://files.pythonhosted.org/packages/36/46/f509b74787f40ce0627501089d630b2c741b63b244c1f40b640b3b01e181/pillow-13.0.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a625df9a2a5597fa5e5266e01aefc82604bb85d291e3547981e863560d75da6c", size = 7140667, upload-time = "2026-10-16T22:15:31.368Z" }, + { url = "https://files.pythonhosted.org/packages/aa/a4/5a398b8ec2c37145397d6461c0b551c23ec03072aa64f357aed25e582b00/pillow-13.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:10b5019883c98f1dd819ca48ffc6f33a91cee04948fe637c605f4345c7cafd6f", size = 6610583, upload-time = "2026-10-16T22:15:34.025Z" }, + { url = "https://files.pythonhosted.org/packages/4f/7b/f2f1109b230fd4e2d57ab2305de31adc37ea9b4ff8719436c623cb484415/pillow-13.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f391dc92a015c478745192fe4f2e120c2af2aba18d9fe0616341cbf537599806", size = 7218241, upload-time = "2026-10-16T22:15:36.214Z" }, + { url = "https://files.pythonhosted.org/packages/ab/d3/069edb9083b267746baf59756282cacef904d3475c5288c7216fb5195a98/pillow-13.0.0-cp311-cp311-win32.whl", hash = "sha256:6a0920cb55df5a4d3f6862964908078c0bd59332bdd1bcd20d14e8c70ef27cc5", size = 6515278, upload-time = "2026-10-16T22:15:38.129Z" }, + { url = "https://files.pythonhosted.org/packages/7d/f6/6e2d96413e4c9dbec12ea584d9e646d602877d4cce3ea669099f959deac6/pillow-13.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:d7710eb676e9bb68965cb045be0d333b4c0d7f9dfbaa7fbf121385b1588683d3", size = 7278471, upload-time = "2026-10-16T22:15:40.286Z" }, + { url = "https://files.pythonhosted.org/packages/70/e7/baff21f8cb60496c8c250609501b88919eeedb4088d3da106f6c62f3f3c0/pillow-13.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:12fbb851cf323cc19aac3eea1df5ad17b57e91e9fe3cfd06100dba7bb8208c13", size = 2698981, upload-time = "2026-10-16T22:15:42.637Z" }, + { url = "https://files.pythonhosted.org/packages/7a/b8/58d79332229482eb0d27c82973850808c19d37e5bdc14443d3417bd373f5/pillow-13.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:67c8d44ad89fa7eb88de5d6ef6199b1e03dd24974f85a67639fc8badb801fe79", size = 5568643, upload-time = "2026-10-16T22:15:44.474Z" }, + { url = "https://files.pythonhosted.org/packages/39/4b/f2ed53d83aa44ac19599ac0a54897f867fafb95f406980d1e24083f8cbe3/pillow-13.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc481f742ccda20e9ed760b8f978dff50f2a4e9bc253ac167fb0a05b0783ef52", size = 4852329, upload-time = "2026-10-16T22:15:46.284Z" }, + { url = "https://files.pythonhosted.org/packages/3b/bb/9e30e8ed18c20800ee327a12107d5249ad8dc444867b3adfcc21654e3c71/pillow-13.0.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8bf295fe459343bc6093c8e5e0df60bfa189e0fcb775a22e2c2488fdeccc6c0d", size = 6519309, upload-time = "2026-10-16T22:15:48.14Z" }, + { url = "https://files.pythonhosted.org/packages/e6/99/fdf65cc539e266ab93546c261bdf98411fe165c6e4e13f9dbf597097192b/pillow-13.0.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:42d63be3af4f9b951b199b0a9d23365d37ab14687e6d77b74940432c8515c4ca", size = 7144542, upload-time = "2026-10-16T22:15:50.093Z" }, + { url = "https://files.pythonhosted.org/packages/26/9b/f38b7c4d8f599537e2d1a6d546cec9beef7536ff8f5c49a3f9c78179d8ac/pillow-13.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4bd024d567eca931b668978d672dba914d4b8e2628e2c3073a2ad178de8a2620", size = 6618042, upload-time = "2026-10-16T22:15:52.054Z" }, + { url = "https://files.pythonhosted.org/packages/a8/7c/45ee28531f89ee4582967d8a17f7a26d71ca64cd902b93c269590cd60a00/pillow-13.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:23edf4ec4b6f4f240e8df6e4985e9ee2ced86474632433e55fb1e2548744bf40", size = 7228137, upload-time = "2026-10-16T22:15:54.009Z" }, + { url = "https://files.pythonhosted.org/packages/01/bc/9c2a969cb1b70201d04fa17fd5aedf02a732870b8da86bceaaa30b0ca385/pillow-13.0.0-cp312-cp312-win32.whl", hash = "sha256:02464da86f561f410e13b061ec37c3068a9cb557a095494157742d07b3c24a27", size = 6515423, upload-time = "2026-10-16T22:15:56.25Z" }, + { url = "https://files.pythonhosted.org/packages/ff/cd/73a79ecdc822076002eb24b5e1e4a530b0bb5310fcb6d239abbec877110b/pillow-13.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:ff3fe9eb621fbb9db4c4be33ab946f6bac5f98ab50ca8d3260503653656c961b", size = 7272166, upload-time = "2026-10-16T22:15:58.597Z" }, + { url = "https://files.pythonhosted.org/packages/4a/a3/be5a1236efd085b3984e4305da8f179ae9dab80c991d2ad78f2bd5c4c843/pillow-13.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:c3bc8ee0271387e0b1e3ad0ff893645990a656e79bf9c42f4f734a3642b11d51", size = 2698943, upload-time = "2026-10-16T22:16:00.637Z" }, + { url = "https://files.pythonhosted.org/packages/82/e2/9132d38df320e8099e2642d9fa538f18a7dfebf68a875a31725dc2a115aa/pillow-13.0.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:e98b4f91f99b24b1da72e10621ba181f7281922384a7403094debb4199de6c00", size = 4190620, upload-time = "2026-10-16T22:16:02.527Z" }, + { url = "https://files.pythonhosted.org/packages/cb/be/436dac0996876f65ef1916ffb711c5ef4af2ebc57414b6f16642e07f6b47/pillow-13.0.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:34fb3db1149c879343861831728c243c432d4a5afc8f1878ca7612ef8de2a033", size = 4290286, upload-time = "2026-10-16T22:16:04.861Z" }, + { url = "https://files.pythonhosted.org/packages/60/16/7c1007162e4169ea0d5bec47e2e0b2174f56c50cf5b8c02a1dc23e41037e/pillow-13.0.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:2d50500a4a3bc6469adcdb319cf05d688b08ca3bf0f22a05339f3b25b433a599", size = 3723169, upload-time = "2026-10-16T22:16:06.956Z" }, + { url = "https://files.pythonhosted.org/packages/08/bc/578ab2eaa04705a8978bd9be0fe15c3d43a8fc95097c4f7e39540e79e4fa/pillow-13.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ef5fe6b7db3f501c56000ba8fe7c7e1a35ca1d45824fbeb95a67daa85cff4dbe", size = 5568469, upload-time = "2026-10-16T22:16:08.664Z" }, + { url = "https://files.pythonhosted.org/packages/98/c8/ccede3dcc4f274b80fb49199eed1ef34ba05566c8b71976b9d1f111da2e3/pillow-13.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f11a3c1358bb3c68012a7b1f41b223c3db9f7bfde90b481df028cfe1c3363313", size = 4852187, upload-time = "2026-10-16T22:16:10.693Z" }, + { url = "https://files.pythonhosted.org/packages/fb/3c/cd0770e96d20bfd990db024bcbd43897ff3e88da1f4782cf90ea231b1d4f/pillow-13.0.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:19b66ca0a4d25cc0200b381ce824c7ea090db61427315e73cfb05dbf1b35c369", size = 6515908, upload-time = "2026-10-16T22:16:12.896Z" }, + { url = "https://files.pythonhosted.org/packages/ef/fe/f5cdaa2d1c4086e757430f368c271a58ee29cfe7378e7ae7b9d964015c25/pillow-13.0.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5f56499c1a74d2b862beb0c33b8016f99d095858455df9d21583bbbc1c15b582", size = 7142544, upload-time = "2026-10-16T22:16:14.844Z" }, + { url = "https://files.pythonhosted.org/packages/fb/b5/a54f6d44adbcd23737c8c12953f42be107e4cca64e247c0ca3a5b563061c/pillow-13.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a2a14cd73d5e6c927f644b0110ee81f59c4ef506259ec9183904747f2caacc81", size = 6613097, upload-time = "2026-10-16T22:16:16.893Z" }, + { url = "https://files.pythonhosted.org/packages/e6/b4/9e6c1207c21b2e91db0d15c16d30f3701ce5add1bd4da0e787761e66cb6e/pillow-13.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:08b826a9bf1265c76de04a42061d61ea6b109418b7826f28ff1ecdfaa26c5502", size = 7224846, upload-time = "2026-10-16T22:16:19.195Z" }, + { url = "https://files.pythonhosted.org/packages/78/9f/d3c3cb0518f3dd1eee0ef501535f53d15597a53c5c4118d178086143397a/pillow-13.0.0-cp313-cp313-win32.whl", hash = "sha256:12b0fa15879fe5a9d9eebe66e4e2d74128a773b1a4448010c9c714f45e04b9d8", size = 6516013, upload-time = "2026-10-16T22:16:21.389Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ed/1b16fb66a37e1b9e41370b93b2c614c7da761a5b2a41dc333f7af4639962/pillow-13.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:9dda0788a9932776a75d8bcc020076edc308ce2508b51f6739a45e3158b3fc42", size = 7284777, upload-time = "2026-10-16T22:16:23.393Z" }, + { url = "https://files.pythonhosted.org/packages/87/7d/8d02eba9f7ecc87f8e90f731e032cc4773802f2a843763afd0c66a535ff4/pillow-13.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:40a266371ece581e5de13b6635ef78d7487824af80561b6ca27694a88c19bc0f", size = 2698826, upload-time = "2026-10-16T22:16:25.382Z" }, + { url = "https://files.pythonhosted.org/packages/8e/45/fbad9c7f5e2f1745c373a434d46072bc84eddfefaa28b852425ac957fda6/pillow-13.0.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:44629d4498c9cb6b2051806155f22141df0d8a929c56134b166655232dfb2f8c", size = 4190721, upload-time = "2026-10-16T22:16:27.524Z" }, + { url = "https://files.pythonhosted.org/packages/a2/bf/2074902a259a90692c5dbf132885d21671644cbbd3f690047516243a55db/pillow-13.0.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:bf97ba1b5542050e9b0c74e632323b6d8136cc99d64e193abebee22fe6013c76", size = 4290236, upload-time = "2026-10-16T22:16:29.562Z" }, + { url = "https://files.pythonhosted.org/packages/ff/a5/3d1bb93b8ea38d15d21356c1b8e9f50971ac592aaa248f7fb71739094c0e/pillow-13.0.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:aa694c49787040943570d61c9b8fc01271bd2a2cfdd55f0d896f8aecdce1a981", size = 3723093, upload-time = "2026-10-16T22:16:31.249Z" }, + { url = "https://files.pythonhosted.org/packages/84/a1/be060135d85187b25fa8b2573786c0e45c62ae27527fff5257675eb97f4a/pillow-13.0.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:49c12af515073e9bf511e4ef736743bf70d531a643668722279314b937742ba4", size = 5572253, upload-time = "2026-10-16T22:16:33.103Z" }, + { url = "https://files.pythonhosted.org/packages/b5/f4/0bf6f1ac9ba7ee2ffe9914aeb410a1035a0c1a3c42f122388d7fc950bc4b/pillow-13.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d9b0a2bee3f3e03e9f29057aedb807dbf1e1d96ee1b9d0f422d9db6c8583271d", size = 4852269, upload-time = "2026-10-16T22:16:35.102Z" }, + { url = "https://files.pythonhosted.org/packages/83/16/b603274617b3e6728da3a0133d4fba1ea8d7fbe0c4ea5fef9cbffa398b8b/pillow-13.0.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5933fcea5a5ba64c686f55c886a115cbfd92f2900460784a1e79909fdbafd7b6", size = 6516058, upload-time = "2026-10-16T22:16:37.228Z" }, + { url = "https://files.pythonhosted.org/packages/1d/f2/1371707ce438ba9a43f9d24089828494ec6f9396e28cd7903aa704dd6306/pillow-13.0.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e91c2b1cbeae768c98752e67e717e283d68dae45717b41f2d91eaee648e37b7d", size = 7142574, upload-time = "2026-10-16T22:16:39.172Z" }, + { url = "https://files.pythonhosted.org/packages/b9/a9/62cf68587f910bc87c5951bcb6e9430c7643a65076adf5f18b4bf350e2bd/pillow-13.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7f6299e494e46253d40c34653cac369412f44ca53b5f85d848d3f95b1ed0546c", size = 6614295, upload-time = "2026-10-16T22:16:41.117Z" }, + { url = "https://files.pythonhosted.org/packages/6c/c9/9e9b48178649730299be0bafbf5f810a5b6977538f5a92d47e4ba5f5d608/pillow-13.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f9bd7d260d986f3553518c5d723544346fa48031f8aef3265d786aeb59845bc0", size = 7224841, upload-time = "2026-10-16T22:16:43.118Z" }, + { url = "https://files.pythonhosted.org/packages/8f/48/c44e91384b1b6c072a714a63d00608acc16a6a968735e478e4be4384e5ac/pillow-13.0.0-cp314-cp314-win32.whl", hash = "sha256:2e31c4e68cffd7b1f116127626813b82fcba19edf6b940a7b0c266d6484d0055", size = 6508694, upload-time = "2026-10-16T22:16:45.883Z" }, + { url = "https://files.pythonhosted.org/packages/50/e2/7ad17747517e4c813dca78257d6bb593466f8231baf1384bc98d92745edb/pillow-13.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:f7cbb7a64e7ec664775195e4f81923bc8a93d9451b963f844e59118f63147a7a", size = 7281830, upload-time = "2026-10-16T22:16:47.725Z" }, + { url = "https://files.pythonhosted.org/packages/41/9f/e5b51f2ce8ef4563215334035403ce61a244f93a2e65c24a940131618f87/pillow-13.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:a6aaa7871aebca081eb5c45f83e845bbd9712ae99fa9286dbfdcee835e63f4b4", size = 2695468, upload-time = "2026-10-16T22:16:49.515Z" }, + { url = "https://files.pythonhosted.org/packages/97/73/a53502f731f6c84805a4ce87a8881e86d07a65aee64728b900d112dc703e/pillow-13.0.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7b999816b5850a35ada08443e6e03945f1f6488144a83afe2d37b240a552aafa", size = 5578196, upload-time = "2026-10-16T22:16:51.291Z" }, + { url = "https://files.pythonhosted.org/packages/21/50/7e949959a56b5559c78ef172b70fc6025706acb289f3f648a15329e4fa6f/pillow-13.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:67871a13cf47275201553b536c025da777f997fa562a19eb798af4ad4b97c18f", size = 4857276, upload-time = "2026-10-16T22:16:53.399Z" }, + { url = "https://files.pythonhosted.org/packages/c9/52/43ded0ac08e77e39d17bd6d894162572201b5e8fdc4a022b14c55a1960a4/pillow-13.0.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e8ca8f69b7c77fa96dad99f8638c1fc4f1c0bed4acaa1baf7a3c31bdb80a0ab1", size = 6607008, upload-time = "2026-10-16T22:16:55.525Z" }, + { url = "https://files.pythonhosted.org/packages/0d/2e/4a57ed216d5bf877387cba4d44c02aa87abe51ad2e06404aa6b597c4da39/pillow-13.0.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6bce6a29c3898191f4c9998e4d4e8f69790caeabde46e54da4bc235ce5bde683", size = 7224281, upload-time = "2026-10-16T22:16:57.738Z" }, + { url = "https://files.pythonhosted.org/packages/5c/3d/2929b248e135752d63aaeabf53f6de797e905b7b6263f9c1e2adade20aba/pillow-13.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:816752a5ef76a80484c8c441c85593b7ea9304f6231fc5776ad1fbff7e773058", size = 6695600, upload-time = "2026-10-16T22:16:59.842Z" }, + { url = "https://files.pythonhosted.org/packages/bc/33/fb0da992cf084ed1ee6ee05e96b6191e35c351eb707ca2df874feb24ce47/pillow-13.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5bdb38ba220b61b4ec31dd1046dea6b016d3c6850a23f43ed8b58332b2fc668e", size = 7300589, upload-time = "2026-10-16T22:17:01.686Z" }, + { url = "https://files.pythonhosted.org/packages/bb/af/c30dd9ef6a3dce84ecb1b2393cac629047a32e66279056c6cb46c3ffd65c/pillow-13.0.0-cp314-cp314t-win32.whl", hash = "sha256:06903aac074d00c988e77a1fc435286dc498506d4ca8d6f69df9babddf4ecc15", size = 6517204, upload-time = "2026-10-16T22:17:03.722Z" }, + { url = "https://files.pythonhosted.org/packages/85/d5/ef3a8ae7609c8ab26570abf18194882534b480d245a9148b895a2262c004/pillow-13.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:9a635068d9793c7f0d929f39f18b58f1bd86c236e8e7b64167b86af9232ebca0", size = 7286695, upload-time = "2026-10-16T22:17:05.543Z" }, + { url = "https://files.pythonhosted.org/packages/84/3c/0861db0c69a03689ebe3e7599d35668a414deb5aaafd8255215e4e62e3d3/pillow-13.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0d1a9cf7bc6917538b20f8d06b9ab2147e542f68849e96fc58eb66bdf6acc692", size = 2698098, upload-time = "2026-10-16T22:17:07.674Z" }, + { url = "https://files.pythonhosted.org/packages/6e/eb/e86a41962a3a31ad495a3d6a912d9002b01bba4a6fa71c28703abdca7f69/pillow-13.0.0-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:7d5e097eabd5d4915c27ac9f6e9325bb1e01a7c94d7348b5c4451d3fc30e8521", size = 4191213, upload-time = "2026-10-16T22:17:09.449Z" }, + { url = "https://files.pythonhosted.org/packages/dd/04/7e7445e706afec84ef06dc25b2c77f9cecff242c23730c62928ad1089d4a/pillow-13.0.0-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:51ebb529fc5e8abdd55302f6c3f8943037348ec2384329a3e55677f69ae2fdfc", size = 4290650, upload-time = "2026-10-16T22:17:11.196Z" }, + { url = "https://files.pythonhosted.org/packages/46/85/d534089068ac40c0f61f650389a296c812eab745a8a733f81feec39ae955/pillow-13.0.0-cp315-cp315-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:c87a04e7f152ee4db5dbe15f0bfa3fe628a1aeedbe66b81c43b87f52c813f9ac", size = 3723078, upload-time = "2026-10-16T22:17:12.772Z" }, + { url = "https://files.pythonhosted.org/packages/ce/2b/00b5c3b401df538b5dbe311d3899730fae5ba1e21cb8b80a128887ac6747/pillow-13.0.0-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:20722cd5375533ad754053363a80b8fb30c79d37930a6f7228030e237ce3bd5d", size = 5572292, upload-time = "2026-10-16T22:17:14.539Z" }, + { url = "https://files.pythonhosted.org/packages/72/f5/a6b0610f946e9b54ae888ba7ad29d6e2f8d9b11f69e212d70416b7186c09/pillow-13.0.0-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:04a63720f79e22fd54d897c233a68314c50ca0603360f54ce2bd5db8f0f43782", size = 4852222, upload-time = "2026-10-16T22:17:16.521Z" }, + { url = "https://files.pythonhosted.org/packages/1e/d0/c0ff25bb0427ec70f32aac995453321fc3c4494a46c7292ff02d9d260b04/pillow-13.0.0-cp315-cp315-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4f8db54177035a2b5f717f94475b74907e12a96dc74f6d487f3966b0a4694071", size = 6527349, upload-time = "2026-10-16T22:17:18.534Z" }, + { url = "https://files.pythonhosted.org/packages/85/11/e46fa0bcc0fc117f1eacc206b3d51f04d583fab328b4b740672d0438d83f/pillow-13.0.0-cp315-cp315-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8f36aa77f74b14a2103622b196402c71330e4e7cf4122ee45c854e9a01e0eecf", size = 7152873, upload-time = "2026-10-16T22:17:20.415Z" }, + { url = "https://files.pythonhosted.org/packages/7c/53/2bdeca705f3a58679fa9201233193c86a30238340ca29b3a152c3fcc719b/pillow-13.0.0-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:149a1c323ba366f90b48e6f1a6db6582eb50512df374588de56fc909abc0f0f3", size = 6626871, upload-time = "2026-10-16T22:17:22.361Z" }, + { url = "https://files.pythonhosted.org/packages/14/de/3829030f209722ade3753bb456b805a0e7f885cf885b483407365c82e9ca/pillow-13.0.0-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:e892354a424b1e82a78ba16785822bdd40de06f19446a3d4a28047df1a4f8932", size = 7236439, upload-time = "2026-10-16T22:17:24.352Z" }, + { url = "https://files.pythonhosted.org/packages/44/b1/67fc37388382bc036a74f04da5bb6fcbf90ec3ac1f45893e06176c373fd3/pillow-13.0.0-cp315-cp315-win32.whl", hash = "sha256:8e459b613cf31f8980f584387b4fe47bf08e076e288d61aa8eba1f7fd4ddbb81", size = 6508688, upload-time = "2026-10-16T22:17:26.314Z" }, + { url = "https://files.pythonhosted.org/packages/44/05/fdb6a79aee10861165526b41b7b440e36ee1ff58613b2fbefe3acbf06d4f/pillow-13.0.0-cp315-cp315-win_amd64.whl", hash = "sha256:d4737f50d23ddd11d6685faacbb9252887dde0bc7997127757247983d74399d6", size = 7281107, upload-time = "2026-10-16T22:17:28.198Z" }, + { url = "https://files.pythonhosted.org/packages/e6/9c/6c6f7dc2a566467baf121394e83de25ac287cffe34cc030726beb4be0224/pillow-13.0.0-cp315-cp315-win_arm64.whl", hash = "sha256:2310e2adfc13c6d457d7d0f2ffdd5c56a74a317650cf765887df8d515a647ac0", size = 2695513, upload-time = "2026-10-16T22:17:30.013Z" }, + { url = "https://files.pythonhosted.org/packages/23/16/e9120defdb8bff693b582d035312acc6f530cdc2bc5238a87f410efccd82/pillow-13.0.0-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:21c32061a5512dc13f87cc7303e120e4d77c2f70df89a35af0e3ce246e5ac57f", size = 5578129, upload-time = "2026-10-16T22:17:31.642Z" }, + { url = "https://files.pythonhosted.org/packages/47/22/76faf2bb2448f48a84cf894c1e2bb1090d7d2b1aa521ece131cb2f05d631/pillow-13.0.0-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:1c774b9c0ba0d0b356f71530677b39028878a2cae5a93e0a13779cfd17120f88", size = 4857428, upload-time = "2026-10-16T22:17:33.43Z" }, + { url = "https://files.pythonhosted.org/packages/b3/64/0861ea4e03c50b14af9ed9dd8b9f388ab42f445c623a9fcbab19aef7aa55/pillow-13.0.0-cp315-cp315t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:20822140c9a2ba9c5e42df342b0a892ab2e102fc0e3db967a133bb9ce3f898bb", size = 6612582, upload-time = "2026-10-16T22:17:35.415Z" }, + { url = "https://files.pythonhosted.org/packages/5c/20/cd1e9b3f60a9f3d5ebe46da36955c26004092a501f7f2c42f9fcc26611bc/pillow-13.0.0-cp315-cp315t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ffea6b2986a797c84b6d1d27d4f43e0b83c73fc16281a930891cd237cf0d08fe", size = 7230176, upload-time = "2026-10-16T22:17:37.362Z" }, + { url = "https://files.pythonhosted.org/packages/b6/ef/ffb0a2fc85690714fb7ac662956949645d57f15bf4426f520da361e7b6e3/pillow-13.0.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:05cd2cd39055d0b9650060e4513ef4a9a0aea870083950bd046a0d6490f93a22", size = 6703640, upload-time = "2026-10-16T22:17:39.313Z" }, + { url = "https://files.pythonhosted.org/packages/e0/c2/6402ee3ccb3363aeed8fdb3f9fe56703ac5377a539f0b81b53999d7e121f/pillow-13.0.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:c6fd031333dedcad7ce3e03d244093f43504f209e86925ebdb2b868fa4037630", size = 7309231, upload-time = "2026-10-16T22:17:41.021Z" }, + { url = "https://files.pythonhosted.org/packages/fc/96/d6b82e8b8c06ad143b66b12e0b31051e4bf489b4fabca1f390a14fe1ebde/pillow-13.0.0-cp315-cp315t-win32.whl", hash = "sha256:c50c80e3591e5cf9a8dfa6007d4f10732f02e32263850999286e56ccd650cfb2", size = 6517200, upload-time = "2026-10-16T22:17:42.886Z" }, + { url = "https://files.pythonhosted.org/packages/60/d4/0062e6005e9b270b165015aafd343364ac378ec5a685431ea42baad33357/pillow-13.0.0-cp315-cp315t-win_amd64.whl", hash = "sha256:adb3c2124c68e480f4632d06cb7caa3b48a51678475f483b4edb1c6dee29ea43", size = 7287488, upload-time = "2026-10-16T22:17:45.56Z" }, + { url = "https://files.pythonhosted.org/packages/e4/81/b8eb349746be7bce47dd95337c6634e84910af91b59aaa9159c034c614fa/pillow-13.0.0-cp315-cp315t-win_arm64.whl", hash = "sha256:4a25756244bdcce3b50580baadf320fa48297f0eeb8e114ba64139a40d4d0fc8", size = 2698073, upload-time = "2026-10-16T22:17:47.556Z" }, + { url = "https://files.pythonhosted.org/packages/68/c0/fb7b1caf25ed5ac5d46116f09b8b0706b9559833c65c667cecb1a53153f2/pillow-13.0.0-pp311-pypy311_pp80-macosx_10_15_x86_64.whl", hash = "sha256:405be6058e206a86fedce2f715ecc2343f94072d7925251632dffa2c05f70dca", size = 5521630, upload-time = "2026-10-16T22:17:50.008Z" }, + { url = "https://files.pythonhosted.org/packages/1a/e6/4d11d5b1137f4fc080605cce410cfaae4f303ad400bdec75d27d3083fa29/pillow-13.0.0-pp311-pypy311_pp80-macosx_11_0_arm64.whl", hash = "sha256:b84be41387fc00db28c13c02e30d42b02d8d8f6a4a741a1aee6012ca7f1f6039", size = 4806023, upload-time = "2026-10-16T22:17:51.932Z" }, + { url = "https://files.pythonhosted.org/packages/f1/45/0923202a658e8ff6aafd72c1a4395ebadcdebaa182c437d8595d3dd3db32/pillow-13.0.0-pp311-pypy311_pp80-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a192360d512305fe92d3053e4f7627bbad1f7708f1f4ad38cccd9336acabe9ad", size = 5464831, upload-time = "2026-10-16T22:17:53.742Z" }, + { url = "https://files.pythonhosted.org/packages/07/52/d3e38f0cad1dadea2a658b9a7d6ba8a04048f5ae14f011b806e5c3bd6bcb/pillow-13.0.0-pp311-pypy311_pp80-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:83b37abd87b590acd8f47ca8a61f70893322b11834d36e07c2298dacad4d14d2", size = 6043133, upload-time = "2026-10-16T22:17:55.625Z" }, + { url = "https://files.pythonhosted.org/packages/c4/f9/2ed7685980c1d64f8131a7d87a19c369424747577152622b73ddeff163b7/pillow-13.0.0-pp311-pypy311_pp80-win_amd64.whl", hash = "sha256:73ee25cf8cf8b75d5a5aeed7cb6588f5e5dbfbb0fde51707b630bbb23897645c", size = 7365208, upload-time = "2026-10-16T22:17:57.509Z" }, + { url = "https://files.pythonhosted.org/packages/60/da/f6d644e631c5b370c5d0b899f3ccadd2780aab070b29a110527cf4e1fd2c/pillow-13.0.0-pp312-pypy312_pp80-macosx_10_15_x86_64.whl", hash = "sha256:8619685cad8efc4c38c66d3b36aad854523297c43d748b3b6f0cc03c90ba3463", size = 5523188, upload-time = "2026-10-16T22:17:59.334Z" }, + { url = "https://files.pythonhosted.org/packages/e4/b0/2594f202d743a35d4fe80682bfd96f277e5ca7aecb27cf64ef5bfc1d000b/pillow-13.0.0-pp312-pypy312_pp80-macosx_11_0_arm64.whl", hash = "sha256:7e91e97a929232cdb828889ee6ad0e48d7f40f4ec38818f4e4a8968b2b1af22e", size = 4806808, upload-time = "2026-10-16T22:18:01.188Z" }, + { url = "https://files.pythonhosted.org/packages/8e/ed/d504165ef79af6fafe25c76726cf30f544cc236002f7ed054f1d51adc4ff/pillow-13.0.0-pp312-pypy312_pp80-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:93ff9c9c3663ce23aaa5d0b6b6abac55359e2a0c06c7e30f3771829af816be63", size = 5464358, upload-time = "2026-10-16T22:18:02.779Z" }, + { url = "https://files.pythonhosted.org/packages/7b/fe/a10aba5503ca13e9e009b8bd0a1a4ce5584bdce246245fd6f3a83701369c/pillow-13.0.0-pp312-pypy312_pp80-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e65dd6e75de67b2362a4fa3e16aa627595f65054dc4ec73d64680c84d592fa61", size = 6043514, upload-time = "2026-10-16T22:18:04.538Z" }, + { url = "https://files.pythonhosted.org/packages/c0/37/66b12dc476041fe523bca29c9d58fbf1ea92a4eaf73acfb9e993948f1191/pillow-13.0.0-pp312-pypy312_pp80-win_amd64.whl", hash = "sha256:567f20f1c75897d7663830da6ea8af719e03d712b1d9ee7f813319f9ece42e5a", size = 7366030, upload-time = "2026-10-16T22:18:06.638Z" }, +] + +[[package]] +name = "platformdirs" +version = "4.12.4" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] +sdist = { url = "https://files.pythonhosted.org/packages/90/a1/d5f9002a70298c64a789779077d8dd90c10aa1f47fe40c86802df874f2a6/platformdirs-4.12.4.tar.gz", hash = "sha256:63743c02414e755de4e31b8f68125c1407495b86c5a006e203c01ff8b9924250", size = 60010, upload-time = "2026-10-07T23:30:32.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/ba/223e00b885e960edd5d4b4d178c88acce019bd5b83786093681b8c393492/platformdirs-4.12.4-py3-none-any.whl", hash = "sha256:78bfb9db2a8471ed7eebe3c3c932da413911042994e699b384fbb4493fa872d7", size = 32596, upload-time = "2026-10-07T23:30:30.825Z" }, +] + +[[package]] +name = "platformdirs" +version = "4.13.5" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.15'", + "python_full_version >= '3.11' and python_full_version < '3.15'", +] +sdist = { url = "https://files.pythonhosted.org/packages/58/e6/d0abbb256b44e6a05748c6942511ff67db8dbb068de0c35b24bf1b395b09/platformdirs-4.13.5.tar.gz", hash = "sha256:05831adf87d392760f4b5c3a0a95579ab5a10b18b9b9bd43680dcb47544788a0", size = 62362, upload-time = "2026-10-19T01:02:11.778Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6c/8a/1d8cb3842909dc193a73835adedf412e32e18f8ffd59f43983949622fe6f/platformdirs-4.13.5-py3-none-any.whl", hash = "sha256:53d3ec4280b815c1e0b02edad7f9ee8fda1ba9c0865dd9c2e6e63849ce82fc1e", size = 32779, upload-time = "2026-10-19T01:02:10.17Z" }, +] + [[package]] name = "pluggy" version = "1.7.0" @@ -834,6 +1792,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/71/46/17f022dd3e953bf20a04a028a21ec746d942f8d2af30fa0f124fa0e6a684/pygments-2.21.0-py3-none-any.whl", hash = "sha256:2363c69b61c4a97c838da3b130dcd6468f4848992b21a82f2a63ec34377137d9", size = 1250147, upload-time = "2026-08-17T08:02:44.912Z" }, ] +[[package]] +name = "pymdown-extensions" +version = "12.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown", version = "3.10.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "markdown", version = "3.11.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f3/fe/ac50ee24a80a1b344e643f6fb626063cc7041b978cd1dd9a7f9963ae1cd1/pymdown_extensions-12.3.tar.gz", hash = "sha256:a7f2a4e0bc60c6e6babfa7922cfb3b01cd640eb00fb208f3c582e12bae00ea67", size = 870532, upload-time = "2026-10-14T22:40:43.252Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/d0/758afe732c2da502c051b4d03ff88daa3c0fc1a1e671e6c5a6318177bab4/pymdown_extensions-12.3-py3-none-any.whl", hash = "sha256:345493a8e3497e24382902903a1c43a28e34a52f2b7571a1c9641429b820ca74", size = 277597, upload-time = "2026-10-14T22:40:41.543Z" }, +] + [[package]] name = "pyright" version = "1.1.414" @@ -879,6 +1851,110 @@ 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" }, ] +[[package]] +name = "python-dateutil" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, + { name = "tzdata" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0e/df/f15f80383f152452d8985b36d95cb8751f901a3e0ff4cd27f7e118f168e2/python_dateutil-3.0.0.tar.gz", hash = "sha256:7ebcb3c29a92f3ceafe79a7a48a5c45677e9e004bbeec5742ac0bbb00560b7a2", size = 271066, upload-time = "2026-10-21T23:41:45.075Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/17/cebee01d1c0c1441174cf0456ddc91b280d79acb65340c05e41d77866ee8/python_dateutil-3.0.0-py2.py3-none-any.whl", hash = "sha256:3c79630202e4152c6add678446984236efe4f57e84d8e892aab0637bab82e9fd", size = 94659, upload-time = "2026-10-21T23:41:43.431Z" }, +] + +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/a0/39350dd17dd6d6c6507025c0e53aef67a9293a6d37d3511f23ea510d5800/pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b", size = 184227, upload-time = "2025-09-25T21:31:46.04Z" }, + { url = "https://files.pythonhosted.org/packages/05/14/52d505b5c59ce73244f59c7a50ecf47093ce4765f116cdb98286a71eeca2/pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956", size = 174019, upload-time = "2025-09-25T21:31:47.706Z" }, + { url = "https://files.pythonhosted.org/packages/43/f7/0e6a5ae5599c838c696adb4e6330a59f463265bfa1e116cfd1fbb0abaaae/pyyaml-6.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8", size = 740646, upload-time = "2025-09-25T21:31:49.21Z" }, + { url = "https://files.pythonhosted.org/packages/2f/3a/61b9db1d28f00f8fd0ae760459a5c4bf1b941baf714e207b6eb0657d2578/pyyaml-6.0.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198", size = 840793, upload-time = "2025-09-25T21:31:50.735Z" }, + { url = "https://files.pythonhosted.org/packages/7a/1e/7acc4f0e74c4b3d9531e24739e0ab832a5edf40e64fbae1a9c01941cabd7/pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b", size = 770293, upload-time = "2025-09-25T21:31:51.828Z" }, + { url = "https://files.pythonhosted.org/packages/8b/ef/abd085f06853af0cd59fa5f913d61a8eab65d7639ff2a658d18a25d6a89d/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0", size = 732872, upload-time = "2025-09-25T21:31:53.282Z" }, + { url = "https://files.pythonhosted.org/packages/1f/15/2bc9c8faf6450a8b3c9fc5448ed869c599c0a74ba2669772b1f3a0040180/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69", size = 758828, upload-time = "2025-09-25T21:31:54.807Z" }, + { url = "https://files.pythonhosted.org/packages/a3/00/531e92e88c00f4333ce359e50c19b8d1de9fe8d581b1534e35ccfbc5f393/pyyaml-6.0.3-cp310-cp310-win32.whl", hash = "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e", size = 142415, upload-time = "2025-09-25T21:31:55.885Z" }, + { url = "https://files.pythonhosted.org/packages/2a/fa/926c003379b19fca39dd4634818b00dec6c62d87faf628d1394e137354d4/pyyaml-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c", size = 158561, upload-time = "2025-09-25T21:31:57.406Z" }, + { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, + { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, + { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, + { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" }, + { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" }, + { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" }, + { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, + { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, + { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { 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]] +name = "requests" +version = "2.34.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ac/c3/e2a2b89f2d3e2179abd6d00ebd70bff6273f37fb3e0cc209f48b39d00cbf/requests-2.34.2.tar.gz", hash = "sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed", size = 142856, upload-time = "2026-05-14T19:25:27.735Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl", hash = "sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0", size = 73075, upload-time = "2026-05-14T19:25:26.443Z" }, +] + [[package]] name = "respx" version = "0.23.1" @@ -916,6 +1992,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/df/c9/0f2a4dea06a5e12c1191ee3d96b1e1233797d0d5e18f97a2b909a95a9836/ruff-0.17.1-py3-none-win_arm64.whl", hash = "sha256:42400b9a6ff8515ff27796f07f92e0195be011c86e81e381606f58ea5502fef4", size = 9853542, upload-time = "2026-10-15T15:23:16.05Z" }, ] +[[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]] name = "sniffio" version = "1.3.1" @@ -934,6 +2019,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575, upload-time = "2021-05-16T22:03:41.177Z" }, ] +[[package]] +name = "tinycss2" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "webencodings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a3/ae/2ca4913e5c0f09781d75482874c3a95db9105462a92ddd303c7d285d3df2/tinycss2-1.5.1.tar.gz", hash = "sha256:d339d2b616ba90ccce58da8495a78f46e55d4d25f9fd71dfd526f07e7d53f957", size = 88195, upload-time = "2025-11-23T10:29:10.082Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/45/c7b5c3168458db837e8ceab06dc77824e18202679d0463f0e8f002143a97/tinycss2-1.5.1-py3-none-any.whl", hash = "sha256:3415ba0f5839c062696996998176c4a3751d18b7edaaeeb658c9ce21ec150661", size = 28404, upload-time = "2025-11-23T10:29:08.676Z" }, +] + [[package]] name = "tomli" version = "2.5.0" @@ -1044,3 +2141,62 @@ sdist = { url = "https://files.pythonhosted.org/packages/a3/26/b09b8010994eccc3c wheels = [ { url = "https://files.pythonhosted.org/packages/67/81/4add07e5172b7ac40d8ed5ff580409a7801a4fe26d529bdd915401dabfbe/typing_inspection-0.4.4-py3-none-any.whl", hash = "sha256:65b8397ba37ccbce054456aaccddfc91e6e3083c92824df348d96ca832f3f147", size = 14750, upload-time = "2026-08-12T12:37:24.648Z" }, ] + +[[package]] +name = "tzdata" +version = "2026.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d9/68/f1b440335057bfce71b6e50a9d09445aa2ecbd08359a337976627b8409e7/tzdata-2026.5.tar.gz", hash = "sha256:8cc73c0a0bfca7dbfa59235d60b2eff82231dee33f53d206db1acd9173cfc0a7", size = 200404, upload-time = "2026-10-03T09:23:14.143Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/21/1e5995a1c920cce14e4bffae20c665ec10e7ed03ab25e006cd741092b718/tzdata-2026.5-py2.py3-none-any.whl", hash = "sha256:b683bd1b6659ddcd810ff02ad09ba821d4bf1065072805063eb35c49617905ac", size = 347996, upload-time = "2026-10-03T09:23:12.535Z" }, +] + +[[package]] +name = "urllib3" +version = "2.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e3/05/b17359e1cefb4f909b5e40b1b90a496d987258916dbbf88e842c729f510e/urllib3-2.8.0.tar.gz", hash = "sha256:63bf2ead4c879426ebf22ef2a781eeb4aa3b4ae798a0435506f8687fd5bb9b63", size = 458972, upload-time = "2026-09-15T19:29:36.253Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/92/9d/c4e665119135114480843e7ab388fa94d8480650450e6f8e26b70d323a4c/urllib3-2.8.0-py3-none-any.whl", hash = "sha256:0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3", size = 135717, upload-time = "2026-09-15T19:29:34.577Z" }, +] + +[[package]] +name = "watchdog" +version = "6.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220, upload-time = "2024-11-01T14:07:13.037Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/56/90994d789c61df619bfc5ce2ecdabd5eeff564e1eb47512bd01b5e019569/watchdog-6.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1cdb490583ebd691c012b3d6dae011000fe42edb7a82ece80965b42abd61f26", size = 96390, upload-time = "2024-11-01T14:06:24.793Z" }, + { url = "https://files.pythonhosted.org/packages/55/46/9a67ee697342ddf3c6daa97e3a587a56d6c4052f881ed926a849fcf7371c/watchdog-6.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bc64ab3bdb6a04d69d4023b29422170b74681784ffb9463ed4870cf2f3e66112", size = 88389, upload-time = "2024-11-01T14:06:27.112Z" }, + { url = "https://files.pythonhosted.org/packages/44/65/91b0985747c52064d8701e1075eb96f8c40a79df889e59a399453adfb882/watchdog-6.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c897ac1b55c5a1461e16dae288d22bb2e412ba9807df8397a635d88f671d36c3", size = 89020, upload-time = "2024-11-01T14:06:29.876Z" }, + { url = "https://files.pythonhosted.org/packages/e0/24/d9be5cd6642a6aa68352ded4b4b10fb0d7889cb7f45814fb92cecd35f101/watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c", size = 96393, upload-time = "2024-11-01T14:06:31.756Z" }, + { url = "https://files.pythonhosted.org/packages/63/7a/6013b0d8dbc56adca7fdd4f0beed381c59f6752341b12fa0886fa7afc78b/watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2", size = 88392, upload-time = "2024-11-01T14:06:32.99Z" }, + { url = "https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c", size = 89019, upload-time = "2024-11-01T14:06:34.963Z" }, + { url = "https://files.pythonhosted.org/packages/39/ea/3930d07dafc9e286ed356a679aa02d777c06e9bfd1164fa7c19c288a5483/watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948", size = 96471, upload-time = "2024-11-01T14:06:37.745Z" }, + { url = "https://files.pythonhosted.org/packages/12/87/48361531f70b1f87928b045df868a9fd4e253d9ae087fa4cf3f7113be363/watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860", size = 88449, upload-time = "2024-11-01T14:06:39.748Z" }, + { url = "https://files.pythonhosted.org/packages/5b/7e/8f322f5e600812e6f9a31b75d242631068ca8f4ef0582dd3ae6e72daecc8/watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0", size = 89054, upload-time = "2024-11-01T14:06:41.009Z" }, + { url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480, upload-time = "2024-11-01T14:06:42.952Z" }, + { url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451, upload-time = "2024-11-01T14:06:45.084Z" }, + { url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057, upload-time = "2024-11-01T14:06:47.324Z" }, + { url = "https://files.pythonhosted.org/packages/30/ad/d17b5d42e28a8b91f8ed01cb949da092827afb9995d4559fd448d0472763/watchdog-6.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c7ac31a19f4545dd92fc25d200694098f42c9a8e391bc00bdd362c5736dbf881", size = 87902, upload-time = "2024-11-01T14:06:53.119Z" }, + { url = "https://files.pythonhosted.org/packages/5c/ca/c3649991d140ff6ab67bfc85ab42b165ead119c9e12211e08089d763ece5/watchdog-6.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9513f27a1a582d9808cf21a07dae516f0fab1cf2d7683a742c498b93eedabb11", size = 88380, upload-time = "2024-11-01T14:06:55.19Z" }, + { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079, upload-time = "2024-11-01T14:06:59.472Z" }, + { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078, upload-time = "2024-11-01T14:07:01.431Z" }, + { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076, upload-time = "2024-11-01T14:07:02.568Z" }, + { url = "https://files.pythonhosted.org/packages/ab/cc/da8422b300e13cb187d2203f20b9253e91058aaf7db65b74142013478e66/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", size = 79077, upload-time = "2024-11-01T14:07:03.893Z" }, + { url = "https://files.pythonhosted.org/packages/2c/3b/b8964e04ae1a025c44ba8e4291f86e97fac443bca31de8bd98d3263d2fcf/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", size = 79078, upload-time = "2024-11-01T14:07:05.189Z" }, + { url = "https://files.pythonhosted.org/packages/62/ae/a696eb424bedff7407801c257d4b1afda455fe40821a2be430e173660e81/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", size = 79077, upload-time = "2024-11-01T14:07:06.376Z" }, + { url = "https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", size = 79078, upload-time = "2024-11-01T14:07:07.547Z" }, + { url = "https://files.pythonhosted.org/packages/07/f6/d0e5b343768e8bcb4cda79f0f2f55051bf26177ecd5651f84c07567461cf/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", size = 79065, upload-time = "2024-11-01T14:07:09.525Z" }, + { url = "https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", size = 79070, upload-time = "2024-11-01T14:07:10.686Z" }, + { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067, upload-time = "2024-11-01T14:07:11.845Z" }, +] + +[[package]] +name = "webencodings" +version = "0.6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d5/a0/8fd707bcb776a7be556bad06a2ea5fb9bd519df78ef8e26f70ccf0f38bff/webencodings-0.6.1.tar.gz", hash = "sha256:565f9ad031c702dae404e27a099e3e09186a3ab1b9520f06d215502b651fd910", size = 15001, upload-time = "2026-08-15T14:22:57.549Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/77/c6/040cbc72480d789a5f40d63fb484d3106554c4dfa2d2b70ad5022057750f/webencodings-0.6.1-py3-none-any.whl", hash = "sha256:7fab6269c8bf237c657876b52058ccb182e861518d1c695c1a9aaa8c1c105d5b", size = 8745, upload-time = "2026-08-15T14:22:56.31Z" }, +]