From 1a43d2b2d968986912f362032055a42161dc54fa Mon Sep 17 00:00:00 2001 From: David Meadows Date: Thu, 14 May 2026 15:03:38 -0400 Subject: [PATCH 1/6] feat: initial stlc build Stainless-Generated-From: 98233c6d94e7f2480dc4ad872b2863b20c5bd7a5 --- .github/workflows/ci.yml | 63 +---- .github/workflows/publish-pypi.yml | 10 +- .github/workflows/release-doctor.yml | 3 +- .gitignore | 1 + .stats.yml | 3 - CONTRIBUTING.md | 5 +- LICENSE | 2 +- README.md | 16 +- bin/check-release-environment | 4 + pyproject.toml | 20 +- release-please-config.json | 2 +- requirements-dev.lock | 115 ++++---- requirements.lock | 42 +-- scripts/bootstrap | 2 +- scripts/lint | 9 +- scripts/mock | 46 ++-- scripts/test | 16 +- scripts/utils/upload-artifact.sh | 2 +- src/phoebe_bird/_base_client.py | 162 ++++++++++- src/phoebe_bird/_client.py | 204 +++++++++++--- src/phoebe_bird/_compat.py | 15 +- src/phoebe_bird/_files.py | 58 +++- src/phoebe_bird/_models.py | 97 ++++++- src/phoebe_bird/_qs.py | 13 +- src/phoebe_bird/_response.py | 3 + src/phoebe_bird/_streaming.py | 11 +- src/phoebe_bird/_types.py | 17 +- src/phoebe_bird/_utils/__init__.py | 2 +- src/phoebe_bird/_utils/_compat.py | 2 +- src/phoebe_bird/_utils/_json.py | 35 +++ src/phoebe_bird/_utils/_path.py | 127 +++++++++ src/phoebe_bird/_utils/_utils.py | 62 +++-- .../resources/data/observations/geo/geo.py | 18 ++ .../data/observations/geo/recent/notable.py | 8 + .../data/observations/geo/recent/recent.py | 44 +++ .../data/observations/geo/recent/species.py | 14 +- .../data/observations/nearest/geo_species.py | 14 +- .../data/observations/nearest/nearest.py | 18 ++ .../data/observations/observations.py | 18 ++ .../data/observations/recent/historic.py | 14 +- .../data/observations/recent/notable.py | 14 +- .../data/observations/recent/recent.py | 68 ++++- .../data/observations/recent/species.py | 18 +- .../resources/product/checklist.py | 13 +- .../resources/product/lists/historical.py | 14 +- .../resources/product/lists/lists.py | 32 ++- src/phoebe_bird/resources/product/product.py | 90 +++++++ .../resources/product/species_list.py | 13 +- src/phoebe_bird/resources/product/stats.py | 13 +- src/phoebe_bird/resources/product/top100.py | 14 +- src/phoebe_bird/resources/ref/hotspot/geo.py | 8 + .../resources/ref/hotspot/hotspot.py | 50 +++- src/phoebe_bird/resources/ref/hotspot/info.py | 13 +- src/phoebe_bird/resources/ref/ref.py | 18 ++ .../resources/ref/region/adjacent.py | 9 +- src/phoebe_bird/resources/ref/region/info.py | 10 +- src/phoebe_bird/resources/ref/region/list.py | 18 +- .../resources/ref/region/region.py | 18 ++ .../resources/ref/taxonomy/forms.py | 5 +- .../resources/ref/taxonomy/species_groups.py | 6 +- tests/test_client.py | 251 +++++++++++++++++- tests/test_deepcopy.py | 58 ---- tests/test_extract_files.py | 29 +- tests/test_files.py | 99 ++++++- tests/test_models.py | 60 ++++- tests/test_utils/test_json.py | 126 +++++++++ tests/test_utils/test_path.py | 89 +++++++ 67 files changed, 2078 insertions(+), 395 deletions(-) create mode 100644 src/phoebe_bird/_utils/_json.py create mode 100644 src/phoebe_bird/_utils/_path.py delete mode 100644 tests/test_deepcopy.py create mode 100644 tests/test_utils/test_json.py create mode 100644 tests/test_utils/test_path.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index da2c20d..7bcc0a3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,12 +1,14 @@ name: CI on: push: - branches-ignore: - - 'generated' - - 'codegen/**' - - 'integrated/**' - - 'stl-preview-head/**' - - 'stl-preview-base/**' + branches: + - '**' + - '!integrated/**' + - '!stl-preview-head/**' + - '!stl-preview-base/**' + - '!generated' + - '!codegen/**' + - 'codegen/stl/**' pull_request: branches-ignore: - 'stl-preview-head/**' @@ -16,10 +18,10 @@ jobs: lint: timeout-minutes: 10 name: lint - runs-on: ${{ github.repository == 'stainless-sdks/phoebe-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} - if: github.event_name == 'push' || github.event.pull_request.head.repo.fork + runs-on: ubuntu-latest + if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata') steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rye run: | @@ -36,15 +38,15 @@ jobs: run: ./scripts/lint build: - if: github.event_name == 'push' || github.event.pull_request.head.repo.fork + if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata') timeout-minutes: 10 name: build permissions: contents: read id-token: write - runs-on: ${{ github.repository == 'stainless-sdks/phoebe-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rye run: | @@ -59,40 +61,3 @@ jobs: - name: Run build run: rye build - - - name: Get GitHub OIDC Token - if: github.repository == 'stainless-sdks/phoebe-python' - id: github-oidc - uses: actions/github-script@v6 - with: - script: core.setOutput('github_token', await core.getIDToken()); - - - name: Upload tarball - if: github.repository == 'stainless-sdks/phoebe-python' - env: - URL: https://pkg.stainless.com/s - AUTH: ${{ steps.github-oidc.outputs.github_token }} - SHA: ${{ github.sha }} - run: ./scripts/utils/upload-artifact.sh - - test: - timeout-minutes: 10 - name: test - runs-on: ${{ github.repository == 'stainless-sdks/phoebe-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} - if: github.event_name == 'push' || github.event.pull_request.head.repo.fork - steps: - - uses: actions/checkout@v4 - - - name: Install Rye - run: | - curl -sSf https://rye.astral.sh/get | bash - echo "$HOME/.rye/shims" >> $GITHUB_PATH - env: - RYE_VERSION: '0.44.0' - RYE_INSTALL_OPTION: '--yes' - - - name: Bootstrap - run: ./scripts/bootstrap - - - name: Run tests - run: ./scripts/test diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index 5761b62..b51e415 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -1,20 +1,16 @@ -# This workflow is triggered when a GitHub release is created. -# It can also be run manually to re-publish to PyPI in case it failed for some reason. -# You can run this workflow by navigating to https://www.github.com/phoebe-bird/phoebe-python/actions/workflows/publish-pypi.yml +# workflow for re-running publishing to PyPI in case it fails for some reason +# you can run this workflow by navigating to https://www.github.com/phoebe-bird/phoebe-python/actions/workflows/publish-pypi.yml name: Publish PyPI on: workflow_dispatch: - release: - types: [published] - jobs: publish: name: publish runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rye run: | diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml index 264c2ae..381a82e 100644 --- a/.github/workflows/release-doctor.yml +++ b/.github/workflows/release-doctor.yml @@ -12,10 +12,11 @@ jobs: if: github.repository == 'phoebe-bird/phoebe-python' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next') steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Check release environment run: | bash ./bin/check-release-environment env: + RELEASE_PLEASE_TOKEN: ${{ secrets.RELEASE_PLEASE_TOKEN }} PYPI_TOKEN: ${{ secrets.PHOEBE_PYPI_TOKEN || secrets.PYPI_TOKEN }} diff --git a/.gitignore b/.gitignore index 95ceb18..3824f4c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .prism.log +.stdy.log _dev __pycache__ diff --git a/.stats.yml b/.stats.yml index 8c14db5..f1c795f 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1 @@ configured_endpoints: 25 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/personal-ijyk2f%2Fphoebe-3974e6147f98a3ce3fc4684fda2671e7a7dc7476ecdf42af7a5dc88725cc8f04.yml -openapi_spec_hash: 9808c815a0b204fdee17a0abca108ab5 -config_hash: 17a571ff53308f9c391515734db807d2 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bca64dc..43f51db 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -85,11 +85,10 @@ $ pip install ./path-to-wheel-file.whl ## Running tests -Most tests require you to [set up a mock server](https://github.com/stoplightio/prism) against the OpenAPI spec to run the tests. +Most tests require you to [set up a mock server](https://github.com/dgellow/steady) against the OpenAPI spec to run the tests. ```sh -# you will need npm installed -$ npx prism mock path/to/your/openapi.yml +$ ./scripts/mock ``` ```sh diff --git a/LICENSE b/LICENSE index aa84a46..a69fada 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2025 Phoebe + Copyright 2026 Phoebe Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index a1562e0..5827dd7 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,15 @@ and offers both synchronous and asynchronous clients powered by [httpx](https:// It is generated with [Stainless](https://www.stainless.com/). +## MCP Server + +Use the Phoebe MCP Server to enable AI assistants to interact with this API, allowing them to explore endpoints, make test requests, and use documentation to help integrate this SDK into your application. + +[![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=phoebe-ebird-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsInBob2ViZS1lYmlyZC1tY3AiXSwiZW52Ijp7IkVCSVJEX0FQSV9LRVkiOiJNeSBBUEkgS2V5In19) +[![Install in VS Code](https://img.shields.io/badge/_-Add_to_VS_Code-blue?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHBhdGggZmlsbD0iI0VFRSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMzAuMjM1IDM5Ljg4NGEyLjQ5MSAyLjQ5MSAwIDAgMS0xLjc4MS0uNzNMMTIuNyAyNC43OGwtMy40NiAyLjYyNC0zLjQwNiAyLjU4MmExLjY2NSAxLjY2NSAwIDAgMS0xLjA4Mi4zMzggMS42NjQgMS42NjQgMCAwIDEtMS4wNDYtLjQzMWwtMi4yLTJhMS42NjYgMS42NjYgMCAwIDEgMC0yLjQ2M0w3LjQ1OCAyMCA0LjY3IDE3LjQ1MyAxLjUwNyAxNC41N2ExLjY2NSAxLjY2NSAwIDAgMSAwLTIuNDYzbDIuMi0yYTEuNjY1IDEuNjY1IDAgMCAxIDIuMTMtLjA5N2w2Ljg2MyA1LjIwOUwyOC40NTIuODQ0YTIuNDg4IDIuNDg4IDAgMCAxIDEuODQxLS43MjljLjM1MS4wMDkuNjk5LjA5MSAxLjAxOS4yNDVsOC4yMzYgMy45NjFhMi41IDIuNSAwIDAgMSAxLjQxNSAyLjI1M3YuMDk5LS4wNDVWMzMuMzd2LS4wNDUuMDk1YTIuNTAxIDIuNTAxIDAgMCAxLTEuNDE2IDIuMjU3bC04LjIzNSAzLjk2MWEyLjQ5MiAyLjQ5MiAwIDAgMS0xLjA3Ny4yNDZabS43MTYtMjguOTQ3LTExLjk0OCA5LjA2MiAxMS45NTIgOS4wNjUtLjAwNC0xOC4xMjdaIi8+PC9zdmc+)](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22phoebe-ebird-mcp%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22phoebe-ebird-mcp%22%5D%2C%22env%22%3A%7B%22EBIRD_API_KEY%22%3A%22My%20API%20Key%22%7D%7D) + +> Note: You may need to set environment variables in your MCP client. + ## Documentation The REST API documentation can be found on [science.ebird.org](https://science.ebird.org/en/use-ebird-data/download-ebird-data-products). The full API of this library can be found in [api.md](api.md). @@ -17,7 +26,7 @@ The REST API documentation can be found on [science.ebird.org](https://science.e ```sh # install from PyPI -pip install --pre phoebe_bird +pip install '--pre phoebe_bird' ``` ## Usage @@ -77,12 +86,13 @@ You can enable this by installing `aiohttp`: ```sh # install from PyPI -pip install --pre phoebe_bird[aiohttp] +pip install '--pre phoebe_bird[aiohttp]' ``` Then you can enable it by instantiating the client with `http_client=DefaultAioHttpClient()`: ```python +import os import asyncio from phoebe_bird import DefaultAioHttpClient from phoebe_bird import AsyncPhoebe @@ -90,7 +100,7 @@ from phoebe_bird import AsyncPhoebe async def main() -> None: async with AsyncPhoebe( - api_key="My API Key", + api_key=os.environ.get("EBIRD_API_KEY"), # This is the default and can be omitted http_client=DefaultAioHttpClient(), ) as client: info = await client.ref.hotspot.info.retrieve( diff --git a/bin/check-release-environment b/bin/check-release-environment index b845b0f..98d98fb 100644 --- a/bin/check-release-environment +++ b/bin/check-release-environment @@ -2,6 +2,10 @@ errors=() +if [ -z "${RELEASE_PLEASE_TOKEN}" ]; then + errors+=("The RELEASE_PLEASE_TOKEN secret has not been set. Create a fine-grained GitHub PAT and add it as a repository secret.") +fi + if [ -z "${PYPI_TOKEN}" ]; then errors+=("The PYPI_TOKEN secret has not been set. Please set it in either this repository's secrets or your organization secrets.") fi diff --git a/pyproject.toml b/pyproject.toml index 38305f1..248ab2b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,14 +7,16 @@ license = "Apache-2.0" authors = [ { name = "Phoebe", email = "sayornis.phoebe.apis@gmail.com" }, ] + dependencies = [ - "httpx>=0.23.0, <1", - "pydantic>=1.9.0, <3", - "typing-extensions>=4.10, <5", - "anyio>=3.5.0, <5", - "distro>=1.7.0, <2", - "sniffio", + "httpx>=0.23.0, <1", + "pydantic>=1.9.0, <3", + "typing-extensions>=4.14, <5", + "anyio>=3.5.0, <5", + "distro>=1.7.0, <2", + "sniffio", ] + requires-python = ">= 3.9" classifiers = [ "Typing :: Typed", @@ -46,7 +48,7 @@ managed = true # version pins are in requirements-dev.lock dev-dependencies = [ "pyright==1.1.399", - "mypy", + "mypy==1.17", "respx", "pytest", "pytest-asyncio", @@ -67,7 +69,7 @@ format = { chain = [ # run formatting again to fix any inconsistencies when imports are stripped "format:ruff", ]} -"format:docs" = "python scripts/utils/ruffen-docs.py README.md api.md" +"format:docs" = "bash -c 'python scripts/utils/ruffen-docs.py README.md $(find . -type f -name api.md)'" "format:ruff" = "ruff format" "lint" = { chain = [ @@ -166,7 +168,7 @@ show_error_codes = true # # We also exclude our `tests` as mypy doesn't always infer # types correctly and Pyright will still catch any type errors. -exclude = ['src/phoebe_bird/_files.py', '_dev/.*.py', 'tests/.*'] +exclude = ["src/phoebe_bird/_files.py", "_dev/.*.py", "tests/.*"] strict_equality = true implicit_reexport = true diff --git a/release-please-config.json b/release-please-config.json index 521cb7c..85bd35a 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -2,7 +2,7 @@ "packages": { ".": {} }, - "$schema": "https://raw.githubusercontent.com/stainless-api/release-please/main/schemas/config.json", + "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", "include-v-in-tag": true, "include-component-in-tag": false, "versioning": "prerelease", diff --git a/requirements-dev.lock b/requirements-dev.lock index 7aa2b78..7cf2b51 100644 --- a/requirements-dev.lock +++ b/requirements-dev.lock @@ -7,45 +7,49 @@ # all-features: true # with-sources: false # generate-hashes: false -# universal: false -e file:. aiohappyeyeballs==2.6.1 # via aiohttp -aiohttp==3.12.8 +aiohttp==3.13.3 # via httpx-aiohttp # via phoebe-bird -aiosignal==1.3.2 +aiosignal==1.4.0 # via aiohttp -annotated-types==0.6.0 +annotated-types==0.7.0 # via pydantic -anyio==4.4.0 +anyio==4.12.1 # via httpx # via phoebe-bird -argcomplete==3.1.2 +argcomplete==3.6.3 # via nox async-timeout==5.0.1 # via aiohttp -attrs==25.3.0 +attrs==25.4.0 # via aiohttp -certifi==2023.7.22 + # via nox +backports-asyncio-runner==1.2.0 + # via pytest-asyncio +certifi==2026.1.4 # via httpcore # via httpx -colorlog==6.7.0 +colorlog==6.10.1 + # via nox +dependency-groups==1.3.1 # via nox -dirty-equals==0.6.0 -distlib==0.3.7 +dirty-equals==0.11 +distlib==0.4.0 # via virtualenv -distro==1.8.0 +distro==1.9.0 # via phoebe-bird -exceptiongroup==1.2.2 +exceptiongroup==1.3.1 # via anyio # via pytest -execnet==2.1.1 +execnet==2.1.2 # via pytest-xdist -filelock==3.12.4 +filelock==3.19.1 # via virtualenv -frozenlist==1.6.2 +frozenlist==1.8.0 # via aiohttp # via aiosignal h11==0.16.0 @@ -56,82 +60,89 @@ httpx==0.28.1 # via httpx-aiohttp # via phoebe-bird # via respx -httpx-aiohttp==0.1.9 +httpx-aiohttp==0.1.12 # via phoebe-bird -idna==3.4 +humanize==4.13.0 + # via nox +idna==3.11 # via anyio # via httpx # via yarl -importlib-metadata==7.0.0 -iniconfig==2.0.0 +importlib-metadata==8.7.1 +iniconfig==2.1.0 # via pytest markdown-it-py==3.0.0 # via rich mdurl==0.1.2 # via markdown-it-py -multidict==6.4.4 +multidict==6.7.0 # via aiohttp # via yarl -mypy==1.14.1 -mypy-extensions==1.0.0 +mypy==1.17.0 +mypy-extensions==1.1.0 # via mypy -nodeenv==1.8.0 +nodeenv==1.10.0 # via pyright -nox==2023.4.22 -packaging==23.2 +nox==2025.11.12 +packaging==25.0 + # via dependency-groups # via nox # via pytest -platformdirs==3.11.0 +pathspec==1.0.3 + # via mypy +platformdirs==4.4.0 # via virtualenv -pluggy==1.5.0 +pluggy==1.6.0 # via pytest -propcache==0.3.1 +propcache==0.4.1 # via aiohttp # via yarl -pydantic==2.11.9 +pydantic==2.12.5 # via phoebe-bird -pydantic-core==2.33.2 +pydantic-core==2.41.5 # via pydantic -pygments==2.18.0 +pygments==2.19.2 + # via pytest # via rich pyright==1.1.399 -pytest==8.3.3 +pytest==8.4.2 # via pytest-asyncio # via pytest-xdist -pytest-asyncio==0.24.0 -pytest-xdist==3.7.0 -python-dateutil==2.8.2 +pytest-asyncio==1.2.0 +pytest-xdist==3.8.0 +python-dateutil==2.9.0.post0 # via time-machine -pytz==2023.3.post1 - # via dirty-equals respx==0.22.0 -rich==13.7.1 -ruff==0.9.4 -setuptools==68.2.2 - # via nodeenv -six==1.16.0 +rich==14.2.0 +ruff==0.14.13 +six==1.17.0 # via python-dateutil -sniffio==1.3.0 - # via anyio +sniffio==1.3.1 # via phoebe-bird -time-machine==2.9.0 -tomli==2.0.2 +time-machine==2.19.0 +tomli==2.4.0 + # via dependency-groups # via mypy + # via nox # via pytest -typing-extensions==4.12.2 +typing-extensions==4.15.0 + # via aiosignal # via anyio + # via exceptiongroup # via multidict # via mypy # via phoebe-bird # via pydantic # via pydantic-core # via pyright + # via pytest-asyncio # via typing-inspection -typing-inspection==0.4.1 + # via virtualenv +typing-inspection==0.4.2 # via pydantic -virtualenv==20.24.5 +virtualenv==20.36.1 # via nox -yarl==1.20.0 +yarl==1.22.0 # via aiohttp -zipp==3.17.0 +zipp==3.23.0 # via importlib-metadata diff --git a/requirements.lock b/requirements.lock index 53495b6..f926e8b 100644 --- a/requirements.lock +++ b/requirements.lock @@ -7,33 +7,32 @@ # all-features: true # with-sources: false # generate-hashes: false -# universal: false -e file:. aiohappyeyeballs==2.6.1 # via aiohttp -aiohttp==3.12.8 +aiohttp==3.13.3 # via httpx-aiohttp # via phoebe-bird -aiosignal==1.3.2 +aiosignal==1.4.0 # via aiohttp -annotated-types==0.6.0 +annotated-types==0.7.0 # via pydantic -anyio==4.4.0 +anyio==4.12.1 # via httpx # via phoebe-bird async-timeout==5.0.1 # via aiohttp -attrs==25.3.0 +attrs==25.4.0 # via aiohttp -certifi==2023.7.22 +certifi==2026.1.4 # via httpcore # via httpx -distro==1.8.0 +distro==1.9.0 # via phoebe-bird -exceptiongroup==1.2.2 +exceptiongroup==1.3.1 # via anyio -frozenlist==1.6.2 +frozenlist==1.8.0 # via aiohttp # via aiosignal h11==0.16.0 @@ -43,33 +42,34 @@ httpcore==1.0.9 httpx==0.28.1 # via httpx-aiohttp # via phoebe-bird -httpx-aiohttp==0.1.9 +httpx-aiohttp==0.1.12 # via phoebe-bird -idna==3.4 +idna==3.11 # via anyio # via httpx # via yarl -multidict==6.4.4 +multidict==6.7.0 # via aiohttp # via yarl -propcache==0.3.1 +propcache==0.4.1 # via aiohttp # via yarl -pydantic==2.11.9 +pydantic==2.12.5 # via phoebe-bird -pydantic-core==2.33.2 +pydantic-core==2.41.5 # via pydantic -sniffio==1.3.0 - # via anyio +sniffio==1.3.1 # via phoebe-bird -typing-extensions==4.12.2 +typing-extensions==4.15.0 + # via aiosignal # via anyio + # via exceptiongroup # via multidict # via phoebe-bird # via pydantic # via pydantic-core # via typing-inspection -typing-inspection==0.4.1 +typing-inspection==0.4.2 # via pydantic -yarl==1.20.0 +yarl==1.22.0 # via aiohttp diff --git a/scripts/bootstrap b/scripts/bootstrap index b430fee..fe8451e 100755 --- a/scripts/bootstrap +++ b/scripts/bootstrap @@ -4,7 +4,7 @@ set -e cd "$(dirname "$0")/.." -if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "$SKIP_BREW" != "1" ] && [ -t 0 ]; then +if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "${SKIP_BREW:-}" != "1" ] && [ -t 0 ]; then brew bundle check >/dev/null 2>&1 || { echo -n "==> Install Homebrew dependencies? (y/N): " read -r response diff --git a/scripts/lint b/scripts/lint index fcfc441..a8a480e 100755 --- a/scripts/lint +++ b/scripts/lint @@ -4,8 +4,13 @@ set -e cd "$(dirname "$0")/.." -echo "==> Running lints" -rye run lint +if [ "$1" = "--fix" ]; then + echo "==> Running lints with --fix" + rye run fix:ruff +else + echo "==> Running lints" + rye run lint +fi echo "==> Making sure it imports" rye run python -c 'import phoebe_bird' diff --git a/scripts/mock b/scripts/mock index 0b28f6e..d0666ff 100755 --- a/scripts/mock +++ b/scripts/mock @@ -7,35 +7,47 @@ cd "$(dirname "$0")/.." if [[ -n "$1" && "$1" != '--'* ]]; then URL="$1" shift +elif [ -n "$STAINLESS_OPENAPI_SPEC_URL" ]; then + URL="$STAINLESS_OPENAPI_SPEC_URL" else - URL="$(grep 'openapi_spec_url' .stats.yml | cut -d' ' -f2)" -fi - -# Check if the URL is empty -if [ -z "$URL" ]; then - echo "Error: No OpenAPI spec path/url provided or found in .stats.yml" - exit 1 + # Embedded OpenAPI spec (base64-encoded, gzipped) + EMBEDDED_SPEC="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" + SPEC_TMPFILE="$(mktemp)" + trap 'rm -f "$SPEC_TMPFILE"' EXIT + echo "$EMBEDDED_SPEC" | base64 --decode | gunzip > "$SPEC_TMPFILE" + URL="$SPEC_TMPFILE" fi echo "==> Starting mock server with URL ${URL}" -# Run prism mock on the given spec +# Run steady mock on the given spec if [ "$1" == "--daemon" ]; then - npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" &> .prism.log & + # Pre-install the package so the download doesn't eat into the startup timeout + npm exec --package=@stdy/cli@0.22.1 -- steady --version - # Wait for server to come online + npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" &> .stdy.log & + + # Wait for server to come online via health endpoint (max 30s) echo -n "Waiting for server" - while ! grep -q "✖ fatal\|Prism is listening" ".prism.log" ; do + attempts=0 + while ! curl --silent --fail "http://127.0.0.1:4010/_x-steady/health" >/dev/null 2>&1; do + if ! kill -0 $! 2>/dev/null; then + echo + cat .stdy.log + exit 1 + fi + attempts=$((attempts + 1)) + if [ "$attempts" -ge 300 ]; then + echo + echo "Timed out waiting for Steady server to start" + cat .stdy.log + exit 1 + fi echo -n "." sleep 0.1 done - if grep -q "✖ fatal" ".prism.log"; then - cat .prism.log - exit 1 - fi - echo else - npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" + npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" fi diff --git a/scripts/test b/scripts/test index dbeda2d..19acc91 100755 --- a/scripts/test +++ b/scripts/test @@ -9,8 +9,8 @@ GREEN='\033[0;32m' YELLOW='\033[0;33m' NC='\033[0m' # No Color -function prism_is_running() { - curl --silent "http://localhost:4010" >/dev/null 2>&1 +function steady_is_running() { + curl --silent "http://127.0.0.1:4010/_x-steady/health" >/dev/null 2>&1 } kill_server_on_port() { @@ -25,7 +25,7 @@ function is_overriding_api_base_url() { [ -n "$TEST_API_BASE_URL" ] } -if ! is_overriding_api_base_url && ! prism_is_running ; then +if ! is_overriding_api_base_url && ! steady_is_running ; then # When we exit this script, make sure to kill the background mock server process trap 'kill_server_on_port 4010' EXIT @@ -36,19 +36,19 @@ fi if is_overriding_api_base_url ; then echo -e "${GREEN}✔ Running tests against ${TEST_API_BASE_URL}${NC}" echo -elif ! prism_is_running ; then - echo -e "${RED}ERROR:${NC} The test suite will not run without a mock Prism server" +elif ! steady_is_running ; then + echo -e "${RED}ERROR:${NC} The test suite will not run without a mock Steady server" echo -e "running against your OpenAPI spec." echo echo -e "To run the server, pass in the path or url of your OpenAPI" - echo -e "spec to the prism command:" + echo -e "spec to the steady command:" echo - echo -e " \$ ${YELLOW}npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock path/to/your.openapi.yml${NC}" + echo -e " \$ ${YELLOW}npm exec --package=@stdy/cli@0.22.1 -- steady path/to/your.openapi.yml --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets${NC}" echo exit 1 else - echo -e "${GREEN}✔ Mock prism server is running with your OpenAPI spec${NC}" + echo -e "${GREEN}✔ Mock steady server is running with your OpenAPI spec${NC}" echo fi diff --git a/scripts/utils/upload-artifact.sh b/scripts/utils/upload-artifact.sh index 00aeb78..bc44d0e 100755 --- a/scripts/utils/upload-artifact.sh +++ b/scripts/utils/upload-artifact.sh @@ -20,7 +20,7 @@ UPLOAD_RESPONSE=$(curl -v -X PUT \ if echo "$UPLOAD_RESPONSE" | grep -q "HTTP/[0-9.]* 200"; then echo -e "\033[32mUploaded build to Stainless storage.\033[0m" - echo -e "\033[32mInstallation: pip install 'https://pkg.stainless.com/s/phoebe-python/$SHA/$FILENAME'\033[0m" + echo -e "\033[32mInstallation: pip install 'https://pkg.stainless.com/s/phoebe-python-staging/$SHA/$FILENAME'\033[0m" else echo -e "\033[31mFailed to upload artifact.\033[0m" exit 1 diff --git a/src/phoebe_bird/_base_client.py b/src/phoebe_bird/_base_client.py index 5571519..e990911 100644 --- a/src/phoebe_bird/_base_client.py +++ b/src/phoebe_bird/_base_client.py @@ -9,6 +9,7 @@ import inspect import logging import platform +import warnings import email.utils from types import TracebackType from random import random @@ -51,9 +52,11 @@ ResponseT, AnyMapping, PostParser, + BinaryTypes, RequestFiles, HttpxSendArgs, RequestOptions, + AsyncBinaryTypes, HttpxRequestFiles, ModelBuilderProtocol, not_given, @@ -83,6 +86,7 @@ APIConnectionError, APIResponseValidationError, ) +from ._utils._json import openapi_dumps log: logging.Logger = logging.getLogger(__name__) @@ -477,8 +481,19 @@ def _build_request( retries_taken: int = 0, ) -> httpx.Request: if log.isEnabledFor(logging.DEBUG): - log.debug("Request options: %s", model_dump(options, exclude_unset=True)) - + log.debug( + "Request options: %s", + model_dump( + options, + exclude_unset=True, + # Pydantic v1 can't dump every type we support in content, so we exclude it for now. + exclude={ + "content", + } + if PYDANTIC_V1 + else {}, + ), + ) kwargs: dict[str, Any] = {} json_data = options.json_data @@ -525,6 +540,10 @@ def _build_request( files = cast(HttpxRequestFiles, ForceMultipartDict()) prepared_url = self._prepare_url(options.url) + # preserve hard-coded query params from the url + if params and prepared_url.query: + params = {**dict(prepared_url.params.items()), **params} + prepared_url = prepared_url.copy_with(raw_path=prepared_url.raw_path.split(b"?", 1)[0]) if "_" in prepared_url.host: # work around https://github.com/encode/httpx/discussions/2880 kwargs["extensions"] = {"sni_hostname": prepared_url.host.replace("_", "-")} @@ -532,10 +551,18 @@ def _build_request( is_body_allowed = options.method.lower() != "get" if is_body_allowed: - if isinstance(json_data, bytes): + if options.content is not None and json_data is not None: + raise TypeError("Passing both `content` and `json_data` is not supported") + if options.content is not None and files is not None: + raise TypeError("Passing both `content` and `files` is not supported") + if options.content is not None: + kwargs["content"] = options.content + elif isinstance(json_data, bytes): kwargs["content"] = json_data - else: - kwargs["json"] = json_data if is_given(json_data) else None + elif not files: + # Don't set content when JSON is sent as multipart/form-data, + # since httpx's content param overrides other body arguments + kwargs["content"] = openapi_dumps(json_data) if is_given(json_data) and json_data is not None else None kwargs["files"] = files else: headers.pop("Content-Type", None) @@ -1194,6 +1221,7 @@ def post( *, cast_to: Type[ResponseT], body: Body | None = None, + content: BinaryTypes | None = None, options: RequestOptions = {}, files: RequestFiles | None = None, stream: Literal[False] = False, @@ -1206,6 +1234,7 @@ def post( *, cast_to: Type[ResponseT], body: Body | None = None, + content: BinaryTypes | None = None, options: RequestOptions = {}, files: RequestFiles | None = None, stream: Literal[True], @@ -1219,6 +1248,7 @@ def post( *, cast_to: Type[ResponseT], body: Body | None = None, + content: BinaryTypes | None = None, options: RequestOptions = {}, files: RequestFiles | None = None, stream: bool, @@ -1231,13 +1261,25 @@ def post( *, cast_to: Type[ResponseT], body: Body | None = None, + content: BinaryTypes | None = None, options: RequestOptions = {}, files: RequestFiles | None = None, stream: bool = False, stream_cls: type[_StreamT] | None = None, ) -> ResponseT | _StreamT: + if body is not None and content is not None: + raise TypeError("Passing both `body` and `content` is not supported") + if files is not None and content is not None: + raise TypeError("Passing both `files` and `content` is not supported") + if isinstance(body, bytes): + warnings.warn( + "Passing raw bytes as `body` is deprecated and will be removed in a future version. " + "Please pass raw bytes via the `content` parameter instead.", + DeprecationWarning, + stacklevel=2, + ) opts = FinalRequestOptions.construct( - method="post", url=path, json_data=body, files=to_httpx_files(files), **options + method="post", url=path, json_data=body, content=content, files=to_httpx_files(files), **options ) return cast(ResponseT, self.request(cast_to, opts, stream=stream, stream_cls=stream_cls)) @@ -1247,9 +1289,24 @@ def patch( *, cast_to: Type[ResponseT], body: Body | None = None, + content: BinaryTypes | None = None, + files: RequestFiles | None = None, options: RequestOptions = {}, ) -> ResponseT: - opts = FinalRequestOptions.construct(method="patch", url=path, json_data=body, **options) + if body is not None and content is not None: + raise TypeError("Passing both `body` and `content` is not supported") + if files is not None and content is not None: + raise TypeError("Passing both `files` and `content` is not supported") + if isinstance(body, bytes): + warnings.warn( + "Passing raw bytes as `body` is deprecated and will be removed in a future version. " + "Please pass raw bytes via the `content` parameter instead.", + DeprecationWarning, + stacklevel=2, + ) + opts = FinalRequestOptions.construct( + method="patch", url=path, json_data=body, content=content, files=to_httpx_files(files), **options + ) return self.request(cast_to, opts) def put( @@ -1258,11 +1315,23 @@ def put( *, cast_to: Type[ResponseT], body: Body | None = None, + content: BinaryTypes | None = None, files: RequestFiles | None = None, options: RequestOptions = {}, ) -> ResponseT: + if body is not None and content is not None: + raise TypeError("Passing both `body` and `content` is not supported") + if files is not None and content is not None: + raise TypeError("Passing both `files` and `content` is not supported") + if isinstance(body, bytes): + warnings.warn( + "Passing raw bytes as `body` is deprecated and will be removed in a future version. " + "Please pass raw bytes via the `content` parameter instead.", + DeprecationWarning, + stacklevel=2, + ) opts = FinalRequestOptions.construct( - method="put", url=path, json_data=body, files=to_httpx_files(files), **options + method="put", url=path, json_data=body, content=content, files=to_httpx_files(files), **options ) return self.request(cast_to, opts) @@ -1272,9 +1341,19 @@ def delete( *, cast_to: Type[ResponseT], body: Body | None = None, + content: BinaryTypes | None = None, options: RequestOptions = {}, ) -> ResponseT: - opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, **options) + if body is not None and content is not None: + raise TypeError("Passing both `body` and `content` is not supported") + if isinstance(body, bytes): + warnings.warn( + "Passing raw bytes as `body` is deprecated and will be removed in a future version. " + "Please pass raw bytes via the `content` parameter instead.", + DeprecationWarning, + stacklevel=2, + ) + opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, content=content, **options) return self.request(cast_to, opts) def get_api_list( @@ -1714,6 +1793,7 @@ async def post( *, cast_to: Type[ResponseT], body: Body | None = None, + content: AsyncBinaryTypes | None = None, files: RequestFiles | None = None, options: RequestOptions = {}, stream: Literal[False] = False, @@ -1726,6 +1806,7 @@ async def post( *, cast_to: Type[ResponseT], body: Body | None = None, + content: AsyncBinaryTypes | None = None, files: RequestFiles | None = None, options: RequestOptions = {}, stream: Literal[True], @@ -1739,6 +1820,7 @@ async def post( *, cast_to: Type[ResponseT], body: Body | None = None, + content: AsyncBinaryTypes | None = None, files: RequestFiles | None = None, options: RequestOptions = {}, stream: bool, @@ -1751,13 +1833,25 @@ async def post( *, cast_to: Type[ResponseT], body: Body | None = None, + content: AsyncBinaryTypes | None = None, files: RequestFiles | None = None, options: RequestOptions = {}, stream: bool = False, stream_cls: type[_AsyncStreamT] | None = None, ) -> ResponseT | _AsyncStreamT: + if body is not None and content is not None: + raise TypeError("Passing both `body` and `content` is not supported") + if files is not None and content is not None: + raise TypeError("Passing both `files` and `content` is not supported") + if isinstance(body, bytes): + warnings.warn( + "Passing raw bytes as `body` is deprecated and will be removed in a future version. " + "Please pass raw bytes via the `content` parameter instead.", + DeprecationWarning, + stacklevel=2, + ) opts = FinalRequestOptions.construct( - method="post", url=path, json_data=body, files=await async_to_httpx_files(files), **options + method="post", url=path, json_data=body, content=content, files=await async_to_httpx_files(files), **options ) return await self.request(cast_to, opts, stream=stream, stream_cls=stream_cls) @@ -1767,9 +1861,29 @@ async def patch( *, cast_to: Type[ResponseT], body: Body | None = None, + content: AsyncBinaryTypes | None = None, + files: RequestFiles | None = None, options: RequestOptions = {}, ) -> ResponseT: - opts = FinalRequestOptions.construct(method="patch", url=path, json_data=body, **options) + if body is not None and content is not None: + raise TypeError("Passing both `body` and `content` is not supported") + if files is not None and content is not None: + raise TypeError("Passing both `files` and `content` is not supported") + if isinstance(body, bytes): + warnings.warn( + "Passing raw bytes as `body` is deprecated and will be removed in a future version. " + "Please pass raw bytes via the `content` parameter instead.", + DeprecationWarning, + stacklevel=2, + ) + opts = FinalRequestOptions.construct( + method="patch", + url=path, + json_data=body, + content=content, + files=await async_to_httpx_files(files), + **options, + ) return await self.request(cast_to, opts) async def put( @@ -1778,11 +1892,23 @@ async def put( *, cast_to: Type[ResponseT], body: Body | None = None, + content: AsyncBinaryTypes | None = None, files: RequestFiles | None = None, options: RequestOptions = {}, ) -> ResponseT: + if body is not None and content is not None: + raise TypeError("Passing both `body` and `content` is not supported") + if files is not None and content is not None: + raise TypeError("Passing both `files` and `content` is not supported") + if isinstance(body, bytes): + warnings.warn( + "Passing raw bytes as `body` is deprecated and will be removed in a future version. " + "Please pass raw bytes via the `content` parameter instead.", + DeprecationWarning, + stacklevel=2, + ) opts = FinalRequestOptions.construct( - method="put", url=path, json_data=body, files=await async_to_httpx_files(files), **options + method="put", url=path, json_data=body, content=content, files=await async_to_httpx_files(files), **options ) return await self.request(cast_to, opts) @@ -1792,9 +1918,19 @@ async def delete( *, cast_to: Type[ResponseT], body: Body | None = None, + content: AsyncBinaryTypes | None = None, options: RequestOptions = {}, ) -> ResponseT: - opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, **options) + if body is not None and content is not None: + raise TypeError("Passing both `body` and `content` is not supported") + if isinstance(body, bytes): + warnings.warn( + "Passing raw bytes as `body` is deprecated and will be removed in a future version. " + "Please pass raw bytes via the `content` parameter instead.", + DeprecationWarning, + stacklevel=2, + ) + opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, content=content, **options) return await self.request(cast_to, opts) def get_api_list( diff --git a/src/phoebe_bird/_client.py b/src/phoebe_bird/_client.py index 0805103..48ecf10 100644 --- a/src/phoebe_bird/_client.py +++ b/src/phoebe_bird/_client.py @@ -3,7 +3,7 @@ from __future__ import annotations import os -from typing import Any, Mapping +from typing import TYPE_CHECKING, Any, Mapping from typing_extensions import Self, override import httpx @@ -19,7 +19,12 @@ RequestOptions, not_given, ) -from ._utils import is_given, get_async_library +from ._utils import ( + is_given, + is_mapping_t, + get_async_library, +) +from ._compat import cached_property from ._version import __version__ from ._streaming import Stream as Stream, AsyncStream as AsyncStream from ._exceptions import PhoebeError, APIStatusError @@ -28,20 +33,17 @@ SyncAPIClient, AsyncAPIClient, ) -from .resources.ref import ref -from .resources.data import data -from .resources.product import product + +if TYPE_CHECKING: + from .resources import ref, data, product + from .resources.ref.ref import RefResource, AsyncRefResource + from .resources.data.data import DataResource, AsyncDataResource + from .resources.product.product import ProductResource, AsyncProductResource __all__ = ["Timeout", "Transport", "ProxiesTypes", "RequestOptions", "Phoebe", "AsyncPhoebe", "Client", "AsyncClient"] class Phoebe(SyncAPIClient): - data: data.DataResource - product: product.ProductResource - ref: ref.RefResource - with_raw_response: PhoebeWithRawResponse - with_streaming_response: PhoebeWithStreamedResponse - # client options api_key: str @@ -85,6 +87,15 @@ def __init__( if base_url is None: base_url = f"https://api.ebird.org/v2" + custom_headers_env = os.environ.get("PHOEBE_CUSTOM_HEADERS") + if custom_headers_env is not None: + parsed: dict[str, str] = {} + for line in custom_headers_env.split("\n"): + colon = line.find(":") + if colon >= 0: + parsed[line[:colon].strip()] = line[colon + 1 :].strip() + default_headers = {**parsed, **(default_headers if is_mapping_t(default_headers) else {})} + super().__init__( version=__version__, base_url=base_url, @@ -96,11 +107,31 @@ def __init__( _strict_response_validation=_strict_response_validation, ) - self.data = data.DataResource(self) - self.product = product.ProductResource(self) - self.ref = ref.RefResource(self) - self.with_raw_response = PhoebeWithRawResponse(self) - self.with_streaming_response = PhoebeWithStreamedResponse(self) + @cached_property + def data(self) -> DataResource: + from .resources.data import DataResource + + return DataResource(self) + + @cached_property + def product(self) -> ProductResource: + from .resources.product import ProductResource + + return ProductResource(self) + + @cached_property + def ref(self) -> RefResource: + from .resources.ref import RefResource + + return RefResource(self) + + @cached_property + def with_raw_response(self) -> PhoebeWithRawResponse: + return PhoebeWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> PhoebeWithStreamedResponse: + return PhoebeWithStreamedResponse(self) @property @override @@ -208,12 +239,6 @@ def _make_status_error( class AsyncPhoebe(AsyncAPIClient): - data: data.AsyncDataResource - product: product.AsyncProductResource - ref: ref.AsyncRefResource - with_raw_response: AsyncPhoebeWithRawResponse - with_streaming_response: AsyncPhoebeWithStreamedResponse - # client options api_key: str @@ -257,6 +282,15 @@ def __init__( if base_url is None: base_url = f"https://api.ebird.org/v2" + custom_headers_env = os.environ.get("PHOEBE_CUSTOM_HEADERS") + if custom_headers_env is not None: + parsed: dict[str, str] = {} + for line in custom_headers_env.split("\n"): + colon = line.find(":") + if colon >= 0: + parsed[line[:colon].strip()] = line[colon + 1 :].strip() + default_headers = {**parsed, **(default_headers if is_mapping_t(default_headers) else {})} + super().__init__( version=__version__, base_url=base_url, @@ -268,11 +302,31 @@ def __init__( _strict_response_validation=_strict_response_validation, ) - self.data = data.AsyncDataResource(self) - self.product = product.AsyncProductResource(self) - self.ref = ref.AsyncRefResource(self) - self.with_raw_response = AsyncPhoebeWithRawResponse(self) - self.with_streaming_response = AsyncPhoebeWithStreamedResponse(self) + @cached_property + def data(self) -> AsyncDataResource: + from .resources.data import AsyncDataResource + + return AsyncDataResource(self) + + @cached_property + def product(self) -> AsyncProductResource: + from .resources.product import AsyncProductResource + + return AsyncProductResource(self) + + @cached_property + def ref(self) -> AsyncRefResource: + from .resources.ref import AsyncRefResource + + return AsyncRefResource(self) + + @cached_property + def with_raw_response(self) -> AsyncPhoebeWithRawResponse: + return AsyncPhoebeWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncPhoebeWithStreamedResponse: + return AsyncPhoebeWithStreamedResponse(self) @property @override @@ -380,31 +434,103 @@ def _make_status_error( class PhoebeWithRawResponse: + _client: Phoebe + def __init__(self, client: Phoebe) -> None: - self.data = data.DataResourceWithRawResponse(client.data) - self.product = product.ProductResourceWithRawResponse(client.product) - self.ref = ref.RefResourceWithRawResponse(client.ref) + self._client = client + + @cached_property + def data(self) -> data.DataResourceWithRawResponse: + from .resources.data import DataResourceWithRawResponse + + return DataResourceWithRawResponse(self._client.data) + + @cached_property + def product(self) -> product.ProductResourceWithRawResponse: + from .resources.product import ProductResourceWithRawResponse + + return ProductResourceWithRawResponse(self._client.product) + + @cached_property + def ref(self) -> ref.RefResourceWithRawResponse: + from .resources.ref import RefResourceWithRawResponse + + return RefResourceWithRawResponse(self._client.ref) class AsyncPhoebeWithRawResponse: + _client: AsyncPhoebe + def __init__(self, client: AsyncPhoebe) -> None: - self.data = data.AsyncDataResourceWithRawResponse(client.data) - self.product = product.AsyncProductResourceWithRawResponse(client.product) - self.ref = ref.AsyncRefResourceWithRawResponse(client.ref) + self._client = client + + @cached_property + def data(self) -> data.AsyncDataResourceWithRawResponse: + from .resources.data import AsyncDataResourceWithRawResponse + + return AsyncDataResourceWithRawResponse(self._client.data) + + @cached_property + def product(self) -> product.AsyncProductResourceWithRawResponse: + from .resources.product import AsyncProductResourceWithRawResponse + + return AsyncProductResourceWithRawResponse(self._client.product) + + @cached_property + def ref(self) -> ref.AsyncRefResourceWithRawResponse: + from .resources.ref import AsyncRefResourceWithRawResponse + + return AsyncRefResourceWithRawResponse(self._client.ref) class PhoebeWithStreamedResponse: + _client: Phoebe + def __init__(self, client: Phoebe) -> None: - self.data = data.DataResourceWithStreamingResponse(client.data) - self.product = product.ProductResourceWithStreamingResponse(client.product) - self.ref = ref.RefResourceWithStreamingResponse(client.ref) + self._client = client + + @cached_property + def data(self) -> data.DataResourceWithStreamingResponse: + from .resources.data import DataResourceWithStreamingResponse + + return DataResourceWithStreamingResponse(self._client.data) + + @cached_property + def product(self) -> product.ProductResourceWithStreamingResponse: + from .resources.product import ProductResourceWithStreamingResponse + + return ProductResourceWithStreamingResponse(self._client.product) + + @cached_property + def ref(self) -> ref.RefResourceWithStreamingResponse: + from .resources.ref import RefResourceWithStreamingResponse + + return RefResourceWithStreamingResponse(self._client.ref) class AsyncPhoebeWithStreamedResponse: + _client: AsyncPhoebe + def __init__(self, client: AsyncPhoebe) -> None: - self.data = data.AsyncDataResourceWithStreamingResponse(client.data) - self.product = product.AsyncProductResourceWithStreamingResponse(client.product) - self.ref = ref.AsyncRefResourceWithStreamingResponse(client.ref) + self._client = client + + @cached_property + def data(self) -> data.AsyncDataResourceWithStreamingResponse: + from .resources.data import AsyncDataResourceWithStreamingResponse + + return AsyncDataResourceWithStreamingResponse(self._client.data) + + @cached_property + def product(self) -> product.AsyncProductResourceWithStreamingResponse: + from .resources.product import AsyncProductResourceWithStreamingResponse + + return AsyncProductResourceWithStreamingResponse(self._client.product) + + @cached_property + def ref(self) -> ref.AsyncRefResourceWithStreamingResponse: + from .resources.ref import AsyncRefResourceWithStreamingResponse + + return AsyncRefResourceWithStreamingResponse(self._client.ref) Client = Phoebe diff --git a/src/phoebe_bird/_compat.py b/src/phoebe_bird/_compat.py index bdef67f..e6690a4 100644 --- a/src/phoebe_bird/_compat.py +++ b/src/phoebe_bird/_compat.py @@ -2,7 +2,7 @@ from typing import TYPE_CHECKING, Any, Union, Generic, TypeVar, Callable, cast, overload from datetime import date, datetime -from typing_extensions import Self, Literal +from typing_extensions import Self, Literal, TypedDict import pydantic from pydantic.fields import FieldInfo @@ -131,6 +131,10 @@ def model_json(model: pydantic.BaseModel, *, indent: int | None = None) -> str: return model.model_dump_json(indent=indent) +class _ModelDumpKwargs(TypedDict, total=False): + by_alias: bool + + def model_dump( model: pydantic.BaseModel, *, @@ -139,8 +143,12 @@ def model_dump( exclude_defaults: bool = False, warnings: bool = True, mode: Literal["json", "python"] = "python", + by_alias: bool | None = None, ) -> dict[str, Any]: if (not PYDANTIC_V1) or hasattr(model, "model_dump"): + kwargs: _ModelDumpKwargs = {} + if by_alias is not None: + kwargs["by_alias"] = by_alias return model.model_dump( mode=mode, exclude=exclude, @@ -148,13 +156,12 @@ def model_dump( exclude_defaults=exclude_defaults, # warnings are not supported in Pydantic v1 warnings=True if PYDANTIC_V1 else warnings, + **kwargs, ) return cast( "dict[str, Any]", model.dict( # pyright: ignore[reportDeprecated, reportUnnecessaryCast] - exclude=exclude, - exclude_unset=exclude_unset, - exclude_defaults=exclude_defaults, + exclude=exclude, exclude_unset=exclude_unset, exclude_defaults=exclude_defaults, by_alias=bool(by_alias) ), ) diff --git a/src/phoebe_bird/_files.py b/src/phoebe_bird/_files.py index cc14c14..76da9e0 100644 --- a/src/phoebe_bird/_files.py +++ b/src/phoebe_bird/_files.py @@ -3,8 +3,8 @@ import io import os import pathlib -from typing import overload -from typing_extensions import TypeGuard +from typing import Sequence, cast, overload +from typing_extensions import TypeVar, TypeGuard import anyio @@ -17,7 +17,9 @@ HttpxFileContent, HttpxRequestFiles, ) -from ._utils import is_tuple_t, is_mapping_t, is_sequence_t +from ._utils import is_list, is_mapping, is_tuple_t, is_mapping_t, is_sequence_t + +_T = TypeVar("_T") def is_base64_file_input(obj: object) -> TypeGuard[Base64FileInput]: @@ -97,7 +99,7 @@ async def async_to_httpx_files(files: RequestFiles | None) -> HttpxRequestFiles elif is_sequence_t(files): files = [(key, await _async_transform_file(file)) for key, file in files] else: - raise TypeError("Unexpected file type input {type(files)}, expected mapping or sequence") + raise TypeError(f"Unexpected file type input {type(files)}, expected mapping or sequence") return files @@ -121,3 +123,51 @@ async def async_read_file_content(file: FileContent) -> HttpxFileContent: return await anyio.Path(file).read_bytes() return file + + +def deepcopy_with_paths(item: _T, paths: Sequence[Sequence[str]]) -> _T: + """Copy only the containers along the given paths. + + Used to guard against mutation by extract_files without copying the entire structure. + Only dicts and lists that lie on a path are copied; everything else + is returned by reference. + + For example, given paths=[["foo", "files", "file"]] and the structure: + { + "foo": { + "bar": {"baz": {}}, + "files": {"file": } + } + } + The root dict, "foo", and "files" are copied (they lie on the path). + "bar" and "baz" are returned by reference (off the path). + """ + return _deepcopy_with_paths(item, paths, 0) + + +def _deepcopy_with_paths(item: _T, paths: Sequence[Sequence[str]], index: int) -> _T: + if not paths: + return item + if is_mapping(item): + key_to_paths: dict[str, list[Sequence[str]]] = {} + for path in paths: + if index < len(path): + key_to_paths.setdefault(path[index], []).append(path) + + # if no path continues through this mapping, it won't be mutated and copying it is redundant + if not key_to_paths: + return item + + result = dict(item) + for key, subpaths in key_to_paths.items(): + if key in result: + result[key] = _deepcopy_with_paths(result[key], subpaths, index + 1) + return cast(_T, result) + if is_list(item): + array_paths = [path for path in paths if index < len(path) and path[index] == ""] + + # if no path expects a list here, nothing will be mutated inside it - return by reference + if not array_paths: + return cast(_T, item) + return cast(_T, [_deepcopy_with_paths(entry, array_paths, index + 1) for entry in item]) + return item diff --git a/src/phoebe_bird/_models.py b/src/phoebe_bird/_models.py index ca9500b..8c5ab26 100644 --- a/src/phoebe_bird/_models.py +++ b/src/phoebe_bird/_models.py @@ -3,7 +3,20 @@ import os import inspect import weakref -from typing import TYPE_CHECKING, Any, Type, Union, Generic, TypeVar, Callable, Optional, cast +from typing import ( + IO, + TYPE_CHECKING, + Any, + Type, + Union, + Generic, + TypeVar, + Callable, + Iterable, + Optional, + AsyncIterable, + cast, +) from datetime import date, datetime from typing_extensions import ( List, @@ -12,7 +25,9 @@ ClassVar, Protocol, Required, + Annotated, ParamSpec, + TypeAlias, TypedDict, TypeGuard, final, @@ -66,7 +81,15 @@ from ._constants import RAW_RESPONSE_HEADER if TYPE_CHECKING: + from pydantic import GetCoreSchemaHandler, ValidatorFunctionWrapHandler + from pydantic_core import CoreSchema, core_schema from pydantic_core.core_schema import ModelField, ModelSchema, LiteralSchema, ModelFieldsSchema +else: + try: + from pydantic_core import CoreSchema, core_schema + except ImportError: + CoreSchema = None + core_schema = None __all__ = ["BaseModel", "GenericModel"] @@ -383,6 +406,76 @@ def model_dump_json( ) +class _EagerIterable(list[_T], Generic[_T]): + """ + Accepts any Iterable[T] input (including generators), consumes it + eagerly, and validates all items upfront. + + Validation preserves the original container type where possible + (e.g. a set[T] stays a set[T]). Serialization (model_dump / JSON) + always emits a list — round-tripping through model_dump() will not + restore the original container type. + """ + + @classmethod + def __get_pydantic_core_schema__( + cls, + source_type: Any, + handler: GetCoreSchemaHandler, + ) -> CoreSchema: + (item_type,) = get_args(source_type) or (Any,) + item_schema: CoreSchema = handler.generate_schema(item_type) + list_of_items_schema: CoreSchema = core_schema.list_schema(item_schema) + + return core_schema.no_info_wrap_validator_function( + cls._validate, + list_of_items_schema, + serialization=core_schema.plain_serializer_function_ser_schema( + cls._serialize, + info_arg=False, + ), + ) + + @staticmethod + def _validate(v: Iterable[_T], handler: "ValidatorFunctionWrapHandler") -> Any: + original_type: type[Any] = type(v) + + # Normalize to list so list_schema can validate each item + if isinstance(v, list): + items: list[_T] = v + else: + try: + items = list(v) + except TypeError as e: + raise TypeError("Value is not iterable") from e + + # Validate items against the inner schema + validated: list[_T] = handler(items) + + # Reconstruct original container type + if original_type is list: + return validated + # str(list) produces the list's repr, not a string built from items, + # so skip reconstruction for str and its subclasses. + if issubclass(original_type, str): + return validated + try: + return original_type(validated) + except (TypeError, ValueError): + # If the type cannot be reconstructed, just return the validated list + return validated + + @staticmethod + def _serialize(v: Iterable[_T]) -> list[_T]: + """Always serialize as a list so Pydantic's JSON encoder is happy.""" + if isinstance(v, list): + return v + return list(v) + + +EagerIterable: TypeAlias = Annotated[Iterable[_T], _EagerIterable] + + def _construct_field(value: object, field: FieldInfo, key: str) -> object: if value is None: return field_get_default(field) @@ -787,6 +880,7 @@ class FinalRequestOptionsInput(TypedDict, total=False): timeout: float | Timeout | None files: HttpxRequestFiles | None idempotency_key: str + content: Union[bytes, bytearray, IO[bytes], Iterable[bytes], AsyncIterable[bytes], None] json_data: Body extra_json: AnyMapping follow_redirects: bool @@ -805,6 +899,7 @@ class FinalRequestOptions(pydantic.BaseModel): post_parser: Union[Callable[[Any], Any], NotGiven] = NotGiven() follow_redirects: Union[bool, None] = None + content: Union[bytes, bytearray, IO[bytes], Iterable[bytes], AsyncIterable[bytes], None] = None # It should be noted that we cannot use `json` here as that would override # a BaseModel method in an incompatible fashion. json_data: Union[Body, None] = None diff --git a/src/phoebe_bird/_qs.py b/src/phoebe_bird/_qs.py index ada6fd3..4127c19 100644 --- a/src/phoebe_bird/_qs.py +++ b/src/phoebe_bird/_qs.py @@ -2,17 +2,13 @@ from typing import Any, List, Tuple, Union, Mapping, TypeVar from urllib.parse import parse_qs, urlencode -from typing_extensions import Literal, get_args +from typing_extensions import get_args -from ._types import NotGiven, not_given +from ._types import NotGiven, ArrayFormat, NestedFormat, not_given from ._utils import flatten _T = TypeVar("_T") - -ArrayFormat = Literal["comma", "repeat", "indices", "brackets"] -NestedFormat = Literal["dots", "brackets"] - PrimitiveData = Union[str, int, float, bool, None] # this should be Data = Union[PrimitiveData, "List[Data]", "Tuple[Data]", "Mapping[str, Data]"] # https://github.com/microsoft/pyright/issues/3555 @@ -101,7 +97,10 @@ def _stringify_item( items.extend(self._stringify_item(key, item, opts)) return items elif array_format == "indices": - raise NotImplementedError("The array indices format is not supported yet") + items = [] + for i, item in enumerate(value): + items.extend(self._stringify_item(f"{key}[{i}]", item, opts)) + return items elif array_format == "brackets": items = [] key = key + "[]" diff --git a/src/phoebe_bird/_response.py b/src/phoebe_bird/_response.py index dd6cad2..2e97a79 100644 --- a/src/phoebe_bird/_response.py +++ b/src/phoebe_bird/_response.py @@ -152,6 +152,7 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T: ), response=self.http_response, client=cast(Any, self._client), + options=self._options, ), ) @@ -162,6 +163,7 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T: cast_to=extract_stream_chunk_type(self._stream_cls), response=self.http_response, client=cast(Any, self._client), + options=self._options, ), ) @@ -175,6 +177,7 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T: cast_to=cast_to, response=self.http_response, client=cast(Any, self._client), + options=self._options, ), ) diff --git a/src/phoebe_bird/_streaming.py b/src/phoebe_bird/_streaming.py index c7e74f7..c954ad7 100644 --- a/src/phoebe_bird/_streaming.py +++ b/src/phoebe_bird/_streaming.py @@ -4,7 +4,7 @@ import json import inspect from types import TracebackType -from typing import TYPE_CHECKING, Any, Generic, TypeVar, Iterator, AsyncIterator, cast +from typing import TYPE_CHECKING, Any, Generic, TypeVar, Iterator, Optional, AsyncIterator, cast from typing_extensions import Self, Protocol, TypeGuard, override, get_origin, runtime_checkable import httpx @@ -13,6 +13,7 @@ if TYPE_CHECKING: from ._client import Phoebe, AsyncPhoebe + from ._models import FinalRequestOptions _T = TypeVar("_T") @@ -22,7 +23,7 @@ class Stream(Generic[_T]): """Provides the core interface to iterate over a synchronous stream response.""" response: httpx.Response - + _options: Optional[FinalRequestOptions] = None _decoder: SSEBytesDecoder def __init__( @@ -31,10 +32,12 @@ def __init__( cast_to: type[_T], response: httpx.Response, client: Phoebe, + options: Optional[FinalRequestOptions] = None, ) -> None: self.response = response self._cast_to = cast_to self._client = client + self._options = options self._decoder = client._make_sse_decoder() self._iterator = self.__stream__() @@ -85,7 +88,7 @@ class AsyncStream(Generic[_T]): """Provides the core interface to iterate over an asynchronous stream response.""" response: httpx.Response - + _options: Optional[FinalRequestOptions] = None _decoder: SSEDecoder | SSEBytesDecoder def __init__( @@ -94,10 +97,12 @@ def __init__( cast_to: type[_T], response: httpx.Response, client: AsyncPhoebe, + options: Optional[FinalRequestOptions] = None, ) -> None: self.response = response self._cast_to = cast_to self._client = client + self._options = options self._decoder = client._make_sse_decoder() self._iterator = self.__stream__() diff --git a/src/phoebe_bird/_types.py b/src/phoebe_bird/_types.py index d2ceb6e..ee8c515 100644 --- a/src/phoebe_bird/_types.py +++ b/src/phoebe_bird/_types.py @@ -13,9 +13,11 @@ Mapping, TypeVar, Callable, + Iterable, Iterator, Optional, Sequence, + AsyncIterable, ) from typing_extensions import ( Set, @@ -45,6 +47,9 @@ ModelT = TypeVar("ModelT", bound=pydantic.BaseModel) _T = TypeVar("_T") +ArrayFormat = Literal["comma", "repeat", "indices", "brackets"] +NestedFormat = Literal["dots", "brackets"] + # Approximates httpx internal ProxiesTypes and RequestFiles types # while adding support for `PathLike` instances @@ -56,6 +61,13 @@ else: Base64FileInput = Union[IO[bytes], PathLike] FileContent = Union[IO[bytes], bytes, PathLike] # PathLike is not subscriptable in Python 3.8. + + +# Used for sending raw binary data / streaming data in request bodies +# e.g. for file uploads without multipart encoding +BinaryTypes = Union[bytes, bytearray, IO[bytes], Iterable[bytes]] +AsyncBinaryTypes = Union[bytes, bytearray, IO[bytes], AsyncIterable[bytes]] + FileTypes = Union[ # file (or bytes) FileContent, @@ -243,6 +255,9 @@ class HttpxSendArgs(TypedDict, total=False): if TYPE_CHECKING: # This works because str.__contains__ does not accept object (either in typeshed or at runtime) # https://github.com/hauntsaninja/useful_types/blob/5e9710f3875107d068e7679fd7fec9cfab0eff3b/useful_types/__init__.py#L285 + # + # Note: index() and count() methods are intentionally omitted to allow pyright to properly + # infer TypedDict types when dict literals are used in lists assigned to SequenceNotStr. class SequenceNotStr(Protocol[_T_co]): @overload def __getitem__(self, index: SupportsIndex, /) -> _T_co: ... @@ -251,8 +266,6 @@ def __getitem__(self, index: slice, /) -> Sequence[_T_co]: ... def __contains__(self, value: object, /) -> bool: ... def __len__(self) -> int: ... def __iter__(self) -> Iterator[_T_co]: ... - def index(self, value: Any, start: int = 0, stop: int = ..., /) -> int: ... - def count(self, value: Any, /) -> int: ... def __reversed__(self) -> Iterator[_T_co]: ... else: # just point this to a normal `Sequence` at runtime to avoid having to special case diff --git a/src/phoebe_bird/_utils/__init__.py b/src/phoebe_bird/_utils/__init__.py index dc64e29..1c090e5 100644 --- a/src/phoebe_bird/_utils/__init__.py +++ b/src/phoebe_bird/_utils/__init__.py @@ -1,3 +1,4 @@ +from ._path import path_template as path_template from ._sync import asyncify as asyncify from ._proxy import LazyProxy as LazyProxy from ._utils import ( @@ -23,7 +24,6 @@ coerce_integer as coerce_integer, file_from_path as file_from_path, strip_not_given as strip_not_given, - deepcopy_minimal as deepcopy_minimal, get_async_library as get_async_library, maybe_coerce_float as maybe_coerce_float, get_required_header as get_required_header, diff --git a/src/phoebe_bird/_utils/_compat.py b/src/phoebe_bird/_utils/_compat.py index dd70323..2c70b29 100644 --- a/src/phoebe_bird/_utils/_compat.py +++ b/src/phoebe_bird/_utils/_compat.py @@ -26,7 +26,7 @@ def is_union(tp: Optional[Type[Any]]) -> bool: else: import types - return tp is Union or tp is types.UnionType + return tp is Union or tp is types.UnionType # type: ignore[comparison-overlap] def is_typeddict(tp: Type[Any]) -> bool: diff --git a/src/phoebe_bird/_utils/_json.py b/src/phoebe_bird/_utils/_json.py new file mode 100644 index 0000000..6058421 --- /dev/null +++ b/src/phoebe_bird/_utils/_json.py @@ -0,0 +1,35 @@ +import json +from typing import Any +from datetime import datetime +from typing_extensions import override + +import pydantic + +from .._compat import model_dump + + +def openapi_dumps(obj: Any) -> bytes: + """ + Serialize an object to UTF-8 encoded JSON bytes. + + Extends the standard json.dumps with support for additional types + commonly used in the SDK, such as `datetime`, `pydantic.BaseModel`, etc. + """ + return json.dumps( + obj, + cls=_CustomEncoder, + # Uses the same defaults as httpx's JSON serialization + ensure_ascii=False, + separators=(",", ":"), + allow_nan=False, + ).encode() + + +class _CustomEncoder(json.JSONEncoder): + @override + def default(self, o: Any) -> Any: + if isinstance(o, datetime): + return o.isoformat() + if isinstance(o, pydantic.BaseModel): + return model_dump(o, exclude_unset=True, mode="json", by_alias=True) + return super().default(o) diff --git a/src/phoebe_bird/_utils/_path.py b/src/phoebe_bird/_utils/_path.py new file mode 100644 index 0000000..4d6e1e4 --- /dev/null +++ b/src/phoebe_bird/_utils/_path.py @@ -0,0 +1,127 @@ +from __future__ import annotations + +import re +from typing import ( + Any, + Mapping, + Callable, +) +from urllib.parse import quote + +# Matches '.' or '..' where each dot is either literal or percent-encoded (%2e / %2E). +_DOT_SEGMENT_RE = re.compile(r"^(?:\.|%2[eE]){1,2}$") + +_PLACEHOLDER_RE = re.compile(r"\{(\w+)\}") + + +def _quote_path_segment_part(value: str) -> str: + """Percent-encode `value` for use in a URI path segment. + + Considers characters not in `pchar` set from RFC 3986 §3.3 to be unsafe. + https://datatracker.ietf.org/doc/html/rfc3986#section-3.3 + """ + # quote() already treats unreserved characters (letters, digits, and -._~) + # as safe, so we only need to add sub-delims, ':', and '@'. + # Notably, unlike the default `safe` for quote(), / is unsafe and must be quoted. + return quote(value, safe="!$&'()*+,;=:@") + + +def _quote_query_part(value: str) -> str: + """Percent-encode `value` for use in a URI query string. + + Considers &, = and characters not in `query` set from RFC 3986 §3.4 to be unsafe. + https://datatracker.ietf.org/doc/html/rfc3986#section-3.4 + """ + return quote(value, safe="!$'()*+,;:@/?") + + +def _quote_fragment_part(value: str) -> str: + """Percent-encode `value` for use in a URI fragment. + + Considers characters not in `fragment` set from RFC 3986 §3.5 to be unsafe. + https://datatracker.ietf.org/doc/html/rfc3986#section-3.5 + """ + return quote(value, safe="!$&'()*+,;=:@/?") + + +def _interpolate( + template: str, + values: Mapping[str, Any], + quoter: Callable[[str], str], +) -> str: + """Replace {name} placeholders in `template`, quoting each value with `quoter`. + + Placeholder names are looked up in `values`. + + Raises: + KeyError: If a placeholder is not found in `values`. + """ + # re.split with a capturing group returns alternating + # [text, name, text, name, ..., text] elements. + parts = _PLACEHOLDER_RE.split(template) + + for i in range(1, len(parts), 2): + name = parts[i] + if name not in values: + raise KeyError(f"a value for placeholder {{{name}}} was not provided") + val = values[name] + if val is None: + parts[i] = "null" + elif isinstance(val, bool): + parts[i] = "true" if val else "false" + else: + parts[i] = quoter(str(values[name])) + + return "".join(parts) + + +def path_template(template: str, /, **kwargs: Any) -> str: + """Interpolate {name} placeholders in `template` from keyword arguments. + + Args: + template: The template string containing {name} placeholders. + **kwargs: Keyword arguments to interpolate into the template. + + Returns: + The template with placeholders interpolated and percent-encoded. + + Safe characters for percent-encoding are dependent on the URI component. + Placeholders in path and fragment portions are percent-encoded where the `segment` + and `fragment` sets from RFC 3986 respectively are considered safe. + Placeholders in the query portion are percent-encoded where the `query` set from + RFC 3986 §3.3 is considered safe except for = and & characters. + + Raises: + KeyError: If a placeholder is not found in `kwargs`. + ValueError: If resulting path contains /./ or /../ segments (including percent-encoded dot-segments). + """ + # Split the template into path, query, and fragment portions. + fragment_template: str | None = None + query_template: str | None = None + + rest = template + if "#" in rest: + rest, fragment_template = rest.split("#", 1) + if "?" in rest: + rest, query_template = rest.split("?", 1) + path_template = rest + + # Interpolate each portion with the appropriate quoting rules. + path_result = _interpolate(path_template, kwargs, _quote_path_segment_part) + + # Reject dot-segments (. and ..) in the final assembled path. The check + # runs after interpolation so that adjacent placeholders or a mix of static + # text and placeholders that together form a dot-segment are caught. + # Also reject percent-encoded dot-segments to protect against incorrectly + # implemented normalization in servers/proxies. + for segment in path_result.split("/"): + if _DOT_SEGMENT_RE.match(segment): + raise ValueError(f"Constructed path {path_result!r} contains dot-segment {segment!r} which is not allowed") + + result = path_result + if query_template is not None: + result += "?" + _interpolate(query_template, kwargs, _quote_query_part) + if fragment_template is not None: + result += "#" + _interpolate(fragment_template, kwargs, _quote_fragment_part) + + return result diff --git a/src/phoebe_bird/_utils/_utils.py b/src/phoebe_bird/_utils/_utils.py index eec7f4a..199cd23 100644 --- a/src/phoebe_bird/_utils/_utils.py +++ b/src/phoebe_bird/_utils/_utils.py @@ -17,11 +17,11 @@ ) from pathlib import Path from datetime import date, datetime -from typing_extensions import TypeGuard +from typing_extensions import TypeGuard, get_args import sniffio -from .._types import Omit, NotGiven, FileTypes, HeadersLike +from .._types import Omit, NotGiven, FileTypes, ArrayFormat, HeadersLike _T = TypeVar("_T") _TupleT = TypeVar("_TupleT", bound=Tuple[object, ...]) @@ -40,25 +40,45 @@ def extract_files( query: Mapping[str, object], *, paths: Sequence[Sequence[str]], + array_format: ArrayFormat = "brackets", ) -> list[tuple[str, FileTypes]]: """Recursively extract files from the given dictionary based on specified paths. A path may look like this ['foo', 'files', '', 'data']. + ``array_format`` controls how ```` segments contribute to the emitted + field name. Supported values: ``"brackets"`` (``foo[]``), ``"repeat"`` and + ``"comma"`` (``foo``), ``"indices"`` (``foo[0]``, ``foo[1]``). + Note: this mutates the given dictionary. """ files: list[tuple[str, FileTypes]] = [] for path in paths: - files.extend(_extract_items(query, path, index=0, flattened_key=None)) + files.extend(_extract_items(query, path, index=0, flattened_key=None, array_format=array_format)) return files +def _array_suffix(array_format: ArrayFormat, array_index: int) -> str: + if array_format == "brackets": + return "[]" + if array_format == "indices": + return f"[{array_index}]" + if array_format == "repeat" or array_format == "comma": + # Both repeat the bare field name for each file part; there is no + # meaningful way to comma-join binary parts. + return "" + raise NotImplementedError( + f"Unknown array_format value: {array_format}, choose from {', '.join(get_args(ArrayFormat))}" + ) + + def _extract_items( obj: object, path: Sequence[str], *, index: int, flattened_key: str | None, + array_format: ArrayFormat, ) -> list[tuple[str, FileTypes]]: try: key = path[index] @@ -75,9 +95,11 @@ def _extract_items( if is_list(obj): files: list[tuple[str, FileTypes]] = [] - for entry in obj: - assert_is_file_content(entry, key=flattened_key + "[]" if flattened_key else "") - files.append((flattened_key + "[]", cast(FileTypes, entry))) + for array_index, entry in enumerate(obj): + suffix = _array_suffix(array_format, array_index) + emitted_key = (flattened_key + suffix) if flattened_key else suffix + assert_is_file_content(entry, key=emitted_key) + files.append((emitted_key, cast(FileTypes, entry))) return files assert_is_file_content(obj, key=flattened_key) @@ -86,8 +108,9 @@ def _extract_items( index += 1 if is_dict(obj): try: - # We are at the last entry in the path so we must remove the field - if (len(path)) == index: + # Remove the field if there are no more dict keys in the path, + # only "" traversal markers or end. + if all(p == "" for p in path[index:]): item = obj.pop(key) else: item = obj[key] @@ -105,6 +128,7 @@ def _extract_items( path, index=index, flattened_key=flattened_key, + array_format=array_format, ) elif is_list(obj): if key != "": @@ -116,9 +140,12 @@ def _extract_items( item, path, index=index, - flattened_key=flattened_key + "[]" if flattened_key is not None else "[]", + flattened_key=( + (flattened_key if flattened_key is not None else "") + _array_suffix(array_format, array_index) + ), + array_format=array_format, ) - for item in obj + for array_index, item in enumerate(obj) ] ) @@ -176,21 +203,6 @@ def is_iterable(obj: object) -> TypeGuard[Iterable[object]]: return isinstance(obj, Iterable) -def deepcopy_minimal(item: _T) -> _T: - """Minimal reimplementation of copy.deepcopy() that will only copy certain object types: - - - mappings, e.g. `dict` - - list - - This is done for performance reasons. - """ - if is_mapping(item): - return cast(_T, {k: deepcopy_minimal(v) for k, v in item.items()}) - if is_list(item): - return cast(_T, [deepcopy_minimal(entry) for entry in item]) - return item - - # copied from https://github.com/Rapptz/RoboDanny def human_join(seq: Sequence[str], *, delim: str = ", ", final: str = "or") -> str: size = len(seq) diff --git a/src/phoebe_bird/resources/data/observations/geo/geo.py b/src/phoebe_bird/resources/data/observations/geo/geo.py index 7b77105..df9eecf 100644 --- a/src/phoebe_bird/resources/data/observations/geo/geo.py +++ b/src/phoebe_bird/resources/data/observations/geo/geo.py @@ -19,6 +19,9 @@ class GeoResource(SyncAPIResource): @cached_property def recent(self) -> RecentResource: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return RecentResource(self._client) @cached_property @@ -44,6 +47,9 @@ def with_streaming_response(self) -> GeoResourceWithStreamingResponse: class AsyncGeoResource(AsyncAPIResource): @cached_property def recent(self) -> AsyncRecentResource: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return AsyncRecentResource(self._client) @cached_property @@ -72,6 +78,9 @@ def __init__(self, geo: GeoResource) -> None: @cached_property def recent(self) -> RecentResourceWithRawResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return RecentResourceWithRawResponse(self._geo.recent) @@ -81,6 +90,9 @@ def __init__(self, geo: AsyncGeoResource) -> None: @cached_property def recent(self) -> AsyncRecentResourceWithRawResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return AsyncRecentResourceWithRawResponse(self._geo.recent) @@ -90,6 +102,9 @@ def __init__(self, geo: GeoResource) -> None: @cached_property def recent(self) -> RecentResourceWithStreamingResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return RecentResourceWithStreamingResponse(self._geo.recent) @@ -99,4 +114,7 @@ def __init__(self, geo: AsyncGeoResource) -> None: @cached_property def recent(self) -> AsyncRecentResourceWithStreamingResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return AsyncRecentResourceWithStreamingResponse(self._geo.recent) diff --git a/src/phoebe_bird/resources/data/observations/geo/recent/notable.py b/src/phoebe_bird/resources/data/observations/geo/recent/notable.py index ca45e19..672e061 100644 --- a/src/phoebe_bird/resources/data/observations/geo/recent/notable.py +++ b/src/phoebe_bird/resources/data/observations/geo/recent/notable.py @@ -24,6 +24,10 @@ class NotableResource(SyncAPIResource): + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ + @cached_property def with_raw_response(self) -> NotableResourceWithRawResponse: """ @@ -115,6 +119,10 @@ def list( class AsyncNotableResource(AsyncAPIResource): + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ + @cached_property def with_raw_response(self) -> AsyncNotableResourceWithRawResponse: """ diff --git a/src/phoebe_bird/resources/data/observations/geo/recent/recent.py b/src/phoebe_bird/resources/data/observations/geo/recent/recent.py index a5d697f..f209ee6 100644 --- a/src/phoebe_bird/resources/data/observations/geo/recent/recent.py +++ b/src/phoebe_bird/resources/data/observations/geo/recent/recent.py @@ -40,12 +40,22 @@ class RecentResource(SyncAPIResource): + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ + @cached_property def species(self) -> SpeciesResource: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return SpeciesResource(self._client) @cached_property def notable(self) -> NotableResource: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return NotableResource(self._client) @cached_property @@ -146,12 +156,22 @@ def list( class AsyncRecentResource(AsyncAPIResource): + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ + @cached_property def species(self) -> AsyncSpeciesResource: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return AsyncSpeciesResource(self._client) @cached_property def notable(self) -> AsyncNotableResource: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return AsyncNotableResource(self._client) @cached_property @@ -261,10 +281,16 @@ def __init__(self, recent: RecentResource) -> None: @cached_property def species(self) -> SpeciesResourceWithRawResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return SpeciesResourceWithRawResponse(self._recent.species) @cached_property def notable(self) -> NotableResourceWithRawResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return NotableResourceWithRawResponse(self._recent.notable) @@ -278,10 +304,16 @@ def __init__(self, recent: AsyncRecentResource) -> None: @cached_property def species(self) -> AsyncSpeciesResourceWithRawResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return AsyncSpeciesResourceWithRawResponse(self._recent.species) @cached_property def notable(self) -> AsyncNotableResourceWithRawResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return AsyncNotableResourceWithRawResponse(self._recent.notable) @@ -295,10 +327,16 @@ def __init__(self, recent: RecentResource) -> None: @cached_property def species(self) -> SpeciesResourceWithStreamingResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return SpeciesResourceWithStreamingResponse(self._recent.species) @cached_property def notable(self) -> NotableResourceWithStreamingResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return NotableResourceWithStreamingResponse(self._recent.notable) @@ -312,8 +350,14 @@ def __init__(self, recent: AsyncRecentResource) -> None: @cached_property def species(self) -> AsyncSpeciesResourceWithStreamingResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return AsyncSpeciesResourceWithStreamingResponse(self._recent.species) @cached_property def notable(self) -> AsyncNotableResourceWithStreamingResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return AsyncNotableResourceWithStreamingResponse(self._recent.notable) diff --git a/src/phoebe_bird/resources/data/observations/geo/recent/species.py b/src/phoebe_bird/resources/data/observations/geo/recent/species.py index 0a900d1..955d38b 100644 --- a/src/phoebe_bird/resources/data/observations/geo/recent/species.py +++ b/src/phoebe_bird/resources/data/observations/geo/recent/species.py @@ -5,7 +5,7 @@ import httpx from ......_types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ......_utils import maybe_transform, async_maybe_transform +from ......_utils import path_template, maybe_transform, async_maybe_transform from ......_compat import cached_property from ......_resource import SyncAPIResource, AsyncAPIResource from ......_response import ( @@ -22,6 +22,10 @@ class SpeciesResource(SyncAPIResource): + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ + @cached_property def with_raw_response(self) -> SpeciesResourceWithRawResponse: """ @@ -101,7 +105,7 @@ def list( if not species_code: raise ValueError(f"Expected a non-empty value for `species_code` but received {species_code!r}") return self._get( - f"/data/obs/geo/recent/{species_code}", + path_template("/data/obs/geo/recent/{species_code}", species_code=species_code), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -126,6 +130,10 @@ def list( class AsyncSpeciesResource(AsyncAPIResource): + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ + @cached_property def with_raw_response(self) -> AsyncSpeciesResourceWithRawResponse: """ @@ -205,7 +213,7 @@ async def list( if not species_code: raise ValueError(f"Expected a non-empty value for `species_code` but received {species_code!r}") return await self._get( - f"/data/obs/geo/recent/{species_code}", + path_template("/data/obs/geo/recent/{species_code}", species_code=species_code), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, diff --git a/src/phoebe_bird/resources/data/observations/nearest/geo_species.py b/src/phoebe_bird/resources/data/observations/nearest/geo_species.py index d602e8a..b087941 100644 --- a/src/phoebe_bird/resources/data/observations/nearest/geo_species.py +++ b/src/phoebe_bird/resources/data/observations/nearest/geo_species.py @@ -5,7 +5,7 @@ import httpx from ....._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ....._utils import maybe_transform, async_maybe_transform +from ....._utils import path_template, maybe_transform, async_maybe_transform from ....._compat import cached_property from ....._resource import SyncAPIResource, AsyncAPIResource from ....._response import ( @@ -22,6 +22,10 @@ class GeoSpeciesResource(SyncAPIResource): + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ + @cached_property def with_raw_response(self) -> GeoSpeciesResourceWithRawResponse: """ @@ -90,7 +94,7 @@ def list( if not species_code: raise ValueError(f"Expected a non-empty value for `species_code` but received {species_code!r}") return self._get( - f"/data/nearest/geo/recent/{species_code}", + path_template("/data/nearest/geo/recent/{species_code}", species_code=species_code), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -115,6 +119,10 @@ def list( class AsyncGeoSpeciesResource(AsyncAPIResource): + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ + @cached_property def with_raw_response(self) -> AsyncGeoSpeciesResourceWithRawResponse: """ @@ -183,7 +191,7 @@ async def list( if not species_code: raise ValueError(f"Expected a non-empty value for `species_code` but received {species_code!r}") return await self._get( - f"/data/nearest/geo/recent/{species_code}", + path_template("/data/nearest/geo/recent/{species_code}", species_code=species_code), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, diff --git a/src/phoebe_bird/resources/data/observations/nearest/nearest.py b/src/phoebe_bird/resources/data/observations/nearest/nearest.py index bd269d2..c5885db 100644 --- a/src/phoebe_bird/resources/data/observations/nearest/nearest.py +++ b/src/phoebe_bird/resources/data/observations/nearest/nearest.py @@ -19,6 +19,9 @@ class NearestResource(SyncAPIResource): @cached_property def geo_species(self) -> GeoSpeciesResource: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return GeoSpeciesResource(self._client) @cached_property @@ -44,6 +47,9 @@ def with_streaming_response(self) -> NearestResourceWithStreamingResponse: class AsyncNearestResource(AsyncAPIResource): @cached_property def geo_species(self) -> AsyncGeoSpeciesResource: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return AsyncGeoSpeciesResource(self._client) @cached_property @@ -72,6 +78,9 @@ def __init__(self, nearest: NearestResource) -> None: @cached_property def geo_species(self) -> GeoSpeciesResourceWithRawResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return GeoSpeciesResourceWithRawResponse(self._nearest.geo_species) @@ -81,6 +90,9 @@ def __init__(self, nearest: AsyncNearestResource) -> None: @cached_property def geo_species(self) -> AsyncGeoSpeciesResourceWithRawResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return AsyncGeoSpeciesResourceWithRawResponse(self._nearest.geo_species) @@ -90,6 +102,9 @@ def __init__(self, nearest: NearestResource) -> None: @cached_property def geo_species(self) -> GeoSpeciesResourceWithStreamingResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return GeoSpeciesResourceWithStreamingResponse(self._nearest.geo_species) @@ -99,4 +114,7 @@ def __init__(self, nearest: AsyncNearestResource) -> None: @cached_property def geo_species(self) -> AsyncGeoSpeciesResourceWithStreamingResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return AsyncGeoSpeciesResourceWithStreamingResponse(self._nearest.geo_species) diff --git a/src/phoebe_bird/resources/data/observations/observations.py b/src/phoebe_bird/resources/data/observations/observations.py index 3f68bba..3a03ab4 100644 --- a/src/phoebe_bird/resources/data/observations/observations.py +++ b/src/phoebe_bird/resources/data/observations/observations.py @@ -35,6 +35,9 @@ class ObservationsResource(SyncAPIResource): @cached_property def recent(self) -> RecentResource: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return RecentResource(self._client) @cached_property @@ -68,6 +71,9 @@ def with_streaming_response(self) -> ObservationsResourceWithStreamingResponse: class AsyncObservationsResource(AsyncAPIResource): @cached_property def recent(self) -> AsyncRecentResource: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return AsyncRecentResource(self._client) @cached_property @@ -104,6 +110,9 @@ def __init__(self, observations: ObservationsResource) -> None: @cached_property def recent(self) -> RecentResourceWithRawResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return RecentResourceWithRawResponse(self._observations.recent) @cached_property @@ -121,6 +130,9 @@ def __init__(self, observations: AsyncObservationsResource) -> None: @cached_property def recent(self) -> AsyncRecentResourceWithRawResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return AsyncRecentResourceWithRawResponse(self._observations.recent) @cached_property @@ -138,6 +150,9 @@ def __init__(self, observations: ObservationsResource) -> None: @cached_property def recent(self) -> RecentResourceWithStreamingResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return RecentResourceWithStreamingResponse(self._observations.recent) @cached_property @@ -155,6 +170,9 @@ def __init__(self, observations: AsyncObservationsResource) -> None: @cached_property def recent(self) -> AsyncRecentResourceWithStreamingResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return AsyncRecentResourceWithStreamingResponse(self._observations.recent) @cached_property diff --git a/src/phoebe_bird/resources/data/observations/recent/historic.py b/src/phoebe_bird/resources/data/observations/recent/historic.py index b3c2093..e33b1db 100644 --- a/src/phoebe_bird/resources/data/observations/recent/historic.py +++ b/src/phoebe_bird/resources/data/observations/recent/historic.py @@ -7,7 +7,7 @@ import httpx from ....._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given -from ....._utils import maybe_transform, async_maybe_transform +from ....._utils import path_template, maybe_transform, async_maybe_transform from ....._compat import cached_property from ....._resource import SyncAPIResource, AsyncAPIResource from ....._response import ( @@ -24,6 +24,10 @@ class HistoricResource(SyncAPIResource): + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ + @cached_property def with_raw_response(self) -> HistoricResourceWithRawResponse: """ @@ -100,7 +104,7 @@ def list( if not region_code: raise ValueError(f"Expected a non-empty value for `region_code` but received {region_code!r}") return self._get( - f"/data/obs/{region_code}/historic/{y}/{m}/{d}", + path_template("/data/obs/{region_code}/historic/{y}/{m}/{d}", region_code=region_code, y=y, m=m, d=d), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -125,6 +129,10 @@ def list( class AsyncHistoricResource(AsyncAPIResource): + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ + @cached_property def with_raw_response(self) -> AsyncHistoricResourceWithRawResponse: """ @@ -201,7 +209,7 @@ async def list( if not region_code: raise ValueError(f"Expected a non-empty value for `region_code` but received {region_code!r}") return await self._get( - f"/data/obs/{region_code}/historic/{y}/{m}/{d}", + path_template("/data/obs/{region_code}/historic/{y}/{m}/{d}", region_code=region_code, y=y, m=m, d=d), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, diff --git a/src/phoebe_bird/resources/data/observations/recent/notable.py b/src/phoebe_bird/resources/data/observations/recent/notable.py index 33dc7b6..be9292f 100644 --- a/src/phoebe_bird/resources/data/observations/recent/notable.py +++ b/src/phoebe_bird/resources/data/observations/recent/notable.py @@ -7,7 +7,7 @@ import httpx from ....._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given -from ....._utils import maybe_transform, async_maybe_transform +from ....._utils import path_template, maybe_transform, async_maybe_transform from ....._compat import cached_property from ....._resource import SyncAPIResource, AsyncAPIResource from ....._response import ( @@ -24,6 +24,10 @@ class NotableResource(SyncAPIResource): + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ + @cached_property def with_raw_response(self) -> NotableResourceWithRawResponse: """ @@ -90,7 +94,7 @@ def list( if not region_code: raise ValueError(f"Expected a non-empty value for `region_code` but received {region_code!r}") return self._get( - f"/data/obs/{region_code}/recent/notable", + path_template("/data/obs/{region_code}/recent/notable", region_code=region_code), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -113,6 +117,10 @@ def list( class AsyncNotableResource(AsyncAPIResource): + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ + @cached_property def with_raw_response(self) -> AsyncNotableResourceWithRawResponse: """ @@ -179,7 +187,7 @@ async def list( if not region_code: raise ValueError(f"Expected a non-empty value for `region_code` but received {region_code!r}") return await self._get( - f"/data/obs/{region_code}/recent/notable", + path_template("/data/obs/{region_code}/recent/notable", region_code=region_code), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, diff --git a/src/phoebe_bird/resources/data/observations/recent/recent.py b/src/phoebe_bird/resources/data/observations/recent/recent.py index 5fa495b..3ddf8db 100644 --- a/src/phoebe_bird/resources/data/observations/recent/recent.py +++ b/src/phoebe_bird/resources/data/observations/recent/recent.py @@ -31,7 +31,7 @@ AsyncHistoricResourceWithStreamingResponse, ) from ....._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given -from ....._utils import maybe_transform, async_maybe_transform +from ....._utils import path_template, maybe_transform, async_maybe_transform from ....._compat import cached_property from ....._resource import SyncAPIResource, AsyncAPIResource from ....._response import ( @@ -48,16 +48,29 @@ class RecentResource(SyncAPIResource): + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ + @cached_property def notable(self) -> NotableResource: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return NotableResource(self._client) @cached_property def species(self) -> SpeciesResource: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return SpeciesResource(self._client) @cached_property def historic(self) -> HistoricResource: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return HistoricResource(self._client) @cached_property @@ -128,7 +141,7 @@ def list( if not region_code: raise ValueError(f"Expected a non-empty value for `region_code` but received {region_code!r}") return self._get( - f"/data/obs/{region_code}/recent", + path_template("/data/obs/{region_code}/recent", region_code=region_code), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -152,16 +165,29 @@ def list( class AsyncRecentResource(AsyncAPIResource): + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ + @cached_property def notable(self) -> AsyncNotableResource: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return AsyncNotableResource(self._client) @cached_property def species(self) -> AsyncSpeciesResource: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return AsyncSpeciesResource(self._client) @cached_property def historic(self) -> AsyncHistoricResource: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return AsyncHistoricResource(self._client) @cached_property @@ -232,7 +258,7 @@ async def list( if not region_code: raise ValueError(f"Expected a non-empty value for `region_code` but received {region_code!r}") return await self._get( - f"/data/obs/{region_code}/recent", + path_template("/data/obs/{region_code}/recent", region_code=region_code), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -265,14 +291,23 @@ def __init__(self, recent: RecentResource) -> None: @cached_property def notable(self) -> NotableResourceWithRawResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return NotableResourceWithRawResponse(self._recent.notable) @cached_property def species(self) -> SpeciesResourceWithRawResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return SpeciesResourceWithRawResponse(self._recent.species) @cached_property def historic(self) -> HistoricResourceWithRawResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return HistoricResourceWithRawResponse(self._recent.historic) @@ -286,14 +321,23 @@ def __init__(self, recent: AsyncRecentResource) -> None: @cached_property def notable(self) -> AsyncNotableResourceWithRawResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return AsyncNotableResourceWithRawResponse(self._recent.notable) @cached_property def species(self) -> AsyncSpeciesResourceWithRawResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return AsyncSpeciesResourceWithRawResponse(self._recent.species) @cached_property def historic(self) -> AsyncHistoricResourceWithRawResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return AsyncHistoricResourceWithRawResponse(self._recent.historic) @@ -307,14 +351,23 @@ def __init__(self, recent: RecentResource) -> None: @cached_property def notable(self) -> NotableResourceWithStreamingResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return NotableResourceWithStreamingResponse(self._recent.notable) @cached_property def species(self) -> SpeciesResourceWithStreamingResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return SpeciesResourceWithStreamingResponse(self._recent.species) @cached_property def historic(self) -> HistoricResourceWithStreamingResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return HistoricResourceWithStreamingResponse(self._recent.historic) @@ -328,12 +381,21 @@ def __init__(self, recent: AsyncRecentResource) -> None: @cached_property def notable(self) -> AsyncNotableResourceWithStreamingResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return AsyncNotableResourceWithStreamingResponse(self._recent.notable) @cached_property def species(self) -> AsyncSpeciesResourceWithStreamingResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return AsyncSpeciesResourceWithStreamingResponse(self._recent.species) @cached_property def historic(self) -> AsyncHistoricResourceWithStreamingResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return AsyncHistoricResourceWithStreamingResponse(self._recent.historic) diff --git a/src/phoebe_bird/resources/data/observations/recent/species.py b/src/phoebe_bird/resources/data/observations/recent/species.py index 53df43c..388f8ff 100644 --- a/src/phoebe_bird/resources/data/observations/recent/species.py +++ b/src/phoebe_bird/resources/data/observations/recent/species.py @@ -5,7 +5,7 @@ import httpx from ....._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given -from ....._utils import maybe_transform, async_maybe_transform +from ....._utils import path_template, maybe_transform, async_maybe_transform from ....._compat import cached_property from ....._resource import SyncAPIResource, AsyncAPIResource from ....._response import ( @@ -22,6 +22,10 @@ class SpeciesResource(SyncAPIResource): + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ + @cached_property def with_raw_response(self) -> SpeciesResourceWithRawResponse: """ @@ -98,7 +102,9 @@ def retrieve( if not species_code: raise ValueError(f"Expected a non-empty value for `species_code` but received {species_code!r}") return self._get( - f"/data/obs/{region_code}/recent/{species_code}", + path_template( + "/data/obs/{region_code}/recent/{species_code}", region_code=region_code, species_code=species_code + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -121,6 +127,10 @@ def retrieve( class AsyncSpeciesResource(AsyncAPIResource): + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ + @cached_property def with_raw_response(self) -> AsyncSpeciesResourceWithRawResponse: """ @@ -197,7 +207,9 @@ async def retrieve( if not species_code: raise ValueError(f"Expected a non-empty value for `species_code` but received {species_code!r}") return await self._get( - f"/data/obs/{region_code}/recent/{species_code}", + path_template( + "/data/obs/{region_code}/recent/{species_code}", region_code=region_code, species_code=species_code + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, diff --git a/src/phoebe_bird/resources/product/checklist.py b/src/phoebe_bird/resources/product/checklist.py index 84d8379..4511acc 100644 --- a/src/phoebe_bird/resources/product/checklist.py +++ b/src/phoebe_bird/resources/product/checklist.py @@ -5,6 +5,7 @@ import httpx from ..._types import Body, Query, Headers, NotGiven, not_given +from ..._utils import path_template from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource from ..._response import ( @@ -20,6 +21,10 @@ class ChecklistResource(SyncAPIResource): + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ + @cached_property def with_raw_response(self) -> ChecklistResourceWithRawResponse: """ @@ -67,7 +72,7 @@ def view( if not sub_id: raise ValueError(f"Expected a non-empty value for `sub_id` but received {sub_id!r}") return self._get( - f"/product/checklist/view/{sub_id}", + path_template("/product/checklist/view/{sub_id}", sub_id=sub_id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -76,6 +81,10 @@ def view( class AsyncChecklistResource(AsyncAPIResource): + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ + @cached_property def with_raw_response(self) -> AsyncChecklistResourceWithRawResponse: """ @@ -123,7 +132,7 @@ async def view( if not sub_id: raise ValueError(f"Expected a non-empty value for `sub_id` but received {sub_id!r}") return await self._get( - f"/product/checklist/view/{sub_id}", + path_template("/product/checklist/view/{sub_id}", sub_id=sub_id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/phoebe_bird/resources/product/lists/historical.py b/src/phoebe_bird/resources/product/lists/historical.py index 86bec79..d32da56 100644 --- a/src/phoebe_bird/resources/product/lists/historical.py +++ b/src/phoebe_bird/resources/product/lists/historical.py @@ -7,7 +7,7 @@ import httpx from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ...._utils import maybe_transform, async_maybe_transform +from ...._utils import path_template, maybe_transform, async_maybe_transform from ...._compat import cached_property from ...._resource import SyncAPIResource, AsyncAPIResource from ...._response import ( @@ -24,6 +24,10 @@ class HistoricalResource(SyncAPIResource): + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ + @cached_property def with_raw_response(self) -> HistoricalResourceWithRawResponse: """ @@ -79,7 +83,7 @@ def retrieve( if not region_code: raise ValueError(f"Expected a non-empty value for `region_code` but received {region_code!r}") return self._get( - f"/product/lists/{region_code}/{y}/{m}/{d}", + path_template("/product/lists/{region_code}/{y}/{m}/{d}", region_code=region_code, y=y, m=m, d=d), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -98,6 +102,10 @@ def retrieve( class AsyncHistoricalResource(AsyncAPIResource): + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ + @cached_property def with_raw_response(self) -> AsyncHistoricalResourceWithRawResponse: """ @@ -153,7 +161,7 @@ async def retrieve( if not region_code: raise ValueError(f"Expected a non-empty value for `region_code` but received {region_code!r}") return await self._get( - f"/product/lists/{region_code}/{y}/{m}/{d}", + path_template("/product/lists/{region_code}/{y}/{m}/{d}", region_code=region_code, y=y, m=m, d=d), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, diff --git a/src/phoebe_bird/resources/product/lists/lists.py b/src/phoebe_bird/resources/product/lists/lists.py index cb256d2..92c30dd 100644 --- a/src/phoebe_bird/resources/product/lists/lists.py +++ b/src/phoebe_bird/resources/product/lists/lists.py @@ -5,7 +5,7 @@ import httpx from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ...._utils import maybe_transform, async_maybe_transform +from ...._utils import path_template, maybe_transform, async_maybe_transform from ...._compat import cached_property from .historical import ( HistoricalResource, @@ -30,8 +30,15 @@ class ListsResource(SyncAPIResource): + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ + @cached_property def historical(self) -> HistoricalResource: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return HistoricalResource(self._client) @cached_property @@ -82,7 +89,7 @@ def retrieve( if not region_code: raise ValueError(f"Expected a non-empty value for `region_code` but received {region_code!r}") return self._get( - f"/product/lists/{region_code}", + path_template("/product/lists/{region_code}", region_code=region_code), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -95,8 +102,15 @@ def retrieve( class AsyncListsResource(AsyncAPIResource): + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ + @cached_property def historical(self) -> AsyncHistoricalResource: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return AsyncHistoricalResource(self._client) @cached_property @@ -147,7 +161,7 @@ async def retrieve( if not region_code: raise ValueError(f"Expected a non-empty value for `region_code` but received {region_code!r}") return await self._get( - f"/product/lists/{region_code}", + path_template("/product/lists/{region_code}", region_code=region_code), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -171,6 +185,9 @@ def __init__(self, lists: ListsResource) -> None: @cached_property def historical(self) -> HistoricalResourceWithRawResponse: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return HistoricalResourceWithRawResponse(self._lists.historical) @@ -184,6 +201,9 @@ def __init__(self, lists: AsyncListsResource) -> None: @cached_property def historical(self) -> AsyncHistoricalResourceWithRawResponse: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return AsyncHistoricalResourceWithRawResponse(self._lists.historical) @@ -197,6 +217,9 @@ def __init__(self, lists: ListsResource) -> None: @cached_property def historical(self) -> HistoricalResourceWithStreamingResponse: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return HistoricalResourceWithStreamingResponse(self._lists.historical) @@ -210,4 +233,7 @@ def __init__(self, lists: AsyncListsResource) -> None: @cached_property def historical(self) -> AsyncHistoricalResourceWithStreamingResponse: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return AsyncHistoricalResourceWithStreamingResponse(self._lists.historical) diff --git a/src/phoebe_bird/resources/product/product.py b/src/phoebe_bird/resources/product/product.py index cfcc550..57d039f 100644 --- a/src/phoebe_bird/resources/product/product.py +++ b/src/phoebe_bird/resources/product/product.py @@ -51,22 +51,37 @@ class ProductResource(SyncAPIResource): @cached_property def lists(self) -> ListsResource: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return ListsResource(self._client) @cached_property def top100(self) -> Top100Resource: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return Top100Resource(self._client) @cached_property def stats(self) -> StatsResource: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return StatsResource(self._client) @cached_property def species_list(self) -> SpeciesListResource: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return SpeciesListResource(self._client) @cached_property def checklist(self) -> ChecklistResource: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return ChecklistResource(self._client) @cached_property @@ -92,22 +107,37 @@ def with_streaming_response(self) -> ProductResourceWithStreamingResponse: class AsyncProductResource(AsyncAPIResource): @cached_property def lists(self) -> AsyncListsResource: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return AsyncListsResource(self._client) @cached_property def top100(self) -> AsyncTop100Resource: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return AsyncTop100Resource(self._client) @cached_property def stats(self) -> AsyncStatsResource: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return AsyncStatsResource(self._client) @cached_property def species_list(self) -> AsyncSpeciesListResource: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return AsyncSpeciesListResource(self._client) @cached_property def checklist(self) -> AsyncChecklistResource: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return AsyncChecklistResource(self._client) @cached_property @@ -136,22 +166,37 @@ def __init__(self, product: ProductResource) -> None: @cached_property def lists(self) -> ListsResourceWithRawResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return ListsResourceWithRawResponse(self._product.lists) @cached_property def top100(self) -> Top100ResourceWithRawResponse: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return Top100ResourceWithRawResponse(self._product.top100) @cached_property def stats(self) -> StatsResourceWithRawResponse: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return StatsResourceWithRawResponse(self._product.stats) @cached_property def species_list(self) -> SpeciesListResourceWithRawResponse: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return SpeciesListResourceWithRawResponse(self._product.species_list) @cached_property def checklist(self) -> ChecklistResourceWithRawResponse: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return ChecklistResourceWithRawResponse(self._product.checklist) @@ -161,22 +206,37 @@ def __init__(self, product: AsyncProductResource) -> None: @cached_property def lists(self) -> AsyncListsResourceWithRawResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return AsyncListsResourceWithRawResponse(self._product.lists) @cached_property def top100(self) -> AsyncTop100ResourceWithRawResponse: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return AsyncTop100ResourceWithRawResponse(self._product.top100) @cached_property def stats(self) -> AsyncStatsResourceWithRawResponse: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return AsyncStatsResourceWithRawResponse(self._product.stats) @cached_property def species_list(self) -> AsyncSpeciesListResourceWithRawResponse: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return AsyncSpeciesListResourceWithRawResponse(self._product.species_list) @cached_property def checklist(self) -> AsyncChecklistResourceWithRawResponse: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return AsyncChecklistResourceWithRawResponse(self._product.checklist) @@ -186,22 +246,37 @@ def __init__(self, product: ProductResource) -> None: @cached_property def lists(self) -> ListsResourceWithStreamingResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return ListsResourceWithStreamingResponse(self._product.lists) @cached_property def top100(self) -> Top100ResourceWithStreamingResponse: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return Top100ResourceWithStreamingResponse(self._product.top100) @cached_property def stats(self) -> StatsResourceWithStreamingResponse: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return StatsResourceWithStreamingResponse(self._product.stats) @cached_property def species_list(self) -> SpeciesListResourceWithStreamingResponse: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return SpeciesListResourceWithStreamingResponse(self._product.species_list) @cached_property def checklist(self) -> ChecklistResourceWithStreamingResponse: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return ChecklistResourceWithStreamingResponse(self._product.checklist) @@ -211,20 +286,35 @@ def __init__(self, product: AsyncProductResource) -> None: @cached_property def lists(self) -> AsyncListsResourceWithStreamingResponse: + """ + The data/obs end-points are used to fetch observations submitted to eBird in checklists. There are two categories of end-point: 1. Fetch observations for a specific country, region or location. 2. Fetch observations for nearby locations - up to a distance of 50km. Each end-point supports optional query parameters which allow you to filter the list of observations returned. + """ return AsyncListsResourceWithStreamingResponse(self._product.lists) @cached_property def top100(self) -> AsyncTop100ResourceWithStreamingResponse: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return AsyncTop100ResourceWithStreamingResponse(self._product.top100) @cached_property def stats(self) -> AsyncStatsResourceWithStreamingResponse: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return AsyncStatsResourceWithStreamingResponse(self._product.stats) @cached_property def species_list(self) -> AsyncSpeciesListResourceWithStreamingResponse: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return AsyncSpeciesListResourceWithStreamingResponse(self._product.species_list) @cached_property def checklist(self) -> AsyncChecklistResourceWithStreamingResponse: + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ return AsyncChecklistResourceWithStreamingResponse(self._product.checklist) diff --git a/src/phoebe_bird/resources/product/species_list.py b/src/phoebe_bird/resources/product/species_list.py index d5b639d..c8809f3 100644 --- a/src/phoebe_bird/resources/product/species_list.py +++ b/src/phoebe_bird/resources/product/species_list.py @@ -5,6 +5,7 @@ import httpx from ..._types import Body, Query, Headers, NotGiven, not_given +from ..._utils import path_template from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource from ..._response import ( @@ -20,6 +21,10 @@ class SpeciesListResource(SyncAPIResource): + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ + @cached_property def with_raw_response(self) -> SpeciesListResourceWithRawResponse: """ @@ -68,7 +73,7 @@ def list( if not region_code: raise ValueError(f"Expected a non-empty value for `region_code` but received {region_code!r}") return self._get( - f"/product/spplist/{region_code}", + path_template("/product/spplist/{region_code}", region_code=region_code), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -77,6 +82,10 @@ def list( class AsyncSpeciesListResource(AsyncAPIResource): + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ + @cached_property def with_raw_response(self) -> AsyncSpeciesListResourceWithRawResponse: """ @@ -125,7 +134,7 @@ async def list( if not region_code: raise ValueError(f"Expected a non-empty value for `region_code` but received {region_code!r}") return await self._get( - f"/product/spplist/{region_code}", + path_template("/product/spplist/{region_code}", region_code=region_code), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/phoebe_bird/resources/product/stats.py b/src/phoebe_bird/resources/product/stats.py index 4da26d0..9e4e329 100644 --- a/src/phoebe_bird/resources/product/stats.py +++ b/src/phoebe_bird/resources/product/stats.py @@ -5,6 +5,7 @@ import httpx from ..._types import Body, Query, Headers, NotGiven, not_given +from ..._utils import path_template from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource from ..._response import ( @@ -20,6 +21,10 @@ class StatsResource(SyncAPIResource): + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ + @cached_property def with_raw_response(self) -> StatsResourceWithRawResponse: """ @@ -71,7 +76,7 @@ def retrieve( if not region_code: raise ValueError(f"Expected a non-empty value for `region_code` but received {region_code!r}") return self._get( - f"/product/stats/{region_code}/{y}/{m}/{d}", + path_template("/product/stats/{region_code}/{y}/{m}/{d}", region_code=region_code, y=y, m=m, d=d), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -80,6 +85,10 @@ def retrieve( class AsyncStatsResource(AsyncAPIResource): + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ + @cached_property def with_raw_response(self) -> AsyncStatsResourceWithRawResponse: """ @@ -131,7 +140,7 @@ async def retrieve( if not region_code: raise ValueError(f"Expected a non-empty value for `region_code` but received {region_code!r}") return await self._get( - f"/product/stats/{region_code}/{y}/{m}/{d}", + path_template("/product/stats/{region_code}/{y}/{m}/{d}", region_code=region_code, y=y, m=m, d=d), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/phoebe_bird/resources/product/top100.py b/src/phoebe_bird/resources/product/top100.py index e83cdaa..17ae657 100644 --- a/src/phoebe_bird/resources/product/top100.py +++ b/src/phoebe_bird/resources/product/top100.py @@ -7,7 +7,7 @@ import httpx from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ..._utils import maybe_transform, async_maybe_transform +from ..._utils import path_template, maybe_transform, async_maybe_transform from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource from ..._response import ( @@ -24,6 +24,10 @@ class Top100Resource(SyncAPIResource): + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ + @cached_property def with_raw_response(self) -> Top100ResourceWithRawResponse: """ @@ -94,7 +98,7 @@ def retrieve( if not region_code: raise ValueError(f"Expected a non-empty value for `region_code` but received {region_code!r}") return self._get( - f"/product/top100/{region_code}/{y}/{m}/{d}", + path_template("/product/top100/{region_code}/{y}/{m}/{d}", region_code=region_code, y=y, m=m, d=d), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -113,6 +117,10 @@ def retrieve( class AsyncTop100Resource(AsyncAPIResource): + """ + The product end-points make it easy to get the information shown in various pages on the eBird web site: 1. The Top 100 contributors on a given date. 2. The checklists submitted on a given date. 3. The most recent checklists submitted. 4. A summary of the checklists submitted on a given date. 5. The details and all the observations of a checklist. + """ + @cached_property def with_raw_response(self) -> AsyncTop100ResourceWithRawResponse: """ @@ -183,7 +191,7 @@ async def retrieve( if not region_code: raise ValueError(f"Expected a non-empty value for `region_code` but received {region_code!r}") return await self._get( - f"/product/top100/{region_code}/{y}/{m}/{d}", + path_template("/product/top100/{region_code}/{y}/{m}/{d}", region_code=region_code, y=y, m=m, d=d), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, diff --git a/src/phoebe_bird/resources/ref/hotspot/geo.py b/src/phoebe_bird/resources/ref/hotspot/geo.py index 796b969..84d313f 100644 --- a/src/phoebe_bird/resources/ref/hotspot/geo.py +++ b/src/phoebe_bird/resources/ref/hotspot/geo.py @@ -24,6 +24,10 @@ class GeoResource(SyncAPIResource): + """ + With the ref/hotspot end-points you can find the hotspots for a given country or region or nearby hotspots + """ + @cached_property def with_raw_response(self) -> GeoResourceWithRawResponse: """ @@ -100,6 +104,10 @@ def retrieve( class AsyncGeoResource(AsyncAPIResource): + """ + With the ref/hotspot end-points you can find the hotspots for a given country or region or nearby hotspots + """ + @cached_property def with_raw_response(self) -> AsyncGeoResourceWithRawResponse: """ diff --git a/src/phoebe_bird/resources/ref/hotspot/hotspot.py b/src/phoebe_bird/resources/ref/hotspot/hotspot.py index 0e9ff17..cbe5be1 100644 --- a/src/phoebe_bird/resources/ref/hotspot/hotspot.py +++ b/src/phoebe_bird/resources/ref/hotspot/hotspot.py @@ -23,7 +23,7 @@ AsyncInfoResourceWithStreamingResponse, ) from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ...._utils import maybe_transform, async_maybe_transform +from ...._utils import path_template, maybe_transform, async_maybe_transform from ...._compat import cached_property from ...._resource import SyncAPIResource, AsyncAPIResource from ...._response import ( @@ -40,12 +40,22 @@ class HotspotResource(SyncAPIResource): + """ + With the ref/hotspot end-points you can find the hotspots for a given country or region or nearby hotspots + """ + @cached_property def geo(self) -> GeoResource: + """ + With the ref/hotspot end-points you can find the hotspots for a given country or region or nearby hotspots + """ return GeoResource(self._client) @cached_property def info(self) -> InfoResource: + """ + With the ref/hotspot end-points you can find the hotspots for a given country or region or nearby hotspots + """ return InfoResource(self._client) @cached_property @@ -99,7 +109,7 @@ def list( if not region_code: raise ValueError(f"Expected a non-empty value for `region_code` but received {region_code!r}") return self._get( - f"/ref/hotspot/{region_code}", + path_template("/ref/hotspot/{region_code}", region_code=region_code), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -118,12 +128,22 @@ def list( class AsyncHotspotResource(AsyncAPIResource): + """ + With the ref/hotspot end-points you can find the hotspots for a given country or region or nearby hotspots + """ + @cached_property def geo(self) -> AsyncGeoResource: + """ + With the ref/hotspot end-points you can find the hotspots for a given country or region or nearby hotspots + """ return AsyncGeoResource(self._client) @cached_property def info(self) -> AsyncInfoResource: + """ + With the ref/hotspot end-points you can find the hotspots for a given country or region or nearby hotspots + """ return AsyncInfoResource(self._client) @cached_property @@ -177,7 +197,7 @@ async def list( if not region_code: raise ValueError(f"Expected a non-empty value for `region_code` but received {region_code!r}") return await self._get( - f"/ref/hotspot/{region_code}", + path_template("/ref/hotspot/{region_code}", region_code=region_code), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -205,10 +225,16 @@ def __init__(self, hotspot: HotspotResource) -> None: @cached_property def geo(self) -> GeoResourceWithRawResponse: + """ + With the ref/hotspot end-points you can find the hotspots for a given country or region or nearby hotspots + """ return GeoResourceWithRawResponse(self._hotspot.geo) @cached_property def info(self) -> InfoResourceWithRawResponse: + """ + With the ref/hotspot end-points you can find the hotspots for a given country or region or nearby hotspots + """ return InfoResourceWithRawResponse(self._hotspot.info) @@ -222,10 +248,16 @@ def __init__(self, hotspot: AsyncHotspotResource) -> None: @cached_property def geo(self) -> AsyncGeoResourceWithRawResponse: + """ + With the ref/hotspot end-points you can find the hotspots for a given country or region or nearby hotspots + """ return AsyncGeoResourceWithRawResponse(self._hotspot.geo) @cached_property def info(self) -> AsyncInfoResourceWithRawResponse: + """ + With the ref/hotspot end-points you can find the hotspots for a given country or region or nearby hotspots + """ return AsyncInfoResourceWithRawResponse(self._hotspot.info) @@ -239,10 +271,16 @@ def __init__(self, hotspot: HotspotResource) -> None: @cached_property def geo(self) -> GeoResourceWithStreamingResponse: + """ + With the ref/hotspot end-points you can find the hotspots for a given country or region or nearby hotspots + """ return GeoResourceWithStreamingResponse(self._hotspot.geo) @cached_property def info(self) -> InfoResourceWithStreamingResponse: + """ + With the ref/hotspot end-points you can find the hotspots for a given country or region or nearby hotspots + """ return InfoResourceWithStreamingResponse(self._hotspot.info) @@ -256,8 +294,14 @@ def __init__(self, hotspot: AsyncHotspotResource) -> None: @cached_property def geo(self) -> AsyncGeoResourceWithStreamingResponse: + """ + With the ref/hotspot end-points you can find the hotspots for a given country or region or nearby hotspots + """ return AsyncGeoResourceWithStreamingResponse(self._hotspot.geo) @cached_property def info(self) -> AsyncInfoResourceWithStreamingResponse: + """ + With the ref/hotspot end-points you can find the hotspots for a given country or region or nearby hotspots + """ return AsyncInfoResourceWithStreamingResponse(self._hotspot.info) diff --git a/src/phoebe_bird/resources/ref/hotspot/info.py b/src/phoebe_bird/resources/ref/hotspot/info.py index ea24bcc..0f7e9b6 100644 --- a/src/phoebe_bird/resources/ref/hotspot/info.py +++ b/src/phoebe_bird/resources/ref/hotspot/info.py @@ -5,6 +5,7 @@ import httpx from ...._types import Body, Query, Headers, NotGiven, not_given +from ...._utils import path_template from ...._compat import cached_property from ...._resource import SyncAPIResource, AsyncAPIResource from ...._response import ( @@ -20,6 +21,10 @@ class InfoResource(SyncAPIResource): + """ + With the ref/hotspot end-points you can find the hotspots for a given country or region or nearby hotspots + """ + @cached_property def with_raw_response(self) -> InfoResourceWithRawResponse: """ @@ -68,7 +73,7 @@ def retrieve( if not loc_id: raise ValueError(f"Expected a non-empty value for `loc_id` but received {loc_id!r}") return self._get( - f"/ref/hotspot/info/{loc_id}", + path_template("/ref/hotspot/info/{loc_id}", loc_id=loc_id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -77,6 +82,10 @@ def retrieve( class AsyncInfoResource(AsyncAPIResource): + """ + With the ref/hotspot end-points you can find the hotspots for a given country or region or nearby hotspots + """ + @cached_property def with_raw_response(self) -> AsyncInfoResourceWithRawResponse: """ @@ -125,7 +134,7 @@ async def retrieve( if not loc_id: raise ValueError(f"Expected a non-empty value for `loc_id` but received {loc_id!r}") return await self._get( - f"/ref/hotspot/info/{loc_id}", + path_template("/ref/hotspot/info/{loc_id}", loc_id=loc_id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/phoebe_bird/resources/ref/ref.py b/src/phoebe_bird/resources/ref/ref.py index 10491fc..655a54f 100644 --- a/src/phoebe_bird/resources/ref/ref.py +++ b/src/phoebe_bird/resources/ref/ref.py @@ -39,6 +39,9 @@ def region(self) -> RegionResource: @cached_property def hotspot(self) -> HotspotResource: + """ + With the ref/hotspot end-points you can find the hotspots for a given country or region or nearby hotspots + """ return HotspotResource(self._client) @cached_property @@ -72,6 +75,9 @@ def region(self) -> AsyncRegionResource: @cached_property def hotspot(self) -> AsyncHotspotResource: + """ + With the ref/hotspot end-points you can find the hotspots for a given country or region or nearby hotspots + """ return AsyncHotspotResource(self._client) @cached_property @@ -108,6 +114,9 @@ def region(self) -> RegionResourceWithRawResponse: @cached_property def hotspot(self) -> HotspotResourceWithRawResponse: + """ + With the ref/hotspot end-points you can find the hotspots for a given country or region or nearby hotspots + """ return HotspotResourceWithRawResponse(self._ref.hotspot) @cached_property @@ -125,6 +134,9 @@ def region(self) -> AsyncRegionResourceWithRawResponse: @cached_property def hotspot(self) -> AsyncHotspotResourceWithRawResponse: + """ + With the ref/hotspot end-points you can find the hotspots for a given country or region or nearby hotspots + """ return AsyncHotspotResourceWithRawResponse(self._ref.hotspot) @cached_property @@ -142,6 +154,9 @@ def region(self) -> RegionResourceWithStreamingResponse: @cached_property def hotspot(self) -> HotspotResourceWithStreamingResponse: + """ + With the ref/hotspot end-points you can find the hotspots for a given country or region or nearby hotspots + """ return HotspotResourceWithStreamingResponse(self._ref.hotspot) @cached_property @@ -159,6 +174,9 @@ def region(self) -> AsyncRegionResourceWithStreamingResponse: @cached_property def hotspot(self) -> AsyncHotspotResourceWithStreamingResponse: + """ + With the ref/hotspot end-points you can find the hotspots for a given country or region or nearby hotspots + """ return AsyncHotspotResourceWithStreamingResponse(self._ref.hotspot) @cached_property diff --git a/src/phoebe_bird/resources/ref/region/adjacent.py b/src/phoebe_bird/resources/ref/region/adjacent.py index c03ba7d..51eab2b 100644 --- a/src/phoebe_bird/resources/ref/region/adjacent.py +++ b/src/phoebe_bird/resources/ref/region/adjacent.py @@ -5,6 +5,7 @@ import httpx from ...._types import Body, Query, Headers, NotGiven, not_given +from ...._utils import path_template from ...._compat import cached_property from ...._resource import SyncAPIResource, AsyncAPIResource from ...._response import ( @@ -20,6 +21,8 @@ class AdjacentResource(SyncAPIResource): + """With the ref/geo end-point you can find a country's or region's neighbours.""" + @cached_property def with_raw_response(self) -> AdjacentResourceWithRawResponse: """ @@ -68,7 +71,7 @@ def list( if not region_code: raise ValueError(f"Expected a non-empty value for `region_code` but received {region_code!r}") return self._get( - f"/ref/adjacent/{region_code}", + path_template("/ref/adjacent/{region_code}", region_code=region_code), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -77,6 +80,8 @@ def list( class AsyncAdjacentResource(AsyncAPIResource): + """With the ref/geo end-point you can find a country's or region's neighbours.""" + @cached_property def with_raw_response(self) -> AsyncAdjacentResourceWithRawResponse: """ @@ -125,7 +130,7 @@ async def list( if not region_code: raise ValueError(f"Expected a non-empty value for `region_code` but received {region_code!r}") return await self._get( - f"/ref/adjacent/{region_code}", + path_template("/ref/adjacent/{region_code}", region_code=region_code), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/phoebe_bird/resources/ref/region/info.py b/src/phoebe_bird/resources/ref/region/info.py index e259e08..44f4c1f 100644 --- a/src/phoebe_bird/resources/ref/region/info.py +++ b/src/phoebe_bird/resources/ref/region/info.py @@ -7,7 +7,7 @@ import httpx from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ...._utils import maybe_transform, async_maybe_transform +from ...._utils import path_template, maybe_transform, async_maybe_transform from ...._compat import cached_property from ...._resource import SyncAPIResource, AsyncAPIResource from ...._response import ( @@ -24,6 +24,8 @@ class InfoResource(SyncAPIResource): + """The ref/region end-points return information on regions.""" + @cached_property def with_raw_response(self) -> InfoResourceWithRawResponse: """ @@ -90,7 +92,7 @@ def retrieve( if not region_code: raise ValueError(f"Expected a non-empty value for `region_code` but received {region_code!r}") return self._get( - f"/ref/region/info/{region_code}", + path_template("/ref/region/info/{region_code}", region_code=region_code), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -109,6 +111,8 @@ def retrieve( class AsyncInfoResource(AsyncAPIResource): + """The ref/region end-points return information on regions.""" + @cached_property def with_raw_response(self) -> AsyncInfoResourceWithRawResponse: """ @@ -175,7 +179,7 @@ async def retrieve( if not region_code: raise ValueError(f"Expected a non-empty value for `region_code` but received {region_code!r}") return await self._get( - f"/ref/region/info/{region_code}", + path_template("/ref/region/info/{region_code}", region_code=region_code), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, diff --git a/src/phoebe_bird/resources/ref/region/list.py b/src/phoebe_bird/resources/ref/region/list.py index 0d6b016..d7a044f 100644 --- a/src/phoebe_bird/resources/ref/region/list.py +++ b/src/phoebe_bird/resources/ref/region/list.py @@ -7,7 +7,7 @@ import httpx from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ...._utils import maybe_transform, async_maybe_transform +from ...._utils import path_template, maybe_transform, async_maybe_transform from ...._compat import cached_property from ...._resource import SyncAPIResource, AsyncAPIResource from ...._response import ( @@ -24,6 +24,8 @@ class ListResource(SyncAPIResource): + """The ref/region end-points return information on regions.""" + @cached_property def with_raw_response(self) -> ListResourceWithRawResponse: """ @@ -79,7 +81,11 @@ def list( if not parent_region_code: raise ValueError(f"Expected a non-empty value for `parent_region_code` but received {parent_region_code!r}") return self._get( - f"/ref/region/list/{region_type}/{parent_region_code}", + path_template( + "/ref/region/list/{region_type}/{parent_region_code}", + region_type=region_type, + parent_region_code=parent_region_code, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -92,6 +98,8 @@ def list( class AsyncListResource(AsyncAPIResource): + """The ref/region end-points return information on regions.""" + @cached_property def with_raw_response(self) -> AsyncListResourceWithRawResponse: """ @@ -147,7 +155,11 @@ async def list( if not parent_region_code: raise ValueError(f"Expected a non-empty value for `parent_region_code` but received {parent_region_code!r}") return await self._get( - f"/ref/region/list/{region_type}/{parent_region_code}", + path_template( + "/ref/region/list/{region_type}/{parent_region_code}", + region_type=region_type, + parent_region_code=parent_region_code, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, diff --git a/src/phoebe_bird/resources/ref/region/region.py b/src/phoebe_bird/resources/ref/region/region.py index 567c15b..0962f3c 100644 --- a/src/phoebe_bird/resources/ref/region/region.py +++ b/src/phoebe_bird/resources/ref/region/region.py @@ -35,14 +35,17 @@ class RegionResource(SyncAPIResource): @cached_property def adjacent(self) -> AdjacentResource: + """With the ref/geo end-point you can find a country's or region's neighbours.""" return AdjacentResource(self._client) @cached_property def info(self) -> InfoResource: + """The ref/region end-points return information on regions.""" return InfoResource(self._client) @cached_property def list(self) -> ListResource: + """The ref/region end-points return information on regions.""" return ListResource(self._client) @cached_property @@ -68,14 +71,17 @@ def with_streaming_response(self) -> RegionResourceWithStreamingResponse: class AsyncRegionResource(AsyncAPIResource): @cached_property def adjacent(self) -> AsyncAdjacentResource: + """With the ref/geo end-point you can find a country's or region's neighbours.""" return AsyncAdjacentResource(self._client) @cached_property def info(self) -> AsyncInfoResource: + """The ref/region end-points return information on regions.""" return AsyncInfoResource(self._client) @cached_property def list(self) -> AsyncListResource: + """The ref/region end-points return information on regions.""" return AsyncListResource(self._client) @cached_property @@ -104,14 +110,17 @@ def __init__(self, region: RegionResource) -> None: @cached_property def adjacent(self) -> AdjacentResourceWithRawResponse: + """With the ref/geo end-point you can find a country's or region's neighbours.""" return AdjacentResourceWithRawResponse(self._region.adjacent) @cached_property def info(self) -> InfoResourceWithRawResponse: + """The ref/region end-points return information on regions.""" return InfoResourceWithRawResponse(self._region.info) @cached_property def list(self) -> ListResourceWithRawResponse: + """The ref/region end-points return information on regions.""" return ListResourceWithRawResponse(self._region.list) @@ -121,14 +130,17 @@ def __init__(self, region: AsyncRegionResource) -> None: @cached_property def adjacent(self) -> AsyncAdjacentResourceWithRawResponse: + """With the ref/geo end-point you can find a country's or region's neighbours.""" return AsyncAdjacentResourceWithRawResponse(self._region.adjacent) @cached_property def info(self) -> AsyncInfoResourceWithRawResponse: + """The ref/region end-points return information on regions.""" return AsyncInfoResourceWithRawResponse(self._region.info) @cached_property def list(self) -> AsyncListResourceWithRawResponse: + """The ref/region end-points return information on regions.""" return AsyncListResourceWithRawResponse(self._region.list) @@ -138,14 +150,17 @@ def __init__(self, region: RegionResource) -> None: @cached_property def adjacent(self) -> AdjacentResourceWithStreamingResponse: + """With the ref/geo end-point you can find a country's or region's neighbours.""" return AdjacentResourceWithStreamingResponse(self._region.adjacent) @cached_property def info(self) -> InfoResourceWithStreamingResponse: + """The ref/region end-points return information on regions.""" return InfoResourceWithStreamingResponse(self._region.info) @cached_property def list(self) -> ListResourceWithStreamingResponse: + """The ref/region end-points return information on regions.""" return ListResourceWithStreamingResponse(self._region.list) @@ -155,12 +170,15 @@ def __init__(self, region: AsyncRegionResource) -> None: @cached_property def adjacent(self) -> AsyncAdjacentResourceWithStreamingResponse: + """With the ref/geo end-point you can find a country's or region's neighbours.""" return AsyncAdjacentResourceWithStreamingResponse(self._region.adjacent) @cached_property def info(self) -> AsyncInfoResourceWithStreamingResponse: + """The ref/region end-points return information on regions.""" return AsyncInfoResourceWithStreamingResponse(self._region.info) @cached_property def list(self) -> AsyncListResourceWithStreamingResponse: + """The ref/region end-points return information on regions.""" return AsyncListResourceWithStreamingResponse(self._region.list) diff --git a/src/phoebe_bird/resources/ref/taxonomy/forms.py b/src/phoebe_bird/resources/ref/taxonomy/forms.py index bf613b2..d90591b 100644 --- a/src/phoebe_bird/resources/ref/taxonomy/forms.py +++ b/src/phoebe_bird/resources/ref/taxonomy/forms.py @@ -5,6 +5,7 @@ import httpx from ...._types import Body, Query, Headers, NotGiven, not_given +from ...._utils import path_template from ...._compat import cached_property from ...._resource import SyncAPIResource, AsyncAPIResource from ...._response import ( @@ -67,7 +68,7 @@ def list( if not species_code: raise ValueError(f"Expected a non-empty value for `species_code` but received {species_code!r}") return self._get( - f"/ref/taxon/forms/{species_code}", + path_template("/ref/taxon/forms/{species_code}", species_code=species_code), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -123,7 +124,7 @@ async def list( if not species_code: raise ValueError(f"Expected a non-empty value for `species_code` but received {species_code!r}") return await self._get( - f"/ref/taxon/forms/{species_code}", + path_template("/ref/taxon/forms/{species_code}", species_code=species_code), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/phoebe_bird/resources/ref/taxonomy/species_groups.py b/src/phoebe_bird/resources/ref/taxonomy/species_groups.py index 78bc36c..fd666be 100644 --- a/src/phoebe_bird/resources/ref/taxonomy/species_groups.py +++ b/src/phoebe_bird/resources/ref/taxonomy/species_groups.py @@ -7,7 +7,7 @@ import httpx from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ...._utils import maybe_transform, async_maybe_transform +from ...._utils import path_template, maybe_transform, async_maybe_transform from ...._compat import cached_property from ...._resource import SyncAPIResource, AsyncAPIResource from ...._response import ( @@ -78,7 +78,7 @@ def list( if not species_grouping: raise ValueError(f"Expected a non-empty value for `species_grouping` but received {species_grouping!r}") return self._get( - f"/ref/sppgroup/{species_grouping}", + path_template("/ref/sppgroup/{species_grouping}", species_grouping=species_grouping), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -147,7 +147,7 @@ async def list( if not species_grouping: raise ValueError(f"Expected a non-empty value for `species_grouping` but received {species_grouping!r}") return await self._get( - f"/ref/sppgroup/{species_grouping}", + path_template("/ref/sppgroup/{species_grouping}", species_grouping=species_grouping), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, diff --git a/tests/test_client.py b/tests/test_client.py index 40d5d13..060c0dc 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -8,10 +8,11 @@ import json import asyncio import inspect +import dataclasses import tracemalloc -from typing import Any, Union, cast +from typing import Any, Union, TypeVar, Callable, Iterable, Iterator, Optional, Coroutine, cast from unittest import mock -from typing_extensions import Literal +from typing_extensions import Literal, AsyncIterator, override import httpx import pytest @@ -36,6 +37,7 @@ from .utils import update_env +T = TypeVar("T") base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") api_key = "My API Key" @@ -50,6 +52,57 @@ def _low_retry_timeout(*_args: Any, **_kwargs: Any) -> float: return 0.1 +def mirror_request_content(request: httpx.Request) -> httpx.Response: + return httpx.Response(200, content=request.content) + + +# note: we can't use the httpx.MockTransport class as it consumes the request +# body itself, which means we can't test that the body is read lazily +class MockTransport(httpx.BaseTransport, httpx.AsyncBaseTransport): + def __init__( + self, + handler: Callable[[httpx.Request], httpx.Response] + | Callable[[httpx.Request], Coroutine[Any, Any, httpx.Response]], + ) -> None: + self.handler = handler + + @override + def handle_request( + self, + request: httpx.Request, + ) -> httpx.Response: + assert not inspect.iscoroutinefunction(self.handler), "handler must not be a coroutine function" + assert inspect.isfunction(self.handler), "handler must be a function" + return self.handler(request) + + @override + async def handle_async_request( + self, + request: httpx.Request, + ) -> httpx.Response: + assert inspect.iscoroutinefunction(self.handler), "handler must be a coroutine function" + return await self.handler(request) + + +@dataclasses.dataclass +class Counter: + value: int = 0 + + +def _make_sync_iterator(iterable: Iterable[T], counter: Optional[Counter] = None) -> Iterator[T]: + for item in iterable: + if counter: + counter.value += 1 + yield item + + +async def _make_async_iterator(iterable: Iterable[T], counter: Optional[Counter] = None) -> AsyncIterator[T]: + for item in iterable: + if counter: + counter.value += 1 + yield item + + def _get_open_connections(client: Phoebe | AsyncPhoebe) -> int: transport = client._client._transport assert isinstance(transport, httpx.HTTPTransport) or isinstance(transport, httpx.AsyncHTTPTransport) @@ -374,6 +427,30 @@ def test_default_query_option(self) -> None: client.close() + def test_hardcoded_query_params_in_url(self, client: Phoebe) -> None: + request = client._build_request(FinalRequestOptions(method="get", url="/foo?beta=true")) + url = httpx.URL(request.url) + assert dict(url.params) == {"beta": "true"} + + request = client._build_request( + FinalRequestOptions( + method="get", + url="/foo?beta=true", + params={"limit": "10", "page": "abc"}, + ) + ) + url = httpx.URL(request.url) + assert dict(url.params) == {"beta": "true", "limit": "10", "page": "abc"} + + request = client._build_request( + FinalRequestOptions( + method="get", + url="/files/a%2Fb?beta=true", + params={"limit": "10"}, + ) + ) + assert request.url.raw_path == b"/files/a%2Fb?beta=true&limit=10" + def test_request_extra_json(self, client: Phoebe) -> None: request = client._build_request( FinalRequestOptions( @@ -500,6 +577,70 @@ def test_multipart_repeating_array(self, client: Phoebe) -> None: b"", ] + @pytest.mark.respx(base_url=base_url) + def test_binary_content_upload(self, respx_mock: MockRouter, client: Phoebe) -> None: + respx_mock.post("/upload").mock(side_effect=mirror_request_content) + + file_content = b"Hello, this is a test file." + + response = client.post( + "/upload", + content=file_content, + cast_to=httpx.Response, + options={"headers": {"Content-Type": "application/octet-stream"}}, + ) + + assert response.status_code == 200 + assert response.request.headers["Content-Type"] == "application/octet-stream" + assert response.content == file_content + + def test_binary_content_upload_with_iterator(self) -> None: + file_content = b"Hello, this is a test file." + counter = Counter() + iterator = _make_sync_iterator([file_content], counter=counter) + + def mock_handler(request: httpx.Request) -> httpx.Response: + assert counter.value == 0, "the request body should not have been read" + return httpx.Response(200, content=request.read()) + + with Phoebe( + base_url=base_url, + api_key=api_key, + _strict_response_validation=True, + http_client=httpx.Client(transport=MockTransport(handler=mock_handler)), + ) as client: + response = client.post( + "/upload", + content=iterator, + cast_to=httpx.Response, + options={"headers": {"Content-Type": "application/octet-stream"}}, + ) + + assert response.status_code == 200 + assert response.request.headers["Content-Type"] == "application/octet-stream" + assert response.content == file_content + assert counter.value == 1 + + @pytest.mark.respx(base_url=base_url) + def test_binary_content_upload_with_body_is_deprecated(self, respx_mock: MockRouter, client: Phoebe) -> None: + respx_mock.post("/upload").mock(side_effect=mirror_request_content) + + file_content = b"Hello, this is a test file." + + with pytest.deprecated_call( + match="Passing raw bytes as `body` is deprecated and will be removed in a future version. Please pass raw bytes via the `content` parameter instead." + ): + response = client.post( + "/upload", + body=file_content, + cast_to=httpx.Response, + options={"headers": {"Content-Type": "application/octet-stream"}}, + ) + + assert response.status_code == 200 + assert response.request.headers["Content-Type"] == "application/octet-stream" + assert response.content == file_content + @pytest.mark.respx(base_url=base_url) def test_basic_union_response(self, respx_mock: MockRouter, client: Phoebe) -> None: class Model1(BaseModel): @@ -832,6 +973,14 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: def test_proxy_environment_variables(self, monkeypatch: pytest.MonkeyPatch) -> None: # Test that the proxy environment variables are set correctly monkeypatch.setenv("HTTPS_PROXY", "https://example.org") + # Delete in case our environment has any proxy env vars set + monkeypatch.delenv("HTTP_PROXY", raising=False) + monkeypatch.delenv("ALL_PROXY", raising=False) + monkeypatch.delenv("NO_PROXY", raising=False) + monkeypatch.delenv("http_proxy", raising=False) + monkeypatch.delenv("https_proxy", raising=False) + monkeypatch.delenv("all_proxy", raising=False) + monkeypatch.delenv("no_proxy", raising=False) client = DefaultHttpxClient() @@ -1197,6 +1346,30 @@ async def test_default_query_option(self) -> None: await client.close() + async def test_hardcoded_query_params_in_url(self, async_client: AsyncPhoebe) -> None: + request = async_client._build_request(FinalRequestOptions(method="get", url="/foo?beta=true")) + url = httpx.URL(request.url) + assert dict(url.params) == {"beta": "true"} + + request = async_client._build_request( + FinalRequestOptions( + method="get", + url="/foo?beta=true", + params={"limit": "10", "page": "abc"}, + ) + ) + url = httpx.URL(request.url) + assert dict(url.params) == {"beta": "true", "limit": "10", "page": "abc"} + + request = async_client._build_request( + FinalRequestOptions( + method="get", + url="/files/a%2Fb?beta=true", + params={"limit": "10"}, + ) + ) + assert request.url.raw_path == b"/files/a%2Fb?beta=true&limit=10" + def test_request_extra_json(self, client: Phoebe) -> None: request = client._build_request( FinalRequestOptions( @@ -1323,6 +1496,72 @@ def test_multipart_repeating_array(self, async_client: AsyncPhoebe) -> None: b"", ] + @pytest.mark.respx(base_url=base_url) + async def test_binary_content_upload(self, respx_mock: MockRouter, async_client: AsyncPhoebe) -> None: + respx_mock.post("/upload").mock(side_effect=mirror_request_content) + + file_content = b"Hello, this is a test file." + + response = await async_client.post( + "/upload", + content=file_content, + cast_to=httpx.Response, + options={"headers": {"Content-Type": "application/octet-stream"}}, + ) + + assert response.status_code == 200 + assert response.request.headers["Content-Type"] == "application/octet-stream" + assert response.content == file_content + + async def test_binary_content_upload_with_asynciterator(self) -> None: + file_content = b"Hello, this is a test file." + counter = Counter() + iterator = _make_async_iterator([file_content], counter=counter) + + async def mock_handler(request: httpx.Request) -> httpx.Response: + assert counter.value == 0, "the request body should not have been read" + return httpx.Response(200, content=await request.aread()) + + async with AsyncPhoebe( + base_url=base_url, + api_key=api_key, + _strict_response_validation=True, + http_client=httpx.AsyncClient(transport=MockTransport(handler=mock_handler)), + ) as client: + response = await client.post( + "/upload", + content=iterator, + cast_to=httpx.Response, + options={"headers": {"Content-Type": "application/octet-stream"}}, + ) + + assert response.status_code == 200 + assert response.request.headers["Content-Type"] == "application/octet-stream" + assert response.content == file_content + assert counter.value == 1 + + @pytest.mark.respx(base_url=base_url) + async def test_binary_content_upload_with_body_is_deprecated( + self, respx_mock: MockRouter, async_client: AsyncPhoebe + ) -> None: + respx_mock.post("/upload").mock(side_effect=mirror_request_content) + + file_content = b"Hello, this is a test file." + + with pytest.deprecated_call( + match="Passing raw bytes as `body` is deprecated and will be removed in a future version. Please pass raw bytes via the `content` parameter instead." + ): + response = await async_client.post( + "/upload", + body=file_content, + cast_to=httpx.Response, + options={"headers": {"Content-Type": "application/octet-stream"}}, + ) + + assert response.status_code == 200 + assert response.request.headers["Content-Type"] == "application/octet-stream" + assert response.content == file_content + @pytest.mark.respx(base_url=base_url) async def test_basic_union_response(self, respx_mock: MockRouter, async_client: AsyncPhoebe) -> None: class Model1(BaseModel): @@ -1672,6 +1911,14 @@ async def test_get_platform(self) -> None: async def test_proxy_environment_variables(self, monkeypatch: pytest.MonkeyPatch) -> None: # Test that the proxy environment variables are set correctly monkeypatch.setenv("HTTPS_PROXY", "https://example.org") + # Delete in case our environment has any proxy env vars set + monkeypatch.delenv("HTTP_PROXY", raising=False) + monkeypatch.delenv("ALL_PROXY", raising=False) + monkeypatch.delenv("NO_PROXY", raising=False) + monkeypatch.delenv("http_proxy", raising=False) + monkeypatch.delenv("https_proxy", raising=False) + monkeypatch.delenv("all_proxy", raising=False) + monkeypatch.delenv("no_proxy", raising=False) client = DefaultAsyncHttpxClient() diff --git a/tests/test_deepcopy.py b/tests/test_deepcopy.py deleted file mode 100644 index 130e750..0000000 --- a/tests/test_deepcopy.py +++ /dev/null @@ -1,58 +0,0 @@ -from phoebe_bird._utils import deepcopy_minimal - - -def assert_different_identities(obj1: object, obj2: object) -> None: - assert obj1 == obj2 - assert id(obj1) != id(obj2) - - -def test_simple_dict() -> None: - obj1 = {"foo": "bar"} - obj2 = deepcopy_minimal(obj1) - assert_different_identities(obj1, obj2) - - -def test_nested_dict() -> None: - obj1 = {"foo": {"bar": True}} - obj2 = deepcopy_minimal(obj1) - assert_different_identities(obj1, obj2) - assert_different_identities(obj1["foo"], obj2["foo"]) - - -def test_complex_nested_dict() -> None: - obj1 = {"foo": {"bar": [{"hello": "world"}]}} - obj2 = deepcopy_minimal(obj1) - assert_different_identities(obj1, obj2) - assert_different_identities(obj1["foo"], obj2["foo"]) - assert_different_identities(obj1["foo"]["bar"], obj2["foo"]["bar"]) - assert_different_identities(obj1["foo"]["bar"][0], obj2["foo"]["bar"][0]) - - -def test_simple_list() -> None: - obj1 = ["a", "b", "c"] - obj2 = deepcopy_minimal(obj1) - assert_different_identities(obj1, obj2) - - -def test_nested_list() -> None: - obj1 = ["a", [1, 2, 3]] - obj2 = deepcopy_minimal(obj1) - assert_different_identities(obj1, obj2) - assert_different_identities(obj1[1], obj2[1]) - - -class MyObject: ... - - -def test_ignores_other_types() -> None: - # custom classes - my_obj = MyObject() - obj1 = {"foo": my_obj} - obj2 = deepcopy_minimal(obj1) - assert_different_identities(obj1, obj2) - assert obj1["foo"] is my_obj - - # tuples - obj3 = ("a", "b") - obj4 = deepcopy_minimal(obj3) - assert obj3 is obj4 diff --git a/tests/test_extract_files.py b/tests/test_extract_files.py index bceaeab..82bc6fc 100644 --- a/tests/test_extract_files.py +++ b/tests/test_extract_files.py @@ -4,7 +4,7 @@ import pytest -from phoebe_bird._types import FileTypes +from phoebe_bird._types import FileTypes, ArrayFormat from phoebe_bird._utils import extract_files @@ -35,6 +35,12 @@ def test_multiple_files() -> None: assert query == {"documents": [{}, {}]} +def test_top_level_file_array() -> None: + query = {"files": [b"file one", b"file two"], "title": "hello"} + assert extract_files(query, paths=[["files", ""]]) == [("files[]", b"file one"), ("files[]", b"file two")] + assert query == {"title": "hello"} + + @pytest.mark.parametrize( "query,paths,expected", [ @@ -62,3 +68,24 @@ def test_ignores_incorrect_paths( expected: list[tuple[str, FileTypes]], ) -> None: assert extract_files(query, paths=paths) == expected + + +@pytest.mark.parametrize( + "array_format,expected_top_level,expected_nested", + [ + ("brackets", [("files[]", b"a"), ("files[]", b"b")], [("items[][file]", b"a"), ("items[][file]", b"b")]), + ("repeat", [("files", b"a"), ("files", b"b")], [("items[file]", b"a"), ("items[file]", b"b")]), + ("comma", [("files", b"a"), ("files", b"b")], [("items[file]", b"a"), ("items[file]", b"b")]), + ("indices", [("files[0]", b"a"), ("files[1]", b"b")], [("items[0][file]", b"a"), ("items[1][file]", b"b")]), + ], +) +def test_array_format_controls_file_field_names( + array_format: ArrayFormat, + expected_top_level: list[tuple[str, FileTypes]], + expected_nested: list[tuple[str, FileTypes]], +) -> None: + top_level = {"files": [b"a", b"b"]} + assert extract_files(top_level, paths=[["files", ""]], array_format=array_format) == expected_top_level + + nested = {"items": [{"file": b"a"}, {"file": b"b"}]} + assert extract_files(nested, paths=[["items", "", "file"]], array_format=array_format) == expected_nested diff --git a/tests/test_files.py b/tests/test_files.py index b87ebd3..0b3424d 100644 --- a/tests/test_files.py +++ b/tests/test_files.py @@ -4,7 +4,8 @@ import pytest from dirty_equals import IsDict, IsList, IsBytes, IsTuple -from phoebe_bird._files import to_httpx_files, async_to_httpx_files +from phoebe_bird._files import to_httpx_files, deepcopy_with_paths, async_to_httpx_files +from phoebe_bird._utils import extract_files readme_path = Path(__file__).parent.parent.joinpath("README.md") @@ -49,3 +50,99 @@ def test_string_not_allowed() -> None: "file": "foo", # type: ignore } ) + + +def assert_different_identities(obj1: object, obj2: object) -> None: + assert obj1 == obj2 + assert obj1 is not obj2 + + +class TestDeepcopyWithPaths: + def test_copies_top_level_dict(self) -> None: + original = {"file": b"data", "other": "value"} + result = deepcopy_with_paths(original, [["file"]]) + assert_different_identities(result, original) + + def test_file_value_is_same_reference(self) -> None: + file_bytes = b"contents" + original = {"file": file_bytes} + result = deepcopy_with_paths(original, [["file"]]) + assert_different_identities(result, original) + assert result["file"] is file_bytes + + def test_list_popped_wholesale(self) -> None: + files = [b"f1", b"f2"] + original = {"files": files, "title": "t"} + result = deepcopy_with_paths(original, [["files", ""]]) + assert_different_identities(result, original) + result_files = result["files"] + assert isinstance(result_files, list) + assert_different_identities(result_files, files) + + def test_nested_array_path_copies_list_and_elements(self) -> None: + elem1 = {"file": b"f1", "extra": 1} + elem2 = {"file": b"f2", "extra": 2} + original = {"items": [elem1, elem2]} + result = deepcopy_with_paths(original, [["items", "", "file"]]) + assert_different_identities(result, original) + result_items = result["items"] + assert isinstance(result_items, list) + assert_different_identities(result_items, original["items"]) + assert_different_identities(result_items[0], elem1) + assert_different_identities(result_items[1], elem2) + + def test_empty_paths_returns_same_object(self) -> None: + original = {"foo": "bar"} + result = deepcopy_with_paths(original, []) + assert result is original + + def test_multiple_paths(self) -> None: + f1 = b"file1" + f2 = b"file2" + original = {"a": f1, "b": f2, "c": "unchanged"} + result = deepcopy_with_paths(original, [["a"], ["b"]]) + assert_different_identities(result, original) + assert result["a"] is f1 + assert result["b"] is f2 + assert result["c"] is original["c"] + + def test_extract_files_does_not_mutate_original_top_level(self) -> None: + file_bytes = b"contents" + original = {"file": file_bytes, "other": "value"} + + copied = deepcopy_with_paths(original, [["file"]]) + extracted = extract_files(copied, paths=[["file"]]) + + assert extracted == [("file", file_bytes)] + assert original == {"file": file_bytes, "other": "value"} + assert copied == {"other": "value"} + + def test_extract_files_does_not_mutate_original_nested_array_path(self) -> None: + file1 = b"f1" + file2 = b"f2" + original = { + "items": [ + {"file": file1, "extra": 1}, + {"file": file2, "extra": 2}, + ], + "title": "example", + } + + copied = deepcopy_with_paths(original, [["items", "", "file"]]) + extracted = extract_files(copied, paths=[["items", "", "file"]]) + + assert [entry for _, entry in extracted] == [file1, file2] + assert original == { + "items": [ + {"file": file1, "extra": 1}, + {"file": file2, "extra": 2}, + ], + "title": "example", + } + assert copied == { + "items": [ + {"extra": 1}, + {"extra": 2}, + ], + "title": "example", + } diff --git a/tests/test_models.py b/tests/test_models.py index 02ab4e5..7ebd49d 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -1,7 +1,8 @@ import json -from typing import TYPE_CHECKING, Any, Dict, List, Union, Optional, cast +from typing import TYPE_CHECKING, Any, Dict, List, Union, Iterable, Optional, cast from datetime import datetime, timezone -from typing_extensions import Literal, Annotated, TypeAliasType +from collections import deque +from typing_extensions import Literal, Annotated, TypedDict, TypeAliasType import pytest import pydantic @@ -9,7 +10,7 @@ from phoebe_bird._utils import PropertyInfo from phoebe_bird._compat import PYDANTIC_V1, parse_obj, model_dump, model_json -from phoebe_bird._models import DISCRIMINATOR_CACHE, BaseModel, construct_type +from phoebe_bird._models import DISCRIMINATOR_CACHE, BaseModel, EagerIterable, construct_type class BasicModel(BaseModel): @@ -961,3 +962,56 @@ def __getattr__(self, attr: str) -> Item: ... assert model.a.prop == 1 assert isinstance(model.a, Item) assert model.other == "foo" + + +# NOTE: Workaround for Pydantic Iterable behavior. +# Iterable fields are replaced with a ValidatorIterator and may be consumed +# during serialization, which can cause subsequent dumps to return empty data. +# See: https://github.com/pydantic/pydantic/issues/9541 +@pytest.mark.parametrize( + "data, expected_validated", + [ + ([1, 2, 3], [1, 2, 3]), + ((1, 2, 3), (1, 2, 3)), + (set([1, 2, 3]), set([1, 2, 3])), + (iter([1, 2, 3]), [1, 2, 3]), + ([], []), + ((x for x in [1, 2, 3]), [1, 2, 3]), + (map(lambda x: x, [1, 2, 3]), [1, 2, 3]), + (frozenset([1, 2, 3]), frozenset([1, 2, 3])), + (deque([1, 2, 3]), deque([1, 2, 3])), + ], + ids=["list", "tuple", "set", "iterator", "empty", "generator", "map", "frozenset", "deque"], +) +@pytest.mark.skipif(PYDANTIC_V1, reason="this is only supported in pydantic v2") +def test_iterable_construction(data: Iterable[int], expected_validated: Iterable[int]) -> None: + class TypeWithIterable(TypedDict): + items: EagerIterable[int] + + class Model(BaseModel): + data: TypeWithIterable + + m = Model.model_validate({"data": {"items": data}}) + assert m.data["items"] == expected_validated + + # Verify repeated dumps don't lose data (the original bug) + assert m.model_dump()["data"]["items"] == list(expected_validated) + assert m.model_dump()["data"]["items"] == list(expected_validated) + + +@pytest.mark.skipif(PYDANTIC_V1, reason="this is only supported in pydantic v2") +def test_iterable_construction_str_falls_back_to_list() -> None: + # str is iterable (over chars), but str(list_of_chars) produces the list's repr + # rather than reconstructing a string from items. We special-case str to fall + # back to list instead of attempting reconstruction. + class TypeWithIterable(TypedDict): + items: EagerIterable[str] + + class Model(BaseModel): + data: TypeWithIterable + + m = Model.model_validate({"data": {"items": "hello"}}) + + # falls back to list of chars rather than calling str(["h", "e", "l", "l", "o"]) + assert m.data["items"] == ["h", "e", "l", "l", "o"] + assert m.model_dump()["data"]["items"] == ["h", "e", "l", "l", "o"] diff --git a/tests/test_utils/test_json.py b/tests/test_utils/test_json.py new file mode 100644 index 0000000..22dbc33 --- /dev/null +++ b/tests/test_utils/test_json.py @@ -0,0 +1,126 @@ +from __future__ import annotations + +import datetime +from typing import Union + +import pydantic + +from phoebe_bird import _compat +from phoebe_bird._utils._json import openapi_dumps + + +class TestOpenapiDumps: + def test_basic(self) -> None: + data = {"key": "value", "number": 42} + json_bytes = openapi_dumps(data) + assert json_bytes == b'{"key":"value","number":42}' + + def test_datetime_serialization(self) -> None: + dt = datetime.datetime(2023, 1, 1, 12, 0, 0) + data = {"datetime": dt} + json_bytes = openapi_dumps(data) + assert json_bytes == b'{"datetime":"2023-01-01T12:00:00"}' + + def test_pydantic_model_serialization(self) -> None: + class User(pydantic.BaseModel): + first_name: str + last_name: str + age: int + + model_instance = User(first_name="John", last_name="Kramer", age=83) + data = {"model": model_instance} + json_bytes = openapi_dumps(data) + assert json_bytes == b'{"model":{"first_name":"John","last_name":"Kramer","age":83}}' + + def test_pydantic_model_with_default_values(self) -> None: + class User(pydantic.BaseModel): + name: str + role: str = "user" + active: bool = True + score: int = 0 + + model_instance = User(name="Alice") + data = {"model": model_instance} + json_bytes = openapi_dumps(data) + assert json_bytes == b'{"model":{"name":"Alice"}}' + + def test_pydantic_model_with_default_values_overridden(self) -> None: + class User(pydantic.BaseModel): + name: str + role: str = "user" + active: bool = True + + model_instance = User(name="Bob", role="admin", active=False) + data = {"model": model_instance} + json_bytes = openapi_dumps(data) + assert json_bytes == b'{"model":{"name":"Bob","role":"admin","active":false}}' + + def test_pydantic_model_with_alias(self) -> None: + class User(pydantic.BaseModel): + first_name: str = pydantic.Field(alias="firstName") + last_name: str = pydantic.Field(alias="lastName") + + model_instance = User(firstName="John", lastName="Doe") + data = {"model": model_instance} + json_bytes = openapi_dumps(data) + assert json_bytes == b'{"model":{"firstName":"John","lastName":"Doe"}}' + + def test_pydantic_model_with_alias_and_default(self) -> None: + class User(pydantic.BaseModel): + user_name: str = pydantic.Field(alias="userName") + user_role: str = pydantic.Field(default="member", alias="userRole") + is_active: bool = pydantic.Field(default=True, alias="isActive") + + model_instance = User(userName="charlie") + data = {"model": model_instance} + json_bytes = openapi_dumps(data) + assert json_bytes == b'{"model":{"userName":"charlie"}}' + + model_with_overrides = User(userName="diana", userRole="admin", isActive=False) + data = {"model": model_with_overrides} + json_bytes = openapi_dumps(data) + assert json_bytes == b'{"model":{"userName":"diana","userRole":"admin","isActive":false}}' + + def test_pydantic_model_with_nested_models_and_defaults(self) -> None: + class Address(pydantic.BaseModel): + street: str + city: str = "Unknown" + + class User(pydantic.BaseModel): + name: str + address: Address + verified: bool = False + + if _compat.PYDANTIC_V1: + # to handle forward references in Pydantic v1 + User.update_forward_refs(**locals()) # type: ignore[reportDeprecated] + + address = Address(street="123 Main St") + user = User(name="Diana", address=address) + data = {"user": user} + json_bytes = openapi_dumps(data) + assert json_bytes == b'{"user":{"name":"Diana","address":{"street":"123 Main St"}}}' + + address_with_city = Address(street="456 Oak Ave", city="Boston") + user_verified = User(name="Eve", address=address_with_city, verified=True) + data = {"user": user_verified} + json_bytes = openapi_dumps(data) + assert ( + json_bytes == b'{"user":{"name":"Eve","address":{"street":"456 Oak Ave","city":"Boston"},"verified":true}}' + ) + + def test_pydantic_model_with_optional_fields(self) -> None: + class User(pydantic.BaseModel): + name: str + email: Union[str, None] + phone: Union[str, None] + + model_with_none = User(name="Eve", email=None, phone=None) + data = {"model": model_with_none} + json_bytes = openapi_dumps(data) + assert json_bytes == b'{"model":{"name":"Eve","email":null,"phone":null}}' + + model_with_values = User(name="Frank", email="frank@example.com", phone=None) + data = {"model": model_with_values} + json_bytes = openapi_dumps(data) + assert json_bytes == b'{"model":{"name":"Frank","email":"frank@example.com","phone":null}}' diff --git a/tests/test_utils/test_path.py b/tests/test_utils/test_path.py new file mode 100644 index 0000000..4994e56 --- /dev/null +++ b/tests/test_utils/test_path.py @@ -0,0 +1,89 @@ +from __future__ import annotations + +from typing import Any + +import pytest + +from phoebe_bird._utils._path import path_template + + +@pytest.mark.parametrize( + "template, kwargs, expected", + [ + ("/v1/{id}", dict(id="abc"), "/v1/abc"), + ("/v1/{a}/{b}", dict(a="x", b="y"), "/v1/x/y"), + ("/v1/{a}{b}/path/{c}?val={d}#{e}", dict(a="x", b="y", c="z", d="u", e="v"), "/v1/xy/path/z?val=u#v"), + ("/{w}/{w}", dict(w="echo"), "/echo/echo"), + ("/v1/static", {}, "/v1/static"), + ("", {}, ""), + ("/v1/?q={n}&count=10", dict(n=42), "/v1/?q=42&count=10"), + ("/v1/{v}", dict(v=None), "/v1/null"), + ("/v1/{v}", dict(v=True), "/v1/true"), + ("/v1/{v}", dict(v=False), "/v1/false"), + ("/v1/{v}", dict(v=".hidden"), "/v1/.hidden"), # dot prefix ok + ("/v1/{v}", dict(v="file.txt"), "/v1/file.txt"), # dot in middle ok + ("/v1/{v}", dict(v="..."), "/v1/..."), # triple dot ok + ("/v1/{a}{b}", dict(a=".", b="txt"), "/v1/.txt"), # dot var combining with adjacent to be ok + ("/items?q={v}#{f}", dict(v=".", f=".."), "/items?q=.#.."), # dots in query/fragment are fine + ( + "/v1/{a}?query={b}", + dict(a="../../other/endpoint", b="a&bad=true"), + "/v1/..%2F..%2Fother%2Fendpoint?query=a%26bad%3Dtrue", + ), + ("/v1/{val}", dict(val="a/b/c"), "/v1/a%2Fb%2Fc"), + ("/v1/{val}", dict(val="a/b/c?query=value"), "/v1/a%2Fb%2Fc%3Fquery=value"), + ("/v1/{val}", dict(val="a/b/c?query=value&bad=true"), "/v1/a%2Fb%2Fc%3Fquery=value&bad=true"), + ("/v1/{val}", dict(val="%20"), "/v1/%2520"), # escapes escape sequences in input + # Query: slash and ? are safe, # is not + ("/items?q={v}", dict(v="a/b"), "/items?q=a/b"), + ("/items?q={v}", dict(v="a?b"), "/items?q=a?b"), + ("/items?q={v}", dict(v="a#b"), "/items?q=a%23b"), + ("/items?q={v}", dict(v="a b"), "/items?q=a%20b"), + # Fragment: slash and ? are safe + ("/docs#{v}", dict(v="a/b"), "/docs#a/b"), + ("/docs#{v}", dict(v="a?b"), "/docs#a?b"), + # Path: slash, ? and # are all encoded + ("/v1/{v}", dict(v="a/b"), "/v1/a%2Fb"), + ("/v1/{v}", dict(v="a?b"), "/v1/a%3Fb"), + ("/v1/{v}", dict(v="a#b"), "/v1/a%23b"), + # same var encoded differently by component + ( + "/v1/{v}?q={v}#{v}", + dict(v="a/b?c#d"), + "/v1/a%2Fb%3Fc%23d?q=a/b?c%23d#a/b?c%23d", + ), + ("/v1/{val}", dict(val="x?admin=true"), "/v1/x%3Fadmin=true"), # query injection + ("/v1/{val}", dict(val="x#admin"), "/v1/x%23admin"), # fragment injection + ], +) +def test_interpolation(template: str, kwargs: dict[str, Any], expected: str) -> None: + assert path_template(template, **kwargs) == expected + + +def test_missing_kwarg_raises_key_error() -> None: + with pytest.raises(KeyError, match="org_id"): + path_template("/v1/{org_id}") + + +@pytest.mark.parametrize( + "template, kwargs", + [ + ("{a}/path", dict(a=".")), + ("{a}/path", dict(a="..")), + ("/v1/{a}", dict(a=".")), + ("/v1/{a}", dict(a="..")), + ("/v1/{a}/path", dict(a=".")), + ("/v1/{a}/path", dict(a="..")), + ("/v1/{a}{b}", dict(a=".", b=".")), # adjacent vars → ".." + ("/v1/{a}.", dict(a=".")), # var + static → ".." + ("/v1/{a}{b}", dict(a="", b=".")), # empty + dot → "." + ("/v1/%2e/{x}", dict(x="ok")), # encoded dot in static text + ("/v1/%2e./{x}", dict(x="ok")), # mixed encoded ".." in static + ("/v1/.%2E/{x}", dict(x="ok")), # mixed encoded ".." in static + ("/v1/{v}?q=1", dict(v="..")), + ("/v1/{v}#frag", dict(v="..")), + ], +) +def test_dot_segment_rejected(template: str, kwargs: dict[str, Any]) -> None: + with pytest.raises(ValueError, match="dot-segment"): + path_template(template, **kwargs) From 7f505deb3f375922ec9defbf0924e855613cc566 Mon Sep 17 00:00:00 2001 From: David Meadows Date: Thu, 14 May 2026 16:41:50 -0400 Subject: [PATCH 2/6] chore: enable release-please Stainless-Generated-From: 6fd4ffbed78e198b832e885d8fd4f8f74ee80c32 --- .github/workflows/publish-pypi.yml | 8 ++++++-- .github/workflows/release-please.yml | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/release-please.yml diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index b51e415..c02b9bd 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -1,9 +1,13 @@ -# workflow for re-running publishing to PyPI in case it fails for some reason -# you can run this workflow by navigating to https://www.github.com/phoebe-bird/phoebe-python/actions/workflows/publish-pypi.yml +# This workflow is triggered when a GitHub release is created. +# It can also be run manually to re-publish to PyPI in case it failed for some reason. +# You can run this workflow by navigating to https://www.github.com/phoebe-bird/phoebe-python/actions/workflows/publish-pypi.yml name: Publish PyPI on: workflow_dispatch: + release: + types: [published] + jobs: publish: name: publish diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml new file mode 100644 index 0000000..8100ded --- /dev/null +++ b/.github/workflows/release-please.yml @@ -0,0 +1,20 @@ +name: Release Please +on: + push: + branches: + - main + +permissions: + contents: write + pull-requests: write + +jobs: + release-please: + if: github.repository == 'phoebe-bird/phoebe-python' + runs-on: ubuntu-latest + + steps: + - uses: googleapis/release-please-action@5c625bfb5d1ff62eadeeb3772007f7f66fdcf071 # v4.4.1 + id: release + with: + token: ${{ secrets.RELEASE_PLEASE_TOKEN }} From e216ecb0499786727a38c6aaa5e8855f14e6d8b9 Mon Sep 17 00:00:00 2001 From: dtmeadows Date: Thu, 14 May 2026 16:47:47 -0400 Subject: [PATCH 3/6] Add promote workflow (Phase 7) --- .github/workflows/stlc-promote.yml | 64 ++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 .github/workflows/stlc-promote.yml diff --git a/.github/workflows/stlc-promote.yml b/.github/workflows/stlc-promote.yml new file mode 100644 index 0000000..5c4631a --- /dev/null +++ b/.github/workflows/stlc-promote.yml @@ -0,0 +1,64 @@ +name: Promote SDKs + +on: + push: + branches: [main] + +permissions: + contents: read + +jobs: + promote: + runs-on: ubuntu-latest + env: + PRODUCTION_REPO: phoebe-bird/phoebe-python + GH_TOKEN: ${{ secrets.PRODUCTION_REPO_TOKEN }} + steps: + - name: Check out staging + uses: actions/checkout@v6 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Fetch production main + run: | + git remote add production \ + "https://x-access-token:${GH_TOKEN}@github.com/${PRODUCTION_REPO}.git" + git fetch production main + + - name: Check if production is already in sync + id: diff + run: | + STAGING_SHA=$(git rev-parse origin/main) + PRODUCTION_SHA=$(git rev-parse production/main) + if [ "$STAGING_SHA" = "$PRODUCTION_SHA" ]; then + echo "Production is already at $STAGING_SHA. Nothing to release." + echo "synced=true" >> "$GITHUB_OUTPUT" + else + echo "synced=false" >> "$GITHUB_OUTPUT" + fi + + - name: Push staging main to the release branch on production + if: steps.diff.outputs.synced == 'false' + run: | + git push production origin/main:refs/heads/stainless/release --force + + - name: Open or update the release PR on production + if: steps.diff.outputs.synced == 'false' + run: | + EXISTING_PR=$(gh pr list \ + --repo "${PRODUCTION_REPO}" \ + --head stainless/release \ + --state open \ + --json number \ + --jq '.[0].number') + if [ -z "${EXISTING_PR}" ]; then + gh pr create \ + --repo "${PRODUCTION_REPO}" \ + --base main \ + --head stainless/release \ + --title "Release SDK updates" \ + --body "$(git log --oneline production/main..origin/main)" + else + echo "Release PR #${EXISTING_PR} already exists. Force-push has updated it." + fi From ebd826170c13e59c4a2fff4416e44d38db3a48fb Mon Sep 17 00:00:00 2001 From: dtmeadows Date: Thu, 14 May 2026 17:21:38 -0400 Subject: [PATCH 4/6] Add leak-bug guard: only run on -staging repos --- .github/workflows/stlc-promote.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/stlc-promote.yml b/.github/workflows/stlc-promote.yml index 5c4631a..030873b 100644 --- a/.github/workflows/stlc-promote.yml +++ b/.github/workflows/stlc-promote.yml @@ -9,6 +9,10 @@ permissions: jobs: promote: + # Guard: this workflow file gets propagated to the production repo during + # promotion. The guard prevents it from running there (where it would no-op + # but still waste a runner). + if: endsWith(github.repository, '-staging') runs-on: ubuntu-latest env: PRODUCTION_REPO: phoebe-bird/phoebe-python From bfbcf2b8f40a3353de1ea0f4316e4fef90b7aab4 Mon Sep 17 00:00:00 2001 From: David Meadows Date: Thu, 14 May 2026 17:23:31 -0400 Subject: [PATCH 5/6] feat: switch python SDK to uv (use_uv: true) Stainless-Generated-From: 95b1cd2c435baaea31892459e2c49420d2fe0496 --- .devcontainer/Dockerfile | 3 +- .devcontainer/devcontainer.json | 4 +- .github/workflows/ci.yml | 28 +- .github/workflows/publish-pypi.yml | 11 +- Brewfile | 2 +- CONTRIBUTING.md | 22 +- bin/publish-pypi | 5 +- noxfile.py | 9 - pyproject.toml | 52 +- requirements-dev.lock | 156 +-- requirements.lock | 75 -- scripts/bootstrap | 11 +- scripts/format | 10 +- scripts/lint | 16 +- scripts/mock | 2 +- scripts/test | 31 +- uv.lock | 1829 ++++++++++++++++++++++++++++ 17 files changed, 1994 insertions(+), 272 deletions(-) delete mode 100644 noxfile.py delete mode 100644 requirements.lock create mode 100644 uv.lock diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index ff261ba..62c2d13 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -3,7 +3,6 @@ FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT} USER vscode -RUN curl -sSf https://rye.astral.sh/get | RYE_VERSION="0.44.0" RYE_INSTALL_OPTION="--yes" bash -ENV PATH=/home/vscode/.rye/shims:$PATH +COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ RUN echo "[[ -d .venv ]] && source .venv/bin/activate || export PATH=\$PATH" >> /home/vscode/.bashrc diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index c17fdc1..e01283d 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -7,7 +7,7 @@ "context": ".." }, - "postStartCommand": "rye sync --all-features", + "postStartCommand": "uv sync --all-extras", "customizations": { "vscode": { @@ -20,7 +20,7 @@ "python.defaultInterpreterPath": ".venv/bin/python", "python.typeChecking": "basic", "terminal.integrated.env.linux": { - "PATH": "/home/vscode/.rye/shims:${env:PATH}" + "PATH": "${env:PATH}" } } } diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7bcc0a3..d2f2ce9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,16 +23,13 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: Install Rye - run: | - curl -sSf https://rye.astral.sh/get | bash - echo "$HOME/.rye/shims" >> $GITHUB_PATH - env: - RYE_VERSION: '0.44.0' - RYE_INSTALL_OPTION: '--yes' + - name: Install uv + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2 + with: + version: '0.10.2' - name: Install dependencies - run: rye sync --all-features + run: uv sync --all-extras - name: Run lints run: ./scripts/lint @@ -48,16 +45,13 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: Install Rye - run: | - curl -sSf https://rye.astral.sh/get | bash - echo "$HOME/.rye/shims" >> $GITHUB_PATH - env: - RYE_VERSION: '0.44.0' - RYE_INSTALL_OPTION: '--yes' + - name: Install uv + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2 + with: + version: '0.10.2' - name: Install dependencies - run: rye sync --all-features + run: uv sync --all-extras - name: Run build - run: rye build + run: uv build diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index c02b9bd..e2c5ee2 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -16,13 +16,10 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: Install Rye - run: | - curl -sSf https://rye.astral.sh/get | bash - echo "$HOME/.rye/shims" >> $GITHUB_PATH - env: - RYE_VERSION: '0.44.0' - RYE_INSTALL_OPTION: '--yes' + - name: Install uv + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2 + with: + version: '0.9.13' - name: Publish to PyPI run: | diff --git a/Brewfile b/Brewfile index 492ca37..c43041c 100644 --- a/Brewfile +++ b/Brewfile @@ -1,2 +1,2 @@ -brew "rye" +brew "uv" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 43f51db..a80fe24 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,32 +1,32 @@ ## Setting up the environment -### With Rye +### With `uv` -We use [Rye](https://rye.astral.sh/) to manage dependencies because it will automatically provision a Python environment with the expected Python version. To set it up, run: +We use [uv](https://docs.astral.sh/uv/) to manage dependencies because it will automatically provision a Python environment with the expected Python version. To set it up, run: ```sh $ ./scripts/bootstrap ``` -Or [install Rye manually](https://rye.astral.sh/guide/installation/) and run: +Or [install uv manually](https://docs.astral.sh/uv/getting-started/installation/) and run: ```sh -$ rye sync --all-features +$ uv sync --all-extras ``` -You can then run scripts using `rye run python script.py` or by activating the virtual environment: +You can then run scripts using `uv run python script.py` or by manually activating the virtual environment: ```sh -# Activate the virtual environment - https://docs.python.org/3/library/venv.html#how-venvs-work +# manually activate - https://docs.python.org/3/library/venv.html#how-venvs-work $ source .venv/bin/activate -# now you can omit the `rye run` prefix +# now you can omit the `uv run` prefix $ python script.py ``` -### Without Rye +### Without `uv` -Alternatively if you don't want to install `Rye`, you can stick with the standard `pip` setup by ensuring you have the Python version specified in `.python-version`, create a virtual environment however you desire and then install dependencies using this command: +Alternatively if you don't want to install `uv`, you can stick with the standard `pip` setup by ensuring you have the Python version specified in `.python-version`, create a virtual environment however you desire and then install dependencies using this command: ```sh $ pip install -r requirements-dev.lock @@ -45,7 +45,7 @@ All files in the `examples/` directory are not modified by the generator and can ```py # add an example to examples/.py -#!/usr/bin/env -S rye run python +#!/usr/bin/env -S uv run python … ``` @@ -72,7 +72,7 @@ Building this package will create two files in the `dist/` directory, a `.tar.gz To create a distributable version of the library, all you have to do is run this command: ```sh -$ rye build +$ uv build # or $ python -m build ``` diff --git a/bin/publish-pypi b/bin/publish-pypi index 826054e..e72ca2f 100644 --- a/bin/publish-pypi +++ b/bin/publish-pypi @@ -1,6 +1,7 @@ #!/usr/bin/env bash set -eux +rm -rf dist mkdir -p dist -rye build --clean -rye publish --yes --token=$PYPI_TOKEN +uv build +uv publish --token=$PYPI_TOKEN diff --git a/noxfile.py b/noxfile.py deleted file mode 100644 index 53bca7f..0000000 --- a/noxfile.py +++ /dev/null @@ -1,9 +0,0 @@ -import nox - - -@nox.session(reuse_venv=True, name="test-pydantic-v1") -def test_pydantic_v1(session: nox.Session) -> None: - session.install("-r", "requirements-dev.lock") - session.install("pydantic<2") - - session.run("pytest", "--showlocals", "--ignore=tests/functional", *session.posargs) diff --git a/pyproject.toml b/pyproject.toml index 248ab2b..9617f74 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,10 +43,19 @@ Repository = "https://github.com/phoebe-bird/phoebe-python" [project.optional-dependencies] aiohttp = ["aiohttp", "httpx_aiohttp>=0.1.9"] -[tool.rye] +[tool.uv] managed = true -# version pins are in requirements-dev.lock -dev-dependencies = [ +required-version = ">=0.9" +conflicts = [ + [ + { group = "pydantic-v1" }, + { group = "pydantic-v2" }, + ], +] + +[dependency-groups] +# version pins are in uv.lock +dev = [ "pyright==1.1.399", "mypy==1.17", "respx", @@ -54,41 +63,18 @@ dev-dependencies = [ "pytest-asyncio", "ruff", "time-machine", - "nox", "dirty-equals>=0.6.0", "importlib-metadata>=6.7.0", "rich>=13.7.1", "pytest-xdist>=3.6.1", ] - -[tool.rye.scripts] -format = { chain = [ - "format:ruff", - "format:docs", - "fix:ruff", - # run formatting again to fix any inconsistencies when imports are stripped - "format:ruff", -]} -"format:docs" = "bash -c 'python scripts/utils/ruffen-docs.py README.md $(find . -type f -name api.md)'" -"format:ruff" = "ruff format" - -"lint" = { chain = [ - "check:ruff", - "typecheck", - "check:importable", -]} -"check:ruff" = "ruff check ." -"fix:ruff" = "ruff check --fix ." - -"check:importable" = "python -c 'import phoebe_bird'" - -typecheck = { chain = [ - "typecheck:pyright", - "typecheck:mypy" -]} -"typecheck:pyright" = "pyright" -"typecheck:verify-types" = "pyright --verifytypes phoebe_bird --ignoreexternal" -"typecheck:mypy" = "mypy ." +pydantic-v1 = [ + "pydantic>=1.9.0,<2", +] +pydantic-v2 = [ + "pydantic~=2.0 ; python_full_version < '3.14'", + "pydantic~=2.12 ; python_full_version >= '3.14'", +] [build-system] requires = ["hatchling==1.26.3", "hatch-fancy-pypi-readme"] diff --git a/requirements-dev.lock b/requirements-dev.lock index 7cf2b51..3daf8d1 100644 --- a/requirements-dev.lock +++ b/requirements-dev.lock @@ -1,148 +1,110 @@ -# generated by rye -# use `rye lock` or `rye sync` to update this lockfile -# -# last locked with the following flags: -# pre: false -# features: [] -# all-features: true -# with-sources: false -# generate-hashes: false - --e file:. -aiohappyeyeballs==2.6.1 - # via aiohttp -aiohttp==3.13.3 - # via httpx-aiohttp - # via phoebe-bird -aiosignal==1.4.0 - # via aiohttp +# This file was autogenerated by uv via the following command: +# uv export -o requirements-dev.lock --no-hashes +-e . annotated-types==0.7.0 # via pydantic anyio==4.12.1 - # via httpx - # via phoebe-bird -argcomplete==3.6.3 - # via nox -async-timeout==5.0.1 - # via aiohttp -attrs==25.4.0 - # via aiohttp - # via nox -backports-asyncio-runner==1.2.0 + # via + # httpx + # phoebe-bird +backports-asyncio-runner==1.2.0 ; python_full_version < '3.11' # via pytest-asyncio certifi==2026.1.4 - # via httpcore - # via httpx -colorlog==6.10.1 - # via nox -dependency-groups==1.3.1 - # via nox + # via + # httpcore + # httpx +colorama==0.4.6 ; sys_platform == 'win32' + # via pytest dirty-equals==0.11 -distlib==0.4.0 - # via virtualenv distro==1.9.0 # via phoebe-bird -exceptiongroup==1.3.1 - # via anyio - # via pytest +exceptiongroup==1.3.1 ; python_full_version < '3.11' + # via + # anyio + # pytest execnet==2.1.2 # via pytest-xdist -filelock==3.19.1 - # via virtualenv -frozenlist==1.8.0 - # via aiohttp - # via aiosignal h11==0.16.0 # via httpcore httpcore==1.0.9 # via httpx httpx==0.28.1 - # via httpx-aiohttp - # via phoebe-bird - # via respx -httpx-aiohttp==0.1.12 - # via phoebe-bird -humanize==4.13.0 - # via nox + # via + # phoebe-bird + # respx idna==3.11 - # via anyio - # via httpx - # via yarl + # via + # anyio + # httpx importlib-metadata==8.7.1 -iniconfig==2.1.0 +iniconfig==2.1.0 ; python_full_version < '3.10' + # via pytest +iniconfig==2.3.0 ; python_full_version >= '3.10' # via pytest -markdown-it-py==3.0.0 +markdown-it-py==3.0.0 ; python_full_version < '3.10' + # via rich +markdown-it-py==4.0.0 ; python_full_version >= '3.10' # via rich mdurl==0.1.2 # via markdown-it-py -multidict==6.7.0 - # via aiohttp - # via yarl mypy==1.17.0 mypy-extensions==1.1.0 # via mypy nodeenv==1.10.0 # via pyright -nox==2025.11.12 packaging==25.0 - # via dependency-groups - # via nox # via pytest pathspec==1.0.3 # via mypy -platformdirs==4.4.0 - # via virtualenv pluggy==1.6.0 # via pytest -propcache==0.4.1 - # via aiohttp - # via yarl pydantic==2.12.5 # via phoebe-bird pydantic-core==2.41.5 # via pydantic pygments==2.19.2 - # via pytest - # via rich + # via + # pytest + # rich pyright==1.1.399 -pytest==8.4.2 - # via pytest-asyncio - # via pytest-xdist -pytest-asyncio==1.2.0 +pytest==8.4.2 ; python_full_version < '3.10' + # via + # pytest-asyncio + # pytest-xdist +pytest==9.0.2 ; python_full_version >= '3.10' + # via + # pytest-asyncio + # pytest-xdist +pytest-asyncio==1.2.0 ; python_full_version < '3.10' +pytest-asyncio==1.3.0 ; python_full_version >= '3.10' pytest-xdist==3.8.0 -python-dateutil==2.9.0.post0 +python-dateutil==2.9.0.post0 ; python_full_version < '3.10' # via time-machine respx==0.22.0 rich==14.2.0 ruff==0.14.13 -six==1.17.0 +six==1.17.0 ; python_full_version < '3.10' # via python-dateutil sniffio==1.3.1 # via phoebe-bird -time-machine==2.19.0 -tomli==2.4.0 - # via dependency-groups - # via mypy - # via nox - # via pytest +time-machine==2.19.0 ; python_full_version < '3.10' +time-machine==3.2.0 ; python_full_version >= '3.10' +tomli==2.4.0 ; python_full_version < '3.11' + # via + # mypy + # pytest typing-extensions==4.15.0 - # via aiosignal - # via anyio - # via exceptiongroup - # via multidict - # via mypy - # via phoebe-bird - # via pydantic - # via pydantic-core - # via pyright - # via pytest-asyncio - # via typing-inspection - # via virtualenv + # via + # anyio + # exceptiongroup + # mypy + # phoebe-bird + # pydantic + # pydantic-core + # pyright + # pytest-asyncio + # typing-inspection typing-inspection==0.4.2 # via pydantic -virtualenv==20.36.1 - # via nox -yarl==1.22.0 - # via aiohttp zipp==3.23.0 # via importlib-metadata diff --git a/requirements.lock b/requirements.lock deleted file mode 100644 index f926e8b..0000000 --- a/requirements.lock +++ /dev/null @@ -1,75 +0,0 @@ -# generated by rye -# use `rye lock` or `rye sync` to update this lockfile -# -# last locked with the following flags: -# pre: false -# features: [] -# all-features: true -# with-sources: false -# generate-hashes: false - --e file:. -aiohappyeyeballs==2.6.1 - # via aiohttp -aiohttp==3.13.3 - # via httpx-aiohttp - # via phoebe-bird -aiosignal==1.4.0 - # via aiohttp -annotated-types==0.7.0 - # via pydantic -anyio==4.12.1 - # via httpx - # via phoebe-bird -async-timeout==5.0.1 - # via aiohttp -attrs==25.4.0 - # via aiohttp -certifi==2026.1.4 - # via httpcore - # via httpx -distro==1.9.0 - # via phoebe-bird -exceptiongroup==1.3.1 - # via anyio -frozenlist==1.8.0 - # via aiohttp - # via aiosignal -h11==0.16.0 - # via httpcore -httpcore==1.0.9 - # via httpx -httpx==0.28.1 - # via httpx-aiohttp - # via phoebe-bird -httpx-aiohttp==0.1.12 - # via phoebe-bird -idna==3.11 - # via anyio - # via httpx - # via yarl -multidict==6.7.0 - # via aiohttp - # via yarl -propcache==0.4.1 - # via aiohttp - # via yarl -pydantic==2.12.5 - # via phoebe-bird -pydantic-core==2.41.5 - # via pydantic -sniffio==1.3.1 - # via phoebe-bird -typing-extensions==4.15.0 - # via aiosignal - # via anyio - # via exceptiongroup - # via multidict - # via phoebe-bird - # via pydantic - # via pydantic-core - # via typing-inspection -typing-inspection==0.4.2 - # via pydantic -yarl==1.22.0 - # via aiohttp diff --git a/scripts/bootstrap b/scripts/bootstrap index fe8451e..5a23841 100755 --- a/scripts/bootstrap +++ b/scripts/bootstrap @@ -19,9 +19,12 @@ if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "${SKIP_BREW:-}" != "1 } fi -echo "==> Installing Python dependencies…" +echo "==> Installing Python…" +uv python install -# experimental uv support makes installations significantly faster -rye config --set-bool behavior.use-uv=true +echo "==> Installing Python dependencies…" +uv sync --all-extras -rye sync --all-features +echo "==> Exporting Python dependencies…" +# note: `--no-hashes` is required because of https://github.com/pypa/pip/issues/4995 +uv export -o requirements-dev.lock --no-hashes diff --git a/scripts/format b/scripts/format index 667ec2d..c8e1f69 100755 --- a/scripts/format +++ b/scripts/format @@ -4,5 +4,11 @@ set -e cd "$(dirname "$0")/.." -echo "==> Running formatters" -rye run format +echo "==> Running ruff" +uv run ruff format +uv run ruff check --fix . +# run formatting again to fix any inconsistencies when imports are stripped +uv run ruff format + +echo "==> Formatting docs" +uv run python scripts/utils/ruffen-docs.py README.md $(find . -type f -name api.md) diff --git a/scripts/lint b/scripts/lint index a8a480e..5fa560f 100755 --- a/scripts/lint +++ b/scripts/lint @@ -5,12 +5,18 @@ set -e cd "$(dirname "$0")/.." if [ "$1" = "--fix" ]; then - echo "==> Running lints with --fix" - rye run fix:ruff + echo "==> Running ruff with --fix" + uv run ruff check . --fix else - echo "==> Running lints" - rye run lint + echo "==> Running ruff" + uv run ruff check . fi +echo "==> Running pyright" +uv run pyright + +echo "==> Running mypy" +uv run mypy . + echo "==> Making sure it imports" -rye run python -c 'import phoebe_bird' +uv run python -c 'import phoebe_bird' diff --git a/scripts/mock b/scripts/mock index d0666ff..f9961d2 100755 --- a/scripts/mock +++ b/scripts/mock @@ -11,7 +11,7 @@ elif [ -n "$STAINLESS_OPENAPI_SPEC_URL" ]; then URL="$STAINLESS_OPENAPI_SPEC_URL" else # Embedded OpenAPI spec (base64-encoded, gzipped) - EMBEDDED_SPEC="H4sIAAAAAAAAE+19X28jOZLne3+KvJ4Dqroh2fpjyXZhMYAt/21btsdSVXX3YtCgMmmJ5VRSw8y0StUzwOEOOBxw3+DeDvdw2IcDdg8H3GIXuJfZD9DzjS6CzEylJCaZcrm6XG5rd7psixlJMoIRvwgGg79zLnhEHR440Yg6IY+FS50bLuBXFr766ndOH/51piR0iEcmEfWcG8HHsjHdZ8Jz9q5OHY+7oeOzEL8GSlc8jMYkcEZU0FfOKIom4avNTWgUj2kQUbExpNFEtdlw+XjzjtHpZru91aw1Nnv1w4vprLX7Fb56/+DfwT+9CXXZDXOJ788q8s3pC1zu+9SNGLwTe+jy4I4K7ETEHfiaT2iA3QuBAPzu4bMBjONdLHs6mDkj+VeO46w69H0kiBs5goYTHoQ0dFgAhEJ3RMcklE1YcEMFvEcIKhv+KaZh5GxmjzjRbEJVU0HH/I7CP14ceCSInHT8BPv7FfaNTNgrp7lR26h9BYShF44TsciHOZtPbQO+dBwYVghPvXLqsnVIBf4FH6g6sfDnkwwkN+gAHt7gYrh519j8CiYYugbvlc1D6saCRbMeDorKPzn4njM6O6HEo0L9xZEDeeUAOfgm+ROD949ko+QPARlDm++rsrd7E9bntzTAl6gZU6T4AHsrB71Imw/ewSQmf5oImBARsbRL8n3e/Of0IeAIHWYdwA/I6phE8pv2Vvb3GybCSPZvhUQYCRYMsz/7pGRDlCLoX4d79rYw6RelaLqsVDufu6ea2VhtVYoasOQgsrYa8WmXBDM7D3yiIRbE44GWTzc+J9H82WB472dhGG+Ir5OSAec+JUG+5TVFLUNLNIZZlNJ6JRiIrWY2lx8I44GFObk1sCcEmS0tMvxTusYiOs4tgX8v6M0r58XvNuereDNZXZs5oi/kA/B39xa18OW9l9w6Ml5OiqBVCcmFVnvx+9Vm+anRTE/ByIrHl4xymWGGnhWMwvpEwUxan7th1PeWV7H1KRAMMevSaMS9td9I4vdrP3NH/LjME5lIrimH5fSdfeHhJ4bFcMDCiU9mpbQjaJ+eYt6a5qfZWH9t9FmJHrGQw5I+0CqjpaYwme9KzAk0izigpxJNvVhITXIiNPOxpKkBoV2iqp1wRGF2zekKKmmXmCs004cerH+v/MSWtA6ZkJaYDRiw0q5UNx3L4gECGsgBEr9eSqfCA2MWItTTL+Yis59vY7IZqW17kZ+qe6ld01t0hmjJRD2cGcxIqjekI/wkCqckoAQQH+v4trRafB4My7V0eYwKviT0lG3Lwc+cfK79QKnesPCER+AbadasBneVw8Il4GYZWDliVBDhjtCxtL444pN6rVZaYLWgRA9I4K83zKcn4In6Sya1wAAbDFrhM3qjVmzWigybpNSBVejTiHbSpffRRAWfXsTjj6WCE7MM01bmQ9ChlN8eOOLhmloCx64d83roQE4hLFI2iCNexo4YCH0UVBktrs0H1ZVll/M6uu0+9jR9oFHOlj6QcgE6VNq/EmhlzsU939cDwjWY+XCWNSGo7KoMKvXJex7w8WxNgSkb5SgdNVknEgOMGHKhCWMsNYxwbJciFwJbb/rxMwAlDjSxY/dDVaZpeWCqCVMemCrXT+BSqxsyZn65JZ82LScZqnXPIm9pEFTFTxein87f//GriAyT0KoKcHokIhhtkeRgtlzBJnmI+aI/olkjcMW96oSDXIQwiRRtkgxH39DIHeUDQaEC+1ESrlYRXxbMIXK44fQxgi7JRFOeijJIvsNv5u9Ju1HfcI5WX4KhfKJWzA1zU21bScwg8CtDzBsJnUYhnYASMZhlD4QYfJ7IWLvjQYdJ4FLsWat2O06JHRIglHUVhjxB3xAGMFFa2flTTMXMmRABUx2BU+VMAZCN0JPkU2fGYzl3zIevZOQfJwbfsdA3QaNYBNTbeJHjGigiL07UUp5pil3Jt3lujcktBTl3KAln+NYhjeQrMTSPix2nKxzxaYpYgVd3RDAeh9D9ITIlyG2LTOnACdncY69Lbjp9PnEASOJWRWb/8UHiDNkdDVCMaI4R+MhcIHISU/BIUz0y5iHuTrigzrWPp823Npw9+Ot4TIAHMKvRmq9rqdd5NCLMD+UWCzBOkllgEJAmc8ILbAL7szmkfJVNv68mL3nLopEkmTTNiRPKh0sCEBB8cyrcL0IUayXgL8KESkDZcDTgsQg3lt6emLmyPUia5yVnoRvYLmmTrj45cQmtpI/zHjrzhZU+ttTBKLG6S39Wj692u590NCGf66daJwsCDf+v2sG0TEg0kopvM1Vmmz+rL1FT/2VTCZQSaFgcGQhI1KX6VBfVpZOK1yvnWsnjgmAwlKvcQIo44DjHyWpMFYDQUHuptFGzBn2YgTgO+TfYFJELCDMFHmTk5IszZQi6K6IV9Tv8mleK0O0w9iPsquuDrw4z5s9kT3CRZfRWuyN5T1H9JXAF36mESPIlUcnzxTjXgfnZTPmdsiFvk2GGkGe5PynoVsojxM1LJqj3yolEnCe7IkzzacrB74XfGvkpg/ZepiEcuWn6Sqn5vBcphzUg7m2p3uu8wDEL2BicRqe++GfyXv25WVv4u0dvCDASmm+ZBqtwPIqNlCHsod58lxuhS6Kit12iIGlgQbq/jrvJauWj3c5s//24jVsEOCl/nwgjsM8n4ajisDC8gV8mMfw8mg0E8yqOx8fgvDC3ImFuRc6+GAoASH8sNei8RrX1dDkKtMCqG+KHhaJpnL+cKrX3N1naV4LfsVAK9Cfu+mmqS/L9VsBnRO5ACMG+zEDhDUBnwUJVO5elhgLSnyisT7auAL7UipbW0ldF/MLcktxKy09DqVGKUoNb9mG0XoxhxcBEnMoHVmci/XvhYHUIGuVSWah6bQ6iSw04nEzO4QG/UKJeo7bAWfVJMIwBjkrzk1oe8CDHoJiR1r31R8bkDMpkeTJzCi8atdqLV4UScJb7BhEwDaLFt5PJxGdqYjbfhXMXy9Rj/JTcJ5exkRdLT9P3BMOZq0SrC4EGUCncFby+0mwet3BOOLT0nI7gU02zNAzidLi4i5ErImDvNQ1VgM05397Z2WotrbWshSL1t//0y7/+8s9/+8+//KPzy3//23/85R//9h9++edf/uWX//fL//7lHytOZxQH3ocRcc5+rO75gPlmzsut5karWdutbO9ubLVa9W805NX2pdOoNWrVWr3aqDv19qtmS9MyTRJxdPOCwTQneV2zrWsQDF85ST8WIrm5jqhNvGWQkmuQZXas6NzcbC1kdBQRU/vJTq/dbNd327ur412SiAEfTYmOgZlA7HOQQQauwVvyfrq6jS5fmkrFPh8PZi7zfXAYQHXFfhw+FdnQ8v6JCweNAYEQk3AcxoKEKBx9QanTA/xv0RtXJARVBo5HEJHAKB31WqPZhP+YxGNvBN6G8wPgzDvmvA6YzDGMZqVYXtt9VWveVx00dndb9Ya2BbK8vbPRrLVbjYZOKD4Rz4sa5pnequ2uzueKjYgtTD+BFuswO8Xij5vd2jc/fXYPBY1YZIQEx5ji4vRZZOa1iDEA+Y4LA5d3d7ZqjS2tqkyZ3AMXbhaEpDxbdRaknOKu7+409SInFff2Rm2rBnL5qBT3dmN3x664xZgMjUzNNHeXDCdM+9KMtQBnnQn851Exdus3yFeXCBt+74BWxghWeQAPvsajYqyOLU+dseRDDFpYN7CMsXsfYkFtWrgzIwGeYQHGziz46nnFLo35U2nigV8OQu/7xL3FQL+Jwf1YeGhnKThXj0sfm/DTE+bukPsW7vIJBe4ec9+7YYE7Mi5fAtylPgtR06ufHhePtc76E2cy8NIdGZdwR8UmOyNyY2XxEUYlZYTE5dSng8/nE9Wc+s6rug5MPF2fqLXTaGxZ4x4eiaKRMMIsqayr0IoTTC7oj8D7MfI9UdwkEnwIqlsYV/ZnZ/yTi32UY7zg7oTpIpwZ36+5ewsO0ZDywMTtDvfj8YA4PrtjJjP9yRndtEQ9tkwa/cvk9PZua2d1zKtKfTzTsXBZqXdngY6BGaf3XME8HmGWWwhDBfD9eVe2jeFPb2WX4nck1a9RpScaOpxsmPhtbPWrcLm+i9sVGmWW4/L2k+PyVrOugbrLu1mCjAdGPL4vW1i2seYYDfcp2E3662Pm+NNb16U4Ph3xcGoE529HHNP5nd6UmE32bBhgQEz+Y+R0s7Hdrhu3LXNJf/nP4R2ZcHUU1ZnwwAudl/3OpRPSKWY7RBhmx+oaMDku80EynG8qTo/HkQ5YOk6fglR+KCc9tVc1nUooAfTbGw1wkhqrXlIiPK3mRhMcv90tHf3P5di1mtut+q5NdsZxZJGdbhzRsoLDfePOx5MUm+KI3hMWm/B2Bv6bJeijQno92fTWJD17Pok94hBxR4PQAh2foAQVm60nLEE+jwQ3g9FzHgyreCSBeuBzhrRM6HDCPeIiNmUDJizb7Y3mzlZza7WnOVlSbK5W32J9qLwEXSkJAocH/B0Xwx/EdWkYlki1AZGo7b5qmEWieAOovdGs61BQKhBbjdpOs/krhhhLwJhme7tt3YUfUCIoNUecoAlm5l1T6tkA7BUJYtyOHzAixl+uJGhZ/bQFgcYTWzpGZl2uaODFIAq0atkVvKZj9sGZJM2/VGkwmYonKg0BFyNiDkSf0MA5wT1/qoMkc/PAhBurXWH6LAAL3XjMAiBLad2Y+H8kW4D1KBG0mjDbxsPuzvZObVdrgFPuHwk+lJwuwdQdp976iGyPVgPnqYivmFcLCHD7Me0otmr1nbZ1R3FMfGCErt9zz1M2MaYC7AUEWApzNROjGaBD/rgYa9o7fKqMFSyYjHSE5vtHgNyqAXVvQTlejSgJSWBOqxxJWy8ztXws9PP5kmiR6bVXWv/z6cadt3Z32y2rQyc4vzVa6WtoYDTPKhvvRsRDcPmGj5vJ9SeXFlCOy5jtI8xO2jzdB9y5wO60j3wuMNtH/fuomf5b5bnr8btS7liHo8mmXvWA3xnRWC8SdBKBnPiMOB51CXcj/sz7R8h78Y64pXj/HXFvPVIm4XrMA+qZczef+f3Z+H1LdUp4ld9n6OJS3U7zfBOZ+C53IhYEceBaTkLWa61ae0efi5Ny/HWAZ58xGky8ivPLf/vbf/3l/8L//vVv/wVPRcJP/1Jx5BnIf/snmEf/3/4p/Ld/qjhnP6oTkY2dirO9A9xrlHHGd9AZb93TGce3bbdqDW0MQeJ77Ed9Z2vnMUXuQUQatRInIkU4IeXCc8kBuRGZmjeAXJdNGBaHClj4GYHftswK1O3oPWG90N7d2bXqBRdWOhHGwxkdjHnB4jy37PYdE58K5hGgidXGos9nBkqw++nB/FLshjUu+KAczL/mA2ZMDjgULBrJXTkRD6j7OQ0/cHzrlZYhj2yBF7S5F8N3aq0yUfahNniW8fuCC8zwxFMcYXl9PqRBxMxHOD4txxvIce0BkUfG8Qdc481aY6e9CiyWD7mT6Y124c73VWQLi/vOXZdHI0FideRu4ddnrj86ro/B5lrOdXShiU/Ln+e4Y/CXOy4+I3Arw+/HkeX/cIq9HL/BkvssKIfWz8FRo8ZQPLQgghEskxkQMPtmS/6l5Wo10OXb0onoU83VatZq9W3rlo7PI1tCRj5Xy5KJsUeHiAd9jic8Y49ETyzV+FmKks+y5aHTYWw8mNClU+c49o0hpXNZY8W1Fk56lpqkwRcuNYLSQWxEqZgM6OzH4GeYEwIPsU4l+0Cw+iCnAXNt8cinKELFIOhXlKGyGOiBREgWkzTuYSTnHK+4O7IlnMyi0Yw4NyBJz+BHjuapK6DpiMHEm6Tn7YhF1HlLhoh/TMLT5RFRlSGJP3iWHufpq56BjzWNSjlf+368TmkjgtVvzGmsz1KUNfjCdZCIB4J6xt2X6/iGx2EVC93LAxJeGBFhSauTKEgekqBihnU8Am5zxrbau/WasdxOVoa2mlWmTXZfd2Q92najWWb7VdajtZQ1NAR04HXb29pMvDS7EvrR1G39fC5JaLRrLU1y6rIrziJb/tU5izB8dyzowJwQTdzRbEAmkdyYuWEu982B+p0tENeWUZ30QOjYLb8jZZNoaxi4a96fzc1ac2u3MG6n+LzV2HlMjG5ubTftabTT0XTKzWUOJe6oYj1qWPFvOfcmmFNrPAJxQANPcJdPeOiA9YAfImqL27Ya7XbbmDW9d+sR7abeErdr8jBkU6ehS3B7C7i9267vag/cSm63N9qN1lZ953FVmd6uaZI8VirQzibm87THgsywwGwkmDc0rusrKjz23pnIf6ycrWvtZabMY1Em/l7bcerb966jtbXRaIPpLjy8gnyFadza/RW3W0rwtb2jKWe+Gn0P4pJH2S7iyBXEtoIvYpfdCDLEGLyYYbeJa95peywl5lFIPlLXf2EV5uutndaOVdPParXttk6pLRYb37xvnfl56fHNEiXnvyhpKT4c+3TFxR3Ft2ZT0SlqkSu4QN0oybovaLtoJfSJjKlAnPqsLEPNiF5rixIb0dzd3tluFXp3aCRarcajYijYiN1tq40Avgmqw8rL4Ulw6ibcvDuy55JA3h9045PxmJpjTL8iYw1FU58wZ8cU995NnO0WtVhKoXZVLUXBSmD1X4mlJqD+ZDnqcjGIzdkUHS6CtbajXPCdwCt7NGu1+LKIJ8zYEReWgkYnHO8mtmY3Hwo65pMRk0H+iawC8GiW7G9TC09HES2xgZNmrxySoW/0r09gqIRSDJsRf8Bca1XEZ6WcDfe+DDZeZbwZ8IgM0qv/7n+lcUIGB1P6auMX+guNK3pi9puN084uXmxcfMu741zoXoTXWA/U5ZH4hO/Lm6rTe37hN4G30af3SuaK9uGfZSXfKQupE4OvGBO/4tCN4YbD76jAcGOEm9/DpNeyoykhdfdpTuEFeEO1fDveGkrklINLivezgv+xkd7h+Hxn8hO8M1ldJ38/Ds3vOWZ4qWfFuYl9/4/6QakmRQNL7+hF2YMhRM5L1f4beT84XnP/EmnjrzdyIctyM7A276DzuLDKDfZLuyv5+YLh+eCeLxh+vmC4/AXDK3KRfVOtrX6VQxlHoGacg2WlmH7uiB9rLi/Gz8oW8GCk3SPAz/IusMwqOaFCe1WD7F7muOAtiBFJM0t0kBY/WY203VZbCyaTRgmyBgV7CwDZucbDHM7F2+tq9ZzBco5mTpeIcOS8vPhBFw3GT4Z/69sAfquNpjy1r4O4+DFiYNkpiYPrG42dZhMQeVErxMLV7S2sz9RoaQ98JH1LEHER2k1a2WGxfGvZ4x/4yaMPJRKve9WLH6q17aKh559QjLkUsP5LvKCee0GJ1skeFZ06P3Ctn4yfBFSllM2t0oP/DI8W9yKi3+vCTwzL94CFE58kD50BQPQBVDt74WisrV+ddF96G82d7Z1m3cRwbHa532s1tjF1RJtoJDs+ou4tugPYvnPeaDS1uzv4mYBqpIFLAcPbJGREQgwDo8YyN7xhIowWJ6BwQaQN98KIGKYI3n0NwL5LPUZML19WVETob9HFz1xREXFr2M3CT65WEA88KhPghuAxjIm+FJgcXOZ+79a1GV9JI0X4O7AFIZaXBWPcu0rLOmozWPCj1Uxazxw/JTVTbaO1vdOuFyq4RDM1oVlje1uTNJb1zeyrJ42sOZHynQ+ilzRlR1afSFQHCUMSP229BK1dMH90RsWIskAw7QnbZAiZbqq1tRVJ8bOom2r1dqF10+imInH7xLpJToJVMXU5ThIxTtJ9tdNvF0YV3XGIn2cY9QyjFtWVCz/h0gFdULRccnpqe3erqUvLwM+CnqrvtNvacsSy148GQ+HorWrKPDtlFFTqQtaNLmRPhq6enchnJ1L71vLa7xmpaz+/DaT+rAqegdD8syQN8cQPCwMBmTS8nmDOitOD/0zYpBgXpMKwj4nrZMwI9CwYMln3wSIQrfb27o62JEvSKi08MQVBOCe31Ln2Npzvnf1YDGkYyt/UXk55cdh5tfWRlqG50Wy3d1vaso6ylRKHnY1WrbVd2yoCNb+WOJj31X/OScZfPnZ3fWGPg9/kdo0tW+y5I4rpZrtYJVlxVvbWK+o1YLAw+xlsXPrGrzKC1m12J9klg5ZqH1FuZGMfxhwMj+pIRi7XIbWNI81UtjsMb1O9l6+RnQEJ9Tbm/fkdfHBHH/uY/RH3Zuc7NNAHFuL2C1P7+sRpV33QtLAK8Mtkr94Fv4RzubnTIQHJrbZjzkO6AY5FjI3mbwHOypPyQAteR2Uyw8Jb5YCw/8eHfYfuM+E5ffKeB3w8c2jgVSecBdFGrt9vRzQAdwJzBfCxb8W3atdqvt0v36O+y6TvW+f19XmuSa4sNAkcOp6AqlfbTunO7JPNHkj39LJF+BnGoBidF4Tn/IYvc8s/0WBXgmP6DUrfJ+56mnqx0G+VIjQidxRTpJwZKIAB7tGIxJCVm/vn9IX54J7TF57TF8qnL6wSXU5xl8hBAyTnGe4SUCggoWk3B/2CBNIBhObWi13rAIibxiTZExJg4VkzsF8F9Q3w9423hmvPmCk039jYarebLf1tnArJtze2Ws16TRue/FVLgT4KNrYbtR19wCNjY729C06bGwN6Pg8qDkZGJTdVcNx5CZO+Az5Upbrd2qjVGjvGs4LzqM6u7W744kvW1AsNPJYd2dYePP+0mdFz92xIeeKVfXSWMyViMNMZI5vXtZjivG5m8xzFR3Or4EwZqHPp/xGPxdIxVJRaNeeW+Vzh+oqyKsQZsjvACuA1zMnBEy7nwmMBbmqUc9gWHbVc+rP013J+qd5dU21NbgcI1hJWXzZ4xUZJAYaFL24wjRrhls/JYk2XDK7sLmqxDN1UF74oxP2pdcDgZq5uSjaeBSv5a4ynvlM0oMVv7CPabm7kKgf8tn0Wd2G6yzsasA4QeSl3n7lIhw65YPfHWWl+t1pr4BT7JBxVHBaGN/DLJIafR7OBYF4lO8BekXJTkbMvhqAw6B9LDdoDvfXxbK3p2doqYOtCOYsVtoaghGGiE6WXRVaUepvwkGFTHGlOCT57pQ/S9Wev9CO90pCLcuJVvOoBotBKamcLjnVgm6LR9KALiwwERBOlwUjwCOFX9Y680Ze7+uU4+eyIFvcYP58zj14yv5+aIoyBa1qXz4QA6zLUF9rCT+YtHSRGyBmivwQkNpyX2d+QiUW7jrm7irEaS/kHU59qd7e5Y90G60V0SmBervTHk/Gj3e/S3n6EH2PdJvnqzEOuN7e03pVslXrJ4N5vtR5wK/zT7H4Wes34Kes542ct7znpsyUQkrRaIxiCn/IBEfyYgyKyB9bAiGxlD44knXsUbJ9y7sW6CtH4mR8Th1bOQewWLbD5SmfvHamqbXvcyOzdpnVxH5AADFrV2Se+55zI9Advs8PHN6gJ4cdzRgfwrzOAJ8qv/vpuCTnQ3nMsO5fIQbPZru9qqhYlrTI52N2BNxeJyyeWAy3Rchl3B8oKK6OzPwNWRLrXljc3d3QRb+Q/maS9MTSap1iRaCQvQ7iJQxfMPg2sumVrp9nSXBmTtZpXMKEgZPMbeFSSjdPz+cTAnWU909CX78JPeeuytb1jSa0B4dpp7RpyTh+FigmnwC5rllVvSlgAOOxFWHz9En5WhSAOo9gvuEsl6fljlQFzRs0TkgEO3v2AWaHmpWymvYcAP/M7tCmTxZtJLKBLk4I6JEmXHyvzCxHEF8Z8Xaj+YROoNIH7hTyq5DFTFB/LHRQ+X5Fxel0aFYEng7k9yvJV7hu8X47ZZ5TXj93rkqwycgXJVtn3MttqIdson3b1ZwdXA/xzMJ9R58/576vZZ+GX6mKrnAzAbwU5NflH8klg6d/ukwOmalrJwIQqXpVRw0zuLAXswTK/FO3nbZEvc1vkOdnsMW/cPO9hPO9hPO9hPNwexpOI7/diFxz/8Cb2s2dzTT9rwF/BYYSsNIweHhJfKMLrgeEXRyzwpI5K+pXPQxlRQXNnEkYkVKsnVEsI++7P5ksoh9HSP90Hog2ICKdEytY+EQH6/77Pp/P0/JT4A2G0MgX3nkHax47nGaT9NkHaM2550rilWQhbmuVQiwqOPEns8gi9l1YZlixKoopnybnDLpPApWlZ0AkuEo96aB435ybl6WG2pRDmQ9VWVsFLXVVkLVRbzjn+yHLKD5NznFIrCl/+KqWYkVCCD+wVmTNiaWXmh6jI/AwQP3Y8z8nNzwWnP7Lg9HNA8BED6+cg2nMQ7SEAGYBOL3YBb8JiXyzR8bF4LCuwBuJNs53BVQzGAmXOZF2MYHkvFkQJlNyYRVhVLk8SNV2y9fpbvuThV9ADjWItsL4KmLNw4wtfTtlINN7NQqkbmAC8CdHd/Hn2l82fx/A/7/6L6yQhthSXRkCeO86wuspI5ucgPojIe6LizrbyNHOPJMP8N/B2dfQB3Ry5YLO/L/TKw6UI0gUrd6CSLL4WJLj9Old65WUiTCGiMh99ncXsi0Qh4Ou+0RexSf90nYoRCO4M3SGXAIc8qSjAfYNuxND8yWsKNYQXC0ci1ur7qoYo6Hz6rvHDvakEJmmU75j3a3ZsIcW6sGNlj01+znOOD3xo89md+kI9jOfQ/ZfmLaFx/cjFNAbUXXFcQWEhFywmbGJjoc6S3ySWfCaXlVpHAhoRz8vlDX4JxYqKw/7mYkWt32axokeC143ub8QnsEoXcfs6cD2hs4zW+3yCq1+HyjXVTyLVWk6JYIMYgH4C7VWAC1Fw4vgmMBFXUuIDf7Wcdayr8SiS7GcM/McTpOc59A4LJtZbKUReqa/IhZcE/xWIzzlzSbpI3jOvLLbJSKVCKb2OKZ4wI/5UxmSp84EKvoGlx8GeClCH0+LXzv2Rm0WS9p5p3zof698Nft+jeGs9PJQ6E86RrBskp/LvNge/z00NcPyG+fSEBJ5PcRVjahBWtpeJPTRAYCBTgZhI21bUWsWkHejsSD6Z0QP9IGSaOYucO0YcilstG1wMN+VPmwmNzZ8XXvyXXI9g9L1kRqrpMHGMajqzeZDnzOYeGPYGQOoG6O47PMQwn+C8Ftu7PkwBgeekG5gRjwAU5N/fSaa9M5/0tbqS0coDhS/NV3sc7pmmvzNKRLLnWN8BPSMzBWhyvUG02s1H59lpxgQGLhqlg6rWG6ujeHRuoGYUgIrSWlByQOVQLeI96u2X20Y0OY4TgHyFvtNkUghdUUOjel7Vu3m1+9L1v0kqZswbLujul/CSbx4Tki/E8euj+Lwxz6zNl4qhFEyybBw8BHDKDIjcOygR39TsIuREcL6FUBZOPQcKbX1fXVr3NjiPOMa4hsF5xAHJNQzOvaKXWLDpjH6sIQLE+ZMXJeEH6Cr8UmCUVEuzXYpy/k7iQsgVnwQiMu2QmKbse8DfU5JTGY/GLj3vw5Xdh0ttUxiRT2CbriU54jtInmE4vdwGXEIgFUANL+ZCV1kESCR3+9A9owPp4wXHSkpFBp6Noq3vz0bxt2QUv1SVKRINhrc0hosaE98WRuslAhXoyTQYdS5hvFRM14VX8CwlKeTP/oRSEeXSFVTfZJrffOtRhgvRk1QPygwHTED+Zj3VhxnQYDOXVGAN3g7c8cIsyVqGxSrJ9yg48gsiQCKT/j1ydbkXzLKBVJzXvaO3vWxi8/pyWZdmKhbGiyXWYcUnWSPufBCPeWEU7RLJidftFGmmOlsvmenexO3IzZ/lNaX3XjFvgMbc9S1cJhKqyq3zEJGB5ohq1i2z4T/gzsVlH6PWaUDX8fg08DnxlCw7ZIzsDlUCdUTUqVGMo2c0BtQZkABzfNiNM4NvPT7Xm6dBfsNcnisgixtkarvghuOZVAz2p3vrYs5/L1aMlmcX8FkuI0w4chnRH+ASHvM76AKWkXFu4igWCsy/cr5NygDtRT4lYfRtJSM7/wbTDb+twB+YR498YBX+Aix6d+rhT5KnyQ8Lt+1+m9HCvnybWPBvS617SfTBlvwqEMogJYwpiLAujXh4cya//ayYv/QVJIqdr5zD/dPrg5Vv09uFG7s7u8225mo9eDziLvex1ZXmykBzJVUvFnL8J2JlV1nOkO9fYnWoCXjRxdWhUq84KYG1U63Vq7Utp76lK4GFFwcfengV80LzXYCculss5pW1UrKN5qvGaolQaNdnY2qqdrVyr3KjsVqbE3yfS6kDqH5Gyt5rLf2lELNTujQacU+1lTz+iUzYzcoDK1dPw3Cccxp80A1VZwiW6q0NpzdF1VwzbfLK+fs/aluszjpwRzPr68yIfPOCyiuqfreg/iyNepGApVhfXm3qk+g9U1Uz8+pLxmdegfiZ3+69VWvXtrb1l3dqWaSvAvnMo3yTT8Qj3dSvFEV2CytkP/Mo3+QT8UhfRBHa7cXvdWoQP9VyL1vnhXIEZQUDPxIuKk0+EJR6AIt+chedqcUPReclbyxkdsVP6cOFz5H4fSIuF4VtVIlep4P2Dnzsm03ivSOqJM067jQ+OaSpUcmcg72EWOJElzvUrLw1dew39UuhAeDkcERkOZqBcpyTVH6GIcVcSEzjNMiY8kJETTnpSeTkdYCow8HQAiYjX4BH8yMleJezdBm79D1zufS13ViI9ITPRGGfz+Qxl4sjYvdXxv3woPrTXanwEZ4vH7yjbqT5GjTShIqI6S5bUAPwCqpWG/aD5p/sFDJo6U5f20hKxQO8ocPBi3XxHuflcRruNXRTE6LtXJDUui0ivEChu1dIoUvCEPxmAK/Rwv7SCo2L7wpp4EL8DhYUXeV9jsBVcSeuaBCEM/+OBGy1CHBKorNX/UOnkMQfYjqgq0Xwc+9/UzyNb6jAqGyqW5Nc9vVV62Ie/vxgVZIb76zeFf6EtNFjOcC/3kH99NxCua3Ym/HHHqVxw7uKg5q1YPsZvyoazFGy2yqvkOdJtYxO7w3y67ve5UVSvOFL33VNWKK5fiei76NNmMH1rNI8tJpf3ACDPmZNX6iSMEvHXsyIKW1cebDa04+r4Im+sElRJZTHX/CkoK5JYSmUL7PgyafUl5+4zscjK/TxbB2ejHXAnM/Nn2Xo/SGgn3MK9ApthCbBNEsjkXtuCXFLAVdwsPeuTh1X3pOAnvSUi1u1NZatWudU7aRNAPYvvkjVYZVb6RN1PUSuE/BX3CCXpziWHolGMonIOen3r5ytes15eQwc+8ahQnB5BETQKMb6/eWMFc74p4O7Bdk5j9+/Nq2IdFClN6zMO0qB/Uo+gBQsitGvMlyh5/NgmLQyXaGXeCBpwLToexWIW4gArTTN+zAXmWf6A9eMYI1doMwNyrWr1murMeB822QHCJh1yzQ3W7EwUQwFO10jRgVaKSy/vHpFYiUjXMlGWFFzJ5VYepeoOt5VSn2ljyzrr8VazEaUm91gGoeqKod81qizDnHHXoZN0xBfRgRXD94mlatqnWmoRLArSQHqjFxhIep56sHCO+SB1vRc3nLNwTjEnAFs/23y1bfK7OdOlcnIJpGHYbHmCX4R4VMyE2FRxVxmtRBlUkKsKqWofmDBzqSDVjX5Cco8FKX1pjDCUo7hsWAj+P6BoJF5JP7ysemPLj5b6uR1/sR12WuAFyX6YYVCHbQPs+Kf5fokb+RawLD3mz1VBcDM71xNoeS1aX50uvLujYXthl6C0YkPKuyecDT/yfzH36881eucHl70T49OOz9d7HUPK53LbvfyQv3cuzqEb3s/dS4P4Iu9/uHx5fUPlf7e99Dg8vrg8Bpby6aySa8CxPK/7u9dHJxeHCe/qSeO9rqn5z/8lD6Y/p4+Wbk+vLq87v+016scft8/vej0039/+uFw7/qrlf6fy/v/hj6JXc5wrycakRkVrHLqUtzZcY5j31956mVftnoRflOB9sPYr8iSNFvNrd2NWqV/cvx65ZHTzvHryvne8bn8utIZgXr1BGO49GlY+RrfA/a0TwWa1XxWfDbVtwyrzYZfV6DTzCO0MqvhhmOlUmJYt/HYZzSwjStt9k0FfoJx1dOBtRr2gT3woPLNftV9IRPYlZAmxSMvFhDPJo46XPOODhP4ya7pdo6Qshb9HEmPKSuQNFwK+WHZnwS+oOYcBixMT7nn1NBCrnB6fVxW/Iwm26p4dAj9NkkggwkhdWPBoll+UOAGntHZCQU8IXKpDcakwU9wK8Naly88fh/sIbJ78x/T3p+8yXs1uS39ZtXbSr9Z9eeq83vB07VCqgrEhA/gIfQxG16VknFQemw3OV7LcEC4tEqSTfoEXCXb/qgmJd7RlJ7J6MkGuXqBmJ7oRGwsF9DMmdL5qaONBFpRh7gunUTVFGBlxEZyyWC0Uy5kQYLQl8n6GRRT/ZG1JnJFuuYG4OKyfziPNWiGIuulq0rrg1gpC1knPU1PTipgZASVWpCPpVWqbhi4mOwDJiUD2XDEY9/DVGXpeMmJcEkcybNZCbMeRkfsqVk7X541pSfU3N1PU2QA5/6lgB7luv/suQ0LXsb881CJDYfBENaw/p5nXIiv1cJ7iFc1ao1mtV6rNnadeuOVrJO1GOxIMH74ECZ/hikBYVEqlEabLdZATbuy7G9U0ojBjU+GsGg8KY65sWcXHShNhj7OJ/RRvqQFAQptxFGHAWPM4qTZ45t/cuJU1+cUqlk3v0JXiFDzDk1oz2DzF0ZY1L+kd/qooYaG7vLplIY+F1RDRHc59XpE6hutByGyiojuQUR3affaRHSZx+sSqbV02afrU3kIIlu6nOb1qazG99em8tEUahtlxiKNRziZDAWPJ5nTeIy/gUZ+KMdR0iuXHZLiW9mhMLliMVKeOyA+0MX4x8g1RtS7VPiAICcxOJI+u6XJrToRh5EAyEwM0BHxXTRPAX0fIdg9IdNbxNB4jSRWmJNumjo4Fy6fgy13BG1xNh/Mo5wXE5XjrKgU6+WA8JLXqbKQYVaUdVXzKwF1tjVp80LNQU1JEbdpVipqPnRoOPGz8u6QfHkSFk7xWM7VSIeotnYDvMQqqKLIzZ2t3Bc5j2dO9xmByE/G5YdAs29hjsUNn66GALNXyVIz5nfpsmY0L9OfcZDrWr5kn8eBVzBq81yrT+GMlyWQr4yrP00l22RVcovbWLpSCiPipzgrbP4pxHLppwr/16gXnzDBFq1t/WGi9Pn6bltnU+dNGrW2DtDkKLRbWuM+b1Nvt1f275PBaeYy+aZa0w08M4FKQWtaqJMs2v5Uc2vMskIW1kiBgJcX8Y9j1UK3OyA4HLRopGI+e8EItAFZzQBYHUSRUK83iPvLy/LsR8BjOktiV/tYjkiTcrE6jHpdB9LvMZB7ie1cPOtG8ZS44SOk8w0Y6lggIkuwk2S277Nyc/Qw8tpsmVndrG3phWphKP2RiMNRqX4/jIg2tppal3LeprG1u1tCSDskkvC24nS5ewvrLPkNeQGjIjAqUWZYRfpzzWG1m1rXMjes9lZ7Z6OROh/qfEeSarjuUZOFUyRL9cMKsw2XCoNr8g4R78n5G1I+FGQiM5AQSGKWyx24BzKzJ7sdy1YXnCBXnC7xGIA70I1xEM0Wc5b2nJeL+YQqv6rWan7jENQ9GbFkYc+pY3/viGA8DtW6zbISku6hlBzJEa5m7sDrnZxaTpydV7nO/9l5g0Th34P5HMJvqhaf8+d8y6r8pP/KT/bXxZaquApM458TaI7F3dK/eQsvKpy2jNzrnp54wP8UA9uyV2ScTQqCLRz28ekd9eevm1NP37f4Dpm6tEBZ/kXb9QVWa1P3FkhjF1c7jn/BIiNqA2VlXlZJyNzXjIT8LZuAJCCblBWa01ogIujdKpvmlXGWGMXkjSF4/A0av+7JMWfE1NhXeqy+/NyHv8bkXXZ0t7LGUbC0DvlCpu49/OblVfqRMYGUO5WldaDu76lk4lXJpKSSZ3VBWtnNYp7GwiR2sF4i9/EI/lzE1PXbWAakbIFPj/psfN/BZx19UXFemLjtYnKIi9KmNgpBFyQpi9ShPh1jmkWamfCo3f4CD97sv6ttVL0FtzrumSddWq/NPwMDdLBEJOwxCek4f29zvS3ebhlfNzcH1e3Wxna7COSDk/64+sOCH37d/mw1NnZ2dfsusjvk/WPozsd69x0SEG/1qLbRf0pWYPGz5rWSiLpTrW/VN2q19k67qCaIFEGn2mpstOs78DFJhgPEtms7jQJ3I2GYs9PcqNdr7cYqW8u5m29IAOb1DgPwBymGWLF56afEHHYp2J05VeeAofZyo4qzL1iEEeAO90GMGKk4Hd25+7Jz3WhubDUbWwV+ZDbX9UZjYwum0bwMHczOrNXrO+bJhlat7S25YZj3k/LFQ/uwUP6y+TNYL7At1w/iOvXiQeo+nRdUSPx6ZcsmHlTTyifq6JQ6Ragpkpx2QbNnA7/JrAGXA8OCea3FBKSiUpAuWa4Wpgzty9NY2RmHuSujkp/xgMEy1F8Gc4t9T3sNaAbxbEZwlhyikEhapVTPXUDVPejti+TxFyo5Sh2feAF+lu+9kJ5cRi83jo2vS0NhZPmDQeFydUy/7s9dBUUoGyRgrfzMvsCpzf+l8SIb2nwgy+L6OYaTE80F0chwfcKyhe7/Vo+8Pq0NrAesl1NQ1eyh0soKju19NGpB2WeqntQFvVsbweSr4byptupFhcaS2jxESJ+fRfptr0VqYBfN1EYxngfUnBnQ0SoysAktX3eoU0enKEyr6BzweOgX7G0sUyoCa4rSoX+rr3S5TKZoRyAhE46pIH4BulyiVbjbk9CKBb0tR8g82yeAw7jv6aH6MinzhJ8DDCjwDJYJmef7nAFy9PUJbMuUzFN+PuOlyGjLac7JdFmAnCtFyTzdFzN9hb5lKuYJugIkMirSVMukzDPUi7jQVMbSEGqa5+gtCUe81OCa5il6OwIT41zBlN/Tnelkpf+SeNFbxAz3U6Z7R8a+7t0MRyQAvF2QbpmROTeT8Qfa4mJ5Egc/WkgMqbCQ2Fs9v75AAtQTQyjdI2NuoaSvwZlRCjwO4MFM4tJCYsh9C4VTG4UYLJKFxh8sNCIisIKdhcqxjQobxiTZqhaD2GIC9q7N5MQQK5sHFiJdC5ExtYnc3lsLiXhgIaCriJcjEI7GXCj3EfAIgB/hnIZ4/tBstfdWjxkukI0Bx4H3aembvqjiAhEbCcuS/EDFgLB3Ft2wb16V+2RExhYYs39iIyGINt0lR8K8ovdJAGAK3A/9aYqMyr6FCkyIxy2D0aP3jAb18fSqmcShjcSQxWMzCTNvgQT7YLZ2+7qSlHkKgY0l5hW8T8XYpkn2zUK+P4ptlmvfrKb3uc/uLMtkXx/im5MIQRFJJXBCxQc65Hc23bZvVkz7PAqnxEbjjYVGfEejRB2ZCZm19b4gH5gZOp5a5jgJmp4GHgPrfOlS+G+fCvgzF2botl9UszmlHAeUmSmYTdt+7A+JTU/um0HUfixugePOEQnNbta+2eADnRimyEjizKwpOwS8Ic8ynI55XQINKrjF7ygIe89pFO5CZBTM8tshE4rHxAoqgmdTasY/YJXZYIDydiEz9O22+cysvTtkNgZqZax8xyw1HazMQ3yA4Aq0XtNJPPDZapHdPM2+2cp1RsS81jtmHN8ZMd883x3zggQCFrXV+d5CQIA3AnihjObqXFkCMWyCITselCJmxnod7vLQeXlGwXAGw2/KSYBZL3a4j3sS5vk6syxWDgjUAkg6ZhXY4eCqmAmcWQjw23LzYUaKHY7roUdJOWJms9Xh4NQ61zbPp2NWyZ2//h/w5b0Xp3ecCfPKOLH0R3AS2RSz2S/o2NyVjhlWdGJB/vo/iYXXFv03m9jAa8eMPDsfqDsqp+0OzHJ3QIOxLdR6YAaxB+/YgMeR2eYemJfgAcdSqhY5OzCrgpRGSTPQMZuBg+sSi/rQrO8O3Rg8HXM09NCsWA6Hs4k5LtszY4BD0AbEv7P249gMAg7/FBNAmgyUy3HMAmrm1KF5HR8CahU2Emb37TAEk2RRBYdmx+cwGjE+sdA4Mi+fI+LfylpJibZ1XnZhssF+h9+YyZpF+YgITktp8CPz2jxi78zr8sisu49YYDX6R2ZmHwkSuGa1f2xGeUeCBqDuQO5s/txVKUJX3J8FNLRwvl+KVg80H2DiIDlKk0QK5TaImXHHZvB/TAYW7+HYrFGPiRUWHZuX2DHlYmgLSNtICED6Zvf02OyNHY9sTD82i/AxGwAkAsaYiZiF+FhQahNis1uAFOxr6dhslICI1Sc8NgP6YzBJ1OfxxDIaM4wCKubQ2bFZ98LzER0TS2D+2Gwbj2M8em7ZuDo2O1sljNmxGREqCtV9FoYkNhMyw8LjeGYT9RPzrJ4QZoFhJ2alcUKJSG2Z1Ghd9wCTb7xStuh7s1t6woYj9EzMRE7M/DrhAd4naqFhNtpAY+icccvW6Yl5BZzEwZBYIm+nZl8tqbNoJmGeDhkONBMwaxQgwO228NSsHU+FJYB8agaX8PyfzM+bzcypKDGRZskH+ZY5gl3bSMxa/jQUhFoCveY1fBoR3yxV35lH8h0ZE5sn9Z3ZRnxHJpZp+M7MkIKrthYomBHwd1x4lj6cmX3kM/KB3I6su/Jn5pGc0WBmCS6Z4ccZE2xALGr5e7PCOuMhvzN7omdmI3UWT8E2mCmYje3ZTAxnH6zTeW6GtefEEmc7N3uz5ySy7TSdm7cfz+mABBZofW7W2+c05NHIzI9zs8Y8ZwNrpsa5GS4ACYtknpsl85xRdxTRIIyoZRPy3Kyyzlk0iq25K+dme3oev6fjAY+F2Sp3zWqjS1wLCOualxoQoJ41stA1r5UuYPQhCV2Lz9E1r9kuwOOpWW90zSKCFGY22941rzig4bG7grP3GQ2zVQQalnGYBayL/puZgNmJ7BIRjvC8QRkY2zWDlS4mqQTsT5rqdgtUzAqgS7DcqXXRdM2LRlFhlmDyD7bZnfEosozGDO3VvbZGCkdm1NJlrigBRLtmNNvlvsfvLCTMMdsu+DuWoXTNmLyLYWNb5lHXDDu6MpOfDoWlJ2ZDhVRCKkTBIbyMitlmd7ngrm1KzFisyz9gOMq6ZiwyAv7x2KJTL8xjuSBjZguLXZhX7gWsObOJuTCj6ws6saQRX5jVadlt+AuzpOMRhg7xS5i7CzN3c7dcm8mY8cgFeC2CDGNLX8wL54IVVRvLCJhttyRgmw+zVr5gFjm/MIeWL7i44f5tmQ33rkXUuFDR6S7m5wTlNoXPStAEl8S2gfPi4nL5uq8VQtOCemspjUuzQrgcW7yRKzPYuyK39rTtKzNKuwK5N6uDK7OSvsIq94goSid0aa+pzhOEfy37JOY1cEUmMZHLukR49MqMQa/UmraMyLyor6hF416Z4d/ViGEaCwzFLPlXZsN+xSKXMFEuc+nKrMOvuHVtX5lh2xWsw3hosSRXZlt2FWNqD2Z4mM37H8wS9wdi2165NjP4+q//EAfM4pVfm12/az62wulrs+K+jkMbAL02a4PrKXDVkghpFoweYUGESdLR6K//4NOxeeH0zIKviJ1Qnwak4uyFLnj7spKOrD8mpPJzPOJ04mBkiXKZl4Z60RmLkqKCF/SOWQI9ZnCiCJ7Hrg1Hm02pIqNcNudlsmc7gV/N2/NXZrujqF4x0Nbq4EIXoa1vkd83ZUb8hgXApEhSxWNLasfPqrnemm2M/TBPzzZihSECs57omVVW76//g+PFkH/9Bzm+K/HX/xW4zLIT2TPrnh6JPebsCWKD9T2LBKO7ZdGm15ZZpsLaCYsM0Jk7or5v4XbPokJQMIlzTrnm+NwCHTMM6GFd0Am35Oz1zKGBnlqAsOQKLvrI6JixWs8Hx/7WNr1mDwNpWA889czx4x4mnPJyGKBntlg9sFi2OMGPFunH9JMk/dlI59giupJOkvEhF6f6C6x7b4olyUs5DmawoSjaHYdema72Ytv20KGFzMR2GurcIpCCYZqP5QB2zxywsg+jZ5nUGJQy/GSmYU4S690Rf0C0xWZzNMwxgN4UT7jYIG3PDAN7U+pZtETHAnimLPqgYiPmjpidlt7MFgLom3Fgn7CphbF9M1P65B0r4Z32zWzpk+CDFRX3zXPaHxE7Z/tmk9RnYy6q5+DomiW1b7ZIfW5JyO2b12yf31Kbu943K+0+B6NoJmAGQQC7A+YRlV/T5wNiG5IZt/TBcbKmMpp1SD8Wt5bd+r4ZHiIFPEpsF1cz/kE6YXIUmOFZkTJmp2/ewOrHeMTfSOG1WepeD61O3WuzmX59i2dvzaK/Z9aNSRFHBLrO4ZiJglqOOYtvxjEJvTPAeB435/JprrzXUCosL5kjZJaiBUJYb4ML5zKO/BnW6SojCa/NWv21iK2RqNdmffr6w4CW0MpvzHGGNySISWSWyTdmiXpDInnUAWv3OC9PuD8D54Gavdo3Zgl7Ax7QB3BjzZL+xqyO3jAaBZbc0Dfm5faGAQgN5hn1ydFXy9jMyH+Z5uuN3oaZ4FtzYOEt8X2mVNVRHMWWvM1Ds4V9i3ZRYM0NLIBrpPSDmYc/YJFcs0NhXoM/2tPGfzRDnx/ZeEAG0+LCLQ1j4ZZk9QOztGqnXO0ra6kVMrCFyJGKGUwAldBefslWH0KwD9wiPUjFVg3klgShvc6V9cSxj/dy2/AiErKfyhTEsxbM6pihUocHAcXzFLG1NJXlIMIBqLUpsUQykIwZn6RFTDFTNC1faiN5ZJbFI5gpZi8HZjsuUuKsBlA5MWvJE5gjZs7UASK2jGKPWHLjkIYljRaUa8AtEWQkUyI72r64Ts1ze8qnVhJnZoh0Vmp1Wo7Nn9Egit1ba50uWwomj9FhsE+LLUXFimiRhiVfB1S+1bVEMpYMFRKGxB3FIY0i6yx3zWugy9wRG1rwHZKxJAExUF0ht6StIR1LCg8LQ/z/ycS6Lm2pkUCGx8JOxpItxoOohPDY0jToQJSxnhdm366wROYiETP6wn3uE4Am4ch2PB1pmaM2SKtE8jsSMuMwJFQiq6640GmekKZQ6SoZS7KQzProEMF9W3UKJGZe9orYAbktsT4uzcy7HDHrDF2acdzlrQ8Wyw4HL80Y7FLQob3QpC13gwZBOPPvrDE7IHVtVmTXI2hYJocISNm2pWTIvSzzbSFvSawc822xL4pKNqTWVds371H1wTWx2o3XZr34OiLmsmhA4o2ZxBsqxqBdrVQskQHp6trF562ZDJbyZMEwsov0W7OORue2fKfMMv2WhXgrsGXjBumYleLbGdaKWD1pkLqozTWKNJtyH0t4qxc/gld2US2+IjPx8MLRIJZleFIfxEZ17/WZtajxHuBJedbTWgIaCL7td6o17SXpc4L7se/nLnuwkjyGkRfeoZg6pSKia4385Gy/WmsW3QeRUE0qR+HdiPRF6OyTWWn6l/094Jel1wn9y4gMeWnKShIsRbtldSdXFtsuxTfZ3W3LdPiglMl6M7BtrgV8EAfUYyWqiwO9i/65tbz4EREpcFhnBVhKoGN1ilu8j7y0yJ5dPjzR49NetdYougYmcfFZOOAioKWJ9nBSt4uuO0mIYunV0kOXCqDo3qCEoKDlF5KaSzNBQObMj8pUqc9Wvpk5JwSzbYfhmr00r58TEgtyy0rT7L7tV4uuPs1ocsHxopK4/LqU+qPwytWELFZIjMt3VYmRWe2fBndUuARsvO+XYpTqqFk2zwi7BYe1/OiVFjHbUSCKF7msaaFsNCcsYgALQLJKE96/vIIlb5b9MzKlgsRrdtZM85wDTRCCKCrPqLaZ+13i3tLgAyuvSaT4N80WtEsCMiVR+dErwGMWfiAa38KMlhl6d/8EL3m1BbB80Mo8HpY3S4pLtn6Ga4IepaVsjIrIGP5XvWLgfq2Jp8zW+QLWAMhVKWPfw7Vv1n0X1C91MwmQ65+dWq8TQJR+5c/GyvVcS57MM6oASW+EZrRMZ9WqN4PyywmP2Bq2RHHeLE+XEQjpiATD8ppPmSizLb0i/pgKLMWWBohKzIGaV/PivyITcruO7leLymxQrrhgAqxpedBsHv0fYoqn5/k0qJ6TW1oeUagFZebYNTALrMotXRNUPDxZxS/z1F5zL1gX+DVsJEFm18A+amk9LE01o2aDeh2TCR2VN1PKoprVX4/601l53a9UoFlTqbBbH7BPsA5QVcrFcn2MJP0W4BqJylsVuWJb5hWWURbQ70l5vinMarYJkrYMfqwnDWYJ64HXH91wUZ6qYt5DU1X60GyzURjWXg0PTLO/B55vy0YzxHrh6ykXG8l4siYAelCKcioflKJSfw9P0byI+uj3IqooFUCUusTSxRH8E1Y7AFfGeJWYv6ZeNa+jPhuDdK65iMx69TWWRy/vT6k5sFx+taYmVc60WUcDzTG5JQCAyut+NaNm6yfpRmvEkOT4zQD4Lfroay5O6+gFL09SIR7rwCMAfSVxvwoZm6GZorguex6WptKdZqOMNPl4XV33CWg2bWIEimmdSJda7haiFFOThmUDkkqHmsFemv2JWxD8BvxUGkRrQGkZlLV1OozWQjqq22bF93YE+iQiawSkVXzOMhnSSRV59+T/A0tFAKV76wEA" + EMBEDDED_SPEC="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" SPEC_TMPFILE="$(mktemp)" trap 'rm -f "$SPEC_TMPFILE"' EXIT echo "$EMBEDDED_SPEC" | base64 --decode | gunzip > "$SPEC_TMPFILE" diff --git a/scripts/test b/scripts/test index 19acc91..a47c5b4 100755 --- a/scripts/test +++ b/scripts/test @@ -54,8 +54,31 @@ fi export DEFER_PYDANTIC_BUILD=false -echo "==> Running tests" -rye run pytest "$@" +# Note that we need to specify the patch version here so that uv +# won't use unstable (alpha, beta, rc) releases for the tests +PY_VERSION_MIN=">=3.9.0" +PY_VERSION_MAX=">=3.14.0" -echo "==> Running Pydantic v1 tests" -rye run nox -s test-pydantic-v1 -- "$@" +function run_tests() { + echo "==> Running tests with Pydantic v2" + uv run --isolated --all-extras pytest "$@" + + # Skip Pydantic v1 tests on latest Python (not supported) + if [[ "$UV_PYTHON" != "$PY_VERSION_MAX" ]]; then + echo "==> Running tests with Pydantic v1" + uv run --isolated --all-extras --group=pydantic-v1 pytest "$@" + fi +} + +# If UV_PYTHON is already set in the environment, just run the command once +if [[ -n "$UV_PYTHON" ]]; then + run_tests "$@" +else + # If UV_PYTHON is not set, run the command for min and max versions + + echo "==> Running tests for Python $PY_VERSION_MIN" + UV_PYTHON="$PY_VERSION_MIN" run_tests "$@" + + echo "==> Running tests for Python $PY_VERSION_MAX" + UV_PYTHON="$PY_VERSION_MAX" run_tests "$@" +fi diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..4959858 --- /dev/null +++ b/uv.lock @@ -0,0 +1,1829 @@ +version = 1 +revision = 3 +requires-python = ">=3.9" +resolution-markers = [ + "python_full_version >= '3.14' and extra != 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2'", + "python_full_version >= '3.10' and python_full_version < '3.14' and extra != 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2'", + "python_full_version < '3.10' and extra != 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2'", + "python_full_version >= '3.10' and extra == 'group-11-phoebe-bird-pydantic-v1' and extra != 'group-11-phoebe-bird-pydantic-v2'", + "python_full_version < '3.10' and extra == 'group-11-phoebe-bird-pydantic-v1' and extra != 'group-11-phoebe-bird-pydantic-v2'", + "python_full_version >= '3.10' and extra != 'group-11-phoebe-bird-pydantic-v1' and extra != 'group-11-phoebe-bird-pydantic-v2'", + "python_full_version < '3.10' and extra != 'group-11-phoebe-bird-pydantic-v1' and extra != 'group-11-phoebe-bird-pydantic-v2'", +] +conflicts = [[ + { package = "phoebe-bird", group = "pydantic-v1" }, + { package = "phoebe-bird", group = "pydantic-v2" }, +]] + +[[package]] +name = "aiohappyeyeballs" +version = "2.6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/26/30/f84a107a9c4331c14b2b586036f40965c128aa4fee4dda5d3d51cb14ad54/aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", size = 22760, upload-time = "2025-03-12T01:42:48.764Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8", size = 15265, upload-time = "2025-03-12T01:42:47.083Z" }, +] + +[[package]] +name = "aiohttp" +version = "3.13.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohappyeyeballs" }, + { name = "aiosignal" }, + { name = "async-timeout", marker = "python_full_version < '3.11' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, + { name = "attrs" }, + { name = "frozenlist" }, + { name = "multidict" }, + { name = "propcache" }, + { name = "yarl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/42/32cf8e7704ceb4481406eb87161349abb46a57fee3f008ba9cb610968646/aiohttp-3.13.3.tar.gz", hash = "sha256:a949eee43d3782f2daae4f4a2819b2cb9b0c5d3b7f7a927067cc84dafdbb9f88", size = 7844556, upload-time = "2026-01-03T17:33:05.204Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/d6/5aec9313ee6ea9c7cde8b891b69f4ff4001416867104580670a31daeba5b/aiohttp-3.13.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d5a372fd5afd301b3a89582817fdcdb6c34124787c70dbcc616f259013e7eef7", size = 738950, upload-time = "2026-01-03T17:29:13.002Z" }, + { url = "https://files.pythonhosted.org/packages/68/03/8fa90a7e6d11ff20a18837a8e2b5dd23db01aabc475aa9271c8ad33299f5/aiohttp-3.13.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:147e422fd1223005c22b4fe080f5d93ced44460f5f9c105406b753612b587821", size = 496099, upload-time = "2026-01-03T17:29:15.268Z" }, + { url = "https://files.pythonhosted.org/packages/d2/23/b81f744d402510a8366b74eb420fc0cc1170d0c43daca12d10814df85f10/aiohttp-3.13.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:859bd3f2156e81dd01432f5849fc73e2243d4a487c4fd26609b1299534ee1845", size = 491072, upload-time = "2026-01-03T17:29:16.922Z" }, + { url = "https://files.pythonhosted.org/packages/d5/e1/56d1d1c0dd334cd203dd97706ce004c1aa24b34a813b0b8daf3383039706/aiohttp-3.13.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dca68018bf48c251ba17c72ed479f4dafe9dbd5a73707ad8d28a38d11f3d42af", size = 1671588, upload-time = "2026-01-03T17:29:18.539Z" }, + { url = "https://files.pythonhosted.org/packages/5f/34/8d7f962604f4bc2b4e39eb1220dac7d4e4cba91fb9ba0474b4ecd67db165/aiohttp-3.13.3-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:fee0c6bc7db1de362252affec009707a17478a00ec69f797d23ca256e36d5940", size = 1640334, upload-time = "2026-01-03T17:29:21.028Z" }, + { url = "https://files.pythonhosted.org/packages/94/1d/fcccf2c668d87337ddeef9881537baee13c58d8f01f12ba8a24215f2b804/aiohttp-3.13.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c048058117fd649334d81b4b526e94bde3ccaddb20463a815ced6ecbb7d11160", size = 1722656, upload-time = "2026-01-03T17:29:22.531Z" }, + { url = "https://files.pythonhosted.org/packages/aa/98/c6f3b081c4c606bc1e5f2ec102e87d6411c73a9ef3616fea6f2d5c98c062/aiohttp-3.13.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:215a685b6fbbfcf71dfe96e3eba7a6f58f10da1dfdf4889c7dd856abe430dca7", size = 1817625, upload-time = "2026-01-03T17:29:24.276Z" }, + { url = "https://files.pythonhosted.org/packages/2c/c0/cfcc3d2e11b477f86e1af2863f3858c8850d751ce8dc39c4058a072c9e54/aiohttp-3.13.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de2c184bb1fe2cbd2cefba613e9db29a5ab559323f994b6737e370d3da0ac455", size = 1672604, upload-time = "2026-01-03T17:29:26.099Z" }, + { url = "https://files.pythonhosted.org/packages/1e/77/6b4ffcbcac4c6a5d041343a756f34a6dd26174ae07f977a64fe028dda5b0/aiohttp-3.13.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:75ca857eba4e20ce9f546cd59c7007b33906a4cd48f2ff6ccf1ccfc3b646f279", size = 1554370, upload-time = "2026-01-03T17:29:28.121Z" }, + { url = "https://files.pythonhosted.org/packages/f2/f0/e3ddfa93f17d689dbe014ba048f18e0c9f9b456033b70e94349a2e9048be/aiohttp-3.13.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:81e97251d9298386c2b7dbeb490d3d1badbdc69107fb8c9299dd04eb39bddc0e", size = 1642023, upload-time = "2026-01-03T17:29:30.002Z" }, + { url = "https://files.pythonhosted.org/packages/eb/45/c14019c9ec60a8e243d06d601b33dcc4fd92379424bde3021725859d7f99/aiohttp-3.13.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c0e2d366af265797506f0283487223146af57815b388623f0357ef7eac9b209d", size = 1649680, upload-time = "2026-01-03T17:29:31.782Z" }, + { url = "https://files.pythonhosted.org/packages/9c/fd/09c9451dae5aa5c5ed756df95ff9ef549d45d4be663bafd1e4954fd836f0/aiohttp-3.13.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4e239d501f73d6db1522599e14b9b321a7e3b1de66ce33d53a765d975e9f4808", size = 1692407, upload-time = "2026-01-03T17:29:33.392Z" }, + { url = "https://files.pythonhosted.org/packages/a6/81/938bc2ec33c10efd6637ccb3d22f9f3160d08e8f3aa2587a2c2d5ab578eb/aiohttp-3.13.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:0db318f7a6f065d84cb1e02662c526294450b314a02bd9e2a8e67f0d8564ce40", size = 1543047, upload-time = "2026-01-03T17:29:34.855Z" }, + { url = "https://files.pythonhosted.org/packages/f7/23/80488ee21c8d567c83045e412e1d9b7077d27171591a4eb7822586e8c06a/aiohttp-3.13.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:bfc1cc2fe31a6026a8a88e4ecfb98d7f6b1fec150cfd708adbfd1d2f42257c29", size = 1715264, upload-time = "2026-01-03T17:29:36.389Z" }, + { url = "https://files.pythonhosted.org/packages/e2/83/259a8da6683182768200b368120ab3deff5370bed93880fb9a3a86299f34/aiohttp-3.13.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:af71fff7bac6bb7508956696dce8f6eec2bbb045eceb40343944b1ae62b5ef11", size = 1657275, upload-time = "2026-01-03T17:29:38.162Z" }, + { url = "https://files.pythonhosted.org/packages/3f/4f/2c41f800a0b560785c10fb316216ac058c105f9be50bdc6a285de88db625/aiohttp-3.13.3-cp310-cp310-win32.whl", hash = "sha256:37da61e244d1749798c151421602884db5270faf479cf0ef03af0ff68954c9dd", size = 434053, upload-time = "2026-01-03T17:29:40.074Z" }, + { url = "https://files.pythonhosted.org/packages/80/df/29cd63c7ecfdb65ccc12f7d808cac4fa2a19544660c06c61a4a48462de0c/aiohttp-3.13.3-cp310-cp310-win_amd64.whl", hash = "sha256:7e63f210bc1b57ef699035f2b4b6d9ce096b5914414a49b0997c839b2bd2223c", size = 456687, upload-time = "2026-01-03T17:29:41.819Z" }, + { url = "https://files.pythonhosted.org/packages/f1/4c/a164164834f03924d9a29dc3acd9e7ee58f95857e0b467f6d04298594ebb/aiohttp-3.13.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5b6073099fb654e0a068ae678b10feff95c5cae95bbfcbfa7af669d361a8aa6b", size = 746051, upload-time = "2026-01-03T17:29:43.287Z" }, + { url = "https://files.pythonhosted.org/packages/82/71/d5c31390d18d4f58115037c432b7e0348c60f6f53b727cad33172144a112/aiohttp-3.13.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cb93e166e6c28716c8c6aeb5f99dfb6d5ccf482d29fe9bf9a794110e6d0ab64", size = 499234, upload-time = "2026-01-03T17:29:44.822Z" }, + { url = "https://files.pythonhosted.org/packages/0e/c9/741f8ac91e14b1d2e7100690425a5b2b919a87a5075406582991fb7de920/aiohttp-3.13.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:28e027cf2f6b641693a09f631759b4d9ce9165099d2b5d92af9bd4e197690eea", size = 494979, upload-time = "2026-01-03T17:29:46.405Z" }, + { url = "https://files.pythonhosted.org/packages/75/b5/31d4d2e802dfd59f74ed47eba48869c1c21552c586d5e81a9d0d5c2ad640/aiohttp-3.13.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3b61b7169ababd7802f9568ed96142616a9118dd2be0d1866e920e77ec8fa92a", size = 1748297, upload-time = "2026-01-03T17:29:48.083Z" }, + { url = "https://files.pythonhosted.org/packages/1a/3e/eefad0ad42959f226bb79664826883f2687d602a9ae2941a18e0484a74d3/aiohttp-3.13.3-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:80dd4c21b0f6237676449c6baaa1039abae86b91636b6c91a7f8e61c87f89540", size = 1707172, upload-time = "2026-01-03T17:29:49.648Z" }, + { url = "https://files.pythonhosted.org/packages/c5/3a/54a64299fac2891c346cdcf2aa6803f994a2e4beeaf2e5a09dcc54acc842/aiohttp-3.13.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:65d2ccb7eabee90ce0503c17716fc77226be026dcc3e65cce859a30db715025b", size = 1805405, upload-time = "2026-01-03T17:29:51.244Z" }, + { url = "https://files.pythonhosted.org/packages/6c/70/ddc1b7169cf64075e864f64595a14b147a895a868394a48f6a8031979038/aiohttp-3.13.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5b179331a481cb5529fca8b432d8d3c7001cb217513c94cd72d668d1248688a3", size = 1899449, upload-time = "2026-01-03T17:29:53.938Z" }, + { url = "https://files.pythonhosted.org/packages/a1/7e/6815aab7d3a56610891c76ef79095677b8b5be6646aaf00f69b221765021/aiohttp-3.13.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d4c940f02f49483b18b079d1c27ab948721852b281f8b015c058100e9421dd1", size = 1748444, upload-time = "2026-01-03T17:29:55.484Z" }, + { url = "https://files.pythonhosted.org/packages/6b/f2/073b145c4100da5511f457dc0f7558e99b2987cf72600d42b559db856fbc/aiohttp-3.13.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f9444f105664c4ce47a2a7171a2418bce5b7bae45fb610f4e2c36045d85911d3", size = 1606038, upload-time = "2026-01-03T17:29:57.179Z" }, + { url = "https://files.pythonhosted.org/packages/0a/c1/778d011920cae03ae01424ec202c513dc69243cf2db303965615b81deeea/aiohttp-3.13.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:694976222c711d1d00ba131904beb60534f93966562f64440d0c9d41b8cdb440", size = 1724156, upload-time = "2026-01-03T17:29:58.914Z" }, + { url = "https://files.pythonhosted.org/packages/0e/cb/3419eabf4ec1e9ec6f242c32b689248365a1cf621891f6f0386632525494/aiohttp-3.13.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:f33ed1a2bf1997a36661874b017f5c4b760f41266341af36febaf271d179f6d7", size = 1722340, upload-time = "2026-01-03T17:30:01.962Z" }, + { url = "https://files.pythonhosted.org/packages/7a/e5/76cf77bdbc435bf233c1f114edad39ed4177ccbfab7c329482b179cff4f4/aiohttp-3.13.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e636b3c5f61da31a92bf0d91da83e58fdfa96f178ba682f11d24f31944cdd28c", size = 1783041, upload-time = "2026-01-03T17:30:03.609Z" }, + { url = "https://files.pythonhosted.org/packages/9d/d4/dd1ca234c794fd29c057ce8c0566b8ef7fd6a51069de5f06fa84b9a1971c/aiohttp-3.13.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:5d2d94f1f5fcbe40838ac51a6ab5704a6f9ea42e72ceda48de5e6b898521da51", size = 1596024, upload-time = "2026-01-03T17:30:05.132Z" }, + { url = "https://files.pythonhosted.org/packages/55/58/4345b5f26661a6180afa686c473620c30a66afdf120ed3dd545bbc809e85/aiohttp-3.13.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2be0e9ccf23e8a94f6f0650ce06042cefc6ac703d0d7ab6c7a917289f2539ad4", size = 1804590, upload-time = "2026-01-03T17:30:07.135Z" }, + { url = "https://files.pythonhosted.org/packages/7b/06/05950619af6c2df7e0a431d889ba2813c9f0129cec76f663e547a5ad56f2/aiohttp-3.13.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9af5e68ee47d6534d36791bbe9b646d2a7c7deb6fc24d7943628edfbb3581f29", size = 1740355, upload-time = "2026-01-03T17:30:09.083Z" }, + { url = "https://files.pythonhosted.org/packages/3e/80/958f16de79ba0422d7c1e284b2abd0c84bc03394fbe631d0a39ffa10e1eb/aiohttp-3.13.3-cp311-cp311-win32.whl", hash = "sha256:a2212ad43c0833a873d0fb3c63fa1bacedd4cf6af2fee62bf4b739ceec3ab239", size = 433701, upload-time = "2026-01-03T17:30:10.869Z" }, + { url = "https://files.pythonhosted.org/packages/dc/f2/27cdf04c9851712d6c1b99df6821a6623c3c9e55956d4b1e318c337b5a48/aiohttp-3.13.3-cp311-cp311-win_amd64.whl", hash = "sha256:642f752c3eb117b105acbd87e2c143de710987e09860d674e068c4c2c441034f", size = 457678, upload-time = "2026-01-03T17:30:12.719Z" }, + { url = "https://files.pythonhosted.org/packages/a0/be/4fc11f202955a69e0db803a12a062b8379c970c7c84f4882b6da17337cc1/aiohttp-3.13.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:b903a4dfee7d347e2d87697d0713be59e0b87925be030c9178c5faa58ea58d5c", size = 739732, upload-time = "2026-01-03T17:30:14.23Z" }, + { url = "https://files.pythonhosted.org/packages/97/2c/621d5b851f94fa0bb7430d6089b3aa970a9d9b75196bc93bb624b0db237a/aiohttp-3.13.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a45530014d7a1e09f4a55f4f43097ba0fd155089372e105e4bff4ca76cb1b168", size = 494293, upload-time = "2026-01-03T17:30:15.96Z" }, + { url = "https://files.pythonhosted.org/packages/5d/43/4be01406b78e1be8320bb8316dc9c42dbab553d281c40364e0f862d5661c/aiohttp-3.13.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:27234ef6d85c914f9efeb77ff616dbf4ad2380be0cda40b4db086ffc7ddd1b7d", size = 493533, upload-time = "2026-01-03T17:30:17.431Z" }, + { url = "https://files.pythonhosted.org/packages/8d/a8/5a35dc56a06a2c90d4742cbf35294396907027f80eea696637945a106f25/aiohttp-3.13.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d32764c6c9aafb7fb55366a224756387cd50bfa720f32b88e0e6fa45b27dcf29", size = 1737839, upload-time = "2026-01-03T17:30:19.422Z" }, + { url = "https://files.pythonhosted.org/packages/bf/62/4b9eeb331da56530bf2e198a297e5303e1c1ebdceeb00fe9b568a65c5a0c/aiohttp-3.13.3-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b1a6102b4d3ebc07dad44fbf07b45bb600300f15b552ddf1851b5390202ea2e3", size = 1703932, upload-time = "2026-01-03T17:30:21.756Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f6/af16887b5d419e6a367095994c0b1332d154f647e7dc2bd50e61876e8e3d/aiohttp-3.13.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c014c7ea7fb775dd015b2d3137378b7be0249a448a1612268b5a90c2d81de04d", size = 1771906, upload-time = "2026-01-03T17:30:23.932Z" }, + { url = "https://files.pythonhosted.org/packages/ce/83/397c634b1bcc24292fa1e0c7822800f9f6569e32934bdeef09dae7992dfb/aiohttp-3.13.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2b8d8ddba8f95ba17582226f80e2de99c7a7948e66490ef8d947e272a93e9463", size = 1871020, upload-time = "2026-01-03T17:30:26Z" }, + { url = "https://files.pythonhosted.org/packages/86/f6/a62cbbf13f0ac80a70f71b1672feba90fdb21fd7abd8dbf25c0105fb6fa3/aiohttp-3.13.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9ae8dd55c8e6c4257eae3a20fd2c8f41edaea5992ed67156642493b8daf3cecc", size = 1755181, upload-time = "2026-01-03T17:30:27.554Z" }, + { url = "https://files.pythonhosted.org/packages/0a/87/20a35ad487efdd3fba93d5843efdfaa62d2f1479eaafa7453398a44faf13/aiohttp-3.13.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:01ad2529d4b5035578f5081606a465f3b814c542882804e2e8cda61adf5c71bf", size = 1561794, upload-time = "2026-01-03T17:30:29.254Z" }, + { url = "https://files.pythonhosted.org/packages/de/95/8fd69a66682012f6716e1bc09ef8a1a2a91922c5725cb904689f112309c4/aiohttp-3.13.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bb4f7475e359992b580559e008c598091c45b5088f28614e855e42d39c2f1033", size = 1697900, upload-time = "2026-01-03T17:30:31.033Z" }, + { url = "https://files.pythonhosted.org/packages/e5/66/7b94b3b5ba70e955ff597672dad1691333080e37f50280178967aff68657/aiohttp-3.13.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:c19b90316ad3b24c69cd78d5c9b4f3aa4497643685901185b65166293d36a00f", size = 1728239, upload-time = "2026-01-03T17:30:32.703Z" }, + { url = "https://files.pythonhosted.org/packages/47/71/6f72f77f9f7d74719692ab65a2a0252584bf8d5f301e2ecb4c0da734530a/aiohttp-3.13.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:96d604498a7c782cb15a51c406acaea70d8c027ee6b90c569baa6e7b93073679", size = 1740527, upload-time = "2026-01-03T17:30:34.695Z" }, + { url = "https://files.pythonhosted.org/packages/fa/b4/75ec16cbbd5c01bdaf4a05b19e103e78d7ce1ef7c80867eb0ace42ff4488/aiohttp-3.13.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:084911a532763e9d3dd95adf78a78f4096cd5f58cdc18e6fdbc1b58417a45423", size = 1554489, upload-time = "2026-01-03T17:30:36.864Z" }, + { url = "https://files.pythonhosted.org/packages/52/8f/bc518c0eea29f8406dcf7ed1f96c9b48e3bc3995a96159b3fc11f9e08321/aiohttp-3.13.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:7a4a94eb787e606d0a09404b9c38c113d3b099d508021faa615d70a0131907ce", size = 1767852, upload-time = "2026-01-03T17:30:39.433Z" }, + { url = "https://files.pythonhosted.org/packages/9d/f2/a07a75173124f31f11ea6f863dc44e6f09afe2bca45dd4e64979490deab1/aiohttp-3.13.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:87797e645d9d8e222e04160ee32aa06bc5c163e8499f24db719e7852ec23093a", size = 1722379, upload-time = "2026-01-03T17:30:41.081Z" }, + { url = "https://files.pythonhosted.org/packages/3c/4a/1a3fee7c21350cac78e5c5cef711bac1b94feca07399f3d406972e2d8fcd/aiohttp-3.13.3-cp312-cp312-win32.whl", hash = "sha256:b04be762396457bef43f3597c991e192ee7da460a4953d7e647ee4b1c28e7046", size = 428253, upload-time = "2026-01-03T17:30:42.644Z" }, + { url = "https://files.pythonhosted.org/packages/d9/b7/76175c7cb4eb73d91ad63c34e29fc4f77c9386bba4a65b53ba8e05ee3c39/aiohttp-3.13.3-cp312-cp312-win_amd64.whl", hash = "sha256:e3531d63d3bdfa7e3ac5e9b27b2dd7ec9df3206a98e0b3445fa906f233264c57", size = 455407, upload-time = "2026-01-03T17:30:44.195Z" }, + { url = "https://files.pythonhosted.org/packages/97/8a/12ca489246ca1faaf5432844adbfce7ff2cc4997733e0af120869345643a/aiohttp-3.13.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:5dff64413671b0d3e7d5918ea490bdccb97a4ad29b3f311ed423200b2203e01c", size = 734190, upload-time = "2026-01-03T17:30:45.832Z" }, + { url = "https://files.pythonhosted.org/packages/32/08/de43984c74ed1fca5c014808963cc83cb00d7bb06af228f132d33862ca76/aiohttp-3.13.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:87b9aab6d6ed88235aa2970294f496ff1a1f9adcd724d800e9b952395a80ffd9", size = 491783, upload-time = "2026-01-03T17:30:47.466Z" }, + { url = "https://files.pythonhosted.org/packages/17/f8/8dd2cf6112a5a76f81f81a5130c57ca829d101ad583ce57f889179accdda/aiohttp-3.13.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:425c126c0dc43861e22cb1c14ba4c8e45d09516d0a3ae0a3f7494b79f5f233a3", size = 490704, upload-time = "2026-01-03T17:30:49.373Z" }, + { url = "https://files.pythonhosted.org/packages/6d/40/a46b03ca03936f832bc7eaa47cfbb1ad012ba1be4790122ee4f4f8cba074/aiohttp-3.13.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7f9120f7093c2a32d9647abcaf21e6ad275b4fbec5b55969f978b1a97c7c86bf", size = 1720652, upload-time = "2026-01-03T17:30:50.974Z" }, + { url = "https://files.pythonhosted.org/packages/f7/7e/917fe18e3607af92657e4285498f500dca797ff8c918bd7d90b05abf6c2a/aiohttp-3.13.3-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:697753042d57f4bf7122cab985bf15d0cef23c770864580f5af4f52023a56bd6", size = 1692014, upload-time = "2026-01-03T17:30:52.729Z" }, + { url = "https://files.pythonhosted.org/packages/71/b6/cefa4cbc00d315d68973b671cf105b21a609c12b82d52e5d0c9ae61d2a09/aiohttp-3.13.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6de499a1a44e7de70735d0b39f67c8f25eb3d91eb3103be99ca0fa882cdd987d", size = 1759777, upload-time = "2026-01-03T17:30:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/fb/e3/e06ee07b45e59e6d81498b591fc589629be1553abb2a82ce33efe2a7b068/aiohttp-3.13.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:37239e9f9a7ea9ac5bf6b92b0260b01f8a22281996da609206a84df860bc1261", size = 1861276, upload-time = "2026-01-03T17:30:56.512Z" }, + { url = "https://files.pythonhosted.org/packages/7c/24/75d274228acf35ceeb2850b8ce04de9dd7355ff7a0b49d607ee60c29c518/aiohttp-3.13.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f76c1e3fe7d7c8afad7ed193f89a292e1999608170dcc9751a7462a87dfd5bc0", size = 1743131, upload-time = "2026-01-03T17:30:58.256Z" }, + { url = "https://files.pythonhosted.org/packages/04/98/3d21dde21889b17ca2eea54fdcff21b27b93f45b7bb94ca029c31ab59dc3/aiohttp-3.13.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fc290605db2a917f6e81b0e1e0796469871f5af381ce15c604a3c5c7e51cb730", size = 1556863, upload-time = "2026-01-03T17:31:00.445Z" }, + { url = "https://files.pythonhosted.org/packages/9e/84/da0c3ab1192eaf64782b03971ab4055b475d0db07b17eff925e8c93b3aa5/aiohttp-3.13.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4021b51936308aeea0367b8f006dc999ca02bc118a0cc78c303f50a2ff6afb91", size = 1682793, upload-time = "2026-01-03T17:31:03.024Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0f/5802ada182f575afa02cbd0ec5180d7e13a402afb7c2c03a9aa5e5d49060/aiohttp-3.13.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:49a03727c1bba9a97d3e93c9f93ca03a57300f484b6e935463099841261195d3", size = 1716676, upload-time = "2026-01-03T17:31:04.842Z" }, + { url = "https://files.pythonhosted.org/packages/3f/8c/714d53bd8b5a4560667f7bbbb06b20c2382f9c7847d198370ec6526af39c/aiohttp-3.13.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3d9908a48eb7416dc1f4524e69f1d32e5d90e3981e4e37eb0aa1cd18f9cfa2a4", size = 1733217, upload-time = "2026-01-03T17:31:06.868Z" }, + { url = "https://files.pythonhosted.org/packages/7d/79/e2176f46d2e963facea939f5be2d26368ce543622be6f00a12844d3c991f/aiohttp-3.13.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:2712039939ec963c237286113c68dbad80a82a4281543f3abf766d9d73228998", size = 1552303, upload-time = "2026-01-03T17:31:08.958Z" }, + { url = "https://files.pythonhosted.org/packages/ab/6a/28ed4dea1759916090587d1fe57087b03e6c784a642b85ef48217b0277ae/aiohttp-3.13.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:7bfdc049127717581866fa4708791220970ce291c23e28ccf3922c700740fdc0", size = 1763673, upload-time = "2026-01-03T17:31:10.676Z" }, + { url = "https://files.pythonhosted.org/packages/e8/35/4a3daeb8b9fab49240d21c04d50732313295e4bd813a465d840236dd0ce1/aiohttp-3.13.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8057c98e0c8472d8846b9c79f56766bcc57e3e8ac7bfd510482332366c56c591", size = 1721120, upload-time = "2026-01-03T17:31:12.575Z" }, + { url = "https://files.pythonhosted.org/packages/bc/9f/d643bb3c5fb99547323e635e251c609fbbc660d983144cfebec529e09264/aiohttp-3.13.3-cp313-cp313-win32.whl", hash = "sha256:1449ceddcdbcf2e0446957863af03ebaaa03f94c090f945411b61269e2cb5daf", size = 427383, upload-time = "2026-01-03T17:31:14.382Z" }, + { url = "https://files.pythonhosted.org/packages/4e/f1/ab0395f8a79933577cdd996dd2f9aa6014af9535f65dddcf88204682fe62/aiohttp-3.13.3-cp313-cp313-win_amd64.whl", hash = "sha256:693781c45a4033d31d4187d2436f5ac701e7bbfe5df40d917736108c1cc7436e", size = 453899, upload-time = "2026-01-03T17:31:15.958Z" }, + { url = "https://files.pythonhosted.org/packages/99/36/5b6514a9f5d66f4e2597e40dea2e3db271e023eb7a5d22defe96ba560996/aiohttp-3.13.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:ea37047c6b367fd4bd632bff8077449b8fa034b69e812a18e0132a00fae6e808", size = 737238, upload-time = "2026-01-03T17:31:17.909Z" }, + { url = "https://files.pythonhosted.org/packages/f7/49/459327f0d5bcd8c6c9ca69e60fdeebc3622861e696490d8674a6d0cb90a6/aiohttp-3.13.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:6fc0e2337d1a4c3e6acafda6a78a39d4c14caea625124817420abceed36e2415", size = 492292, upload-time = "2026-01-03T17:31:19.919Z" }, + { url = "https://files.pythonhosted.org/packages/e8/0b/b97660c5fd05d3495b4eb27f2d0ef18dc1dc4eff7511a9bf371397ff0264/aiohttp-3.13.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c685f2d80bb67ca8c3837823ad76196b3694b0159d232206d1e461d3d434666f", size = 493021, upload-time = "2026-01-03T17:31:21.636Z" }, + { url = "https://files.pythonhosted.org/packages/54/d4/438efabdf74e30aeceb890c3290bbaa449780583b1270b00661126b8aae4/aiohttp-3.13.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:48e377758516d262bde50c2584fc6c578af272559c409eecbdd2bae1601184d6", size = 1717263, upload-time = "2026-01-03T17:31:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/71/f2/7bddc7fd612367d1459c5bcf598a9e8f7092d6580d98de0e057eb42697ad/aiohttp-3.13.3-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:34749271508078b261c4abb1767d42b8d0c0cc9449c73a4df494777dc55f0687", size = 1669107, upload-time = "2026-01-03T17:31:25.334Z" }, + { url = "https://files.pythonhosted.org/packages/00/5a/1aeaecca40e22560f97610a329e0e5efef5e0b5afdf9f857f0d93839ab2e/aiohttp-3.13.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:82611aeec80eb144416956ec85b6ca45a64d76429c1ed46ae1b5f86c6e0c9a26", size = 1760196, upload-time = "2026-01-03T17:31:27.394Z" }, + { url = "https://files.pythonhosted.org/packages/f8/f8/0ff6992bea7bd560fc510ea1c815f87eedd745fe035589c71ce05612a19a/aiohttp-3.13.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2fff83cfc93f18f215896e3a190e8e5cb413ce01553901aca925176e7568963a", size = 1843591, upload-time = "2026-01-03T17:31:29.238Z" }, + { url = "https://files.pythonhosted.org/packages/e3/d1/e30e537a15f53485b61f5be525f2157da719819e8377298502aebac45536/aiohttp-3.13.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bbe7d4cecacb439e2e2a8a1a7b935c25b812af7a5fd26503a66dadf428e79ec1", size = 1720277, upload-time = "2026-01-03T17:31:31.053Z" }, + { url = "https://files.pythonhosted.org/packages/84/45/23f4c451d8192f553d38d838831ebbc156907ea6e05557f39563101b7717/aiohttp-3.13.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b928f30fe49574253644b1ca44b1b8adbd903aa0da4b9054a6c20fc7f4092a25", size = 1548575, upload-time = "2026-01-03T17:31:32.87Z" }, + { url = "https://files.pythonhosted.org/packages/6a/ed/0a42b127a43712eda7807e7892c083eadfaf8429ca8fb619662a530a3aab/aiohttp-3.13.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7b5e8fe4de30df199155baaf64f2fcd604f4c678ed20910db8e2c66dc4b11603", size = 1679455, upload-time = "2026-01-03T17:31:34.76Z" }, + { url = "https://files.pythonhosted.org/packages/2e/b5/c05f0c2b4b4fe2c9d55e73b6d3ed4fd6c9dc2684b1d81cbdf77e7fad9adb/aiohttp-3.13.3-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:8542f41a62bcc58fc7f11cf7c90e0ec324ce44950003feb70640fc2a9092c32a", size = 1687417, upload-time = "2026-01-03T17:31:36.699Z" }, + { url = "https://files.pythonhosted.org/packages/c9/6b/915bc5dad66aef602b9e459b5a973529304d4e89ca86999d9d75d80cbd0b/aiohttp-3.13.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:5e1d8c8b8f1d91cd08d8f4a3c2b067bfca6ec043d3ff36de0f3a715feeedf926", size = 1729968, upload-time = "2026-01-03T17:31:38.622Z" }, + { url = "https://files.pythonhosted.org/packages/11/3b/e84581290a9520024a08640b63d07673057aec5ca548177a82026187ba73/aiohttp-3.13.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:90455115e5da1c3c51ab619ac57f877da8fd6d73c05aacd125c5ae9819582aba", size = 1545690, upload-time = "2026-01-03T17:31:40.57Z" }, + { url = "https://files.pythonhosted.org/packages/f5/04/0c3655a566c43fd647c81b895dfe361b9f9ad6d58c19309d45cff52d6c3b/aiohttp-3.13.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:042e9e0bcb5fba81886c8b4fbb9a09d6b8a00245fd8d88e4d989c1f96c74164c", size = 1746390, upload-time = "2026-01-03T17:31:42.857Z" }, + { url = "https://files.pythonhosted.org/packages/1f/53/71165b26978f719c3419381514c9690bd5980e764a09440a10bb816ea4ab/aiohttp-3.13.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2eb752b102b12a76ca02dff751a801f028b4ffbbc478840b473597fc91a9ed43", size = 1702188, upload-time = "2026-01-03T17:31:44.984Z" }, + { url = "https://files.pythonhosted.org/packages/29/a7/cbe6c9e8e136314fa1980da388a59d2f35f35395948a08b6747baebb6aa6/aiohttp-3.13.3-cp314-cp314-win32.whl", hash = "sha256:b556c85915d8efaed322bf1bdae9486aa0f3f764195a0fb6ee962e5c71ef5ce1", size = 433126, upload-time = "2026-01-03T17:31:47.463Z" }, + { url = "https://files.pythonhosted.org/packages/de/56/982704adea7d3b16614fc5936014e9af85c0e34b58f9046655817f04306e/aiohttp-3.13.3-cp314-cp314-win_amd64.whl", hash = "sha256:9bf9f7a65e7aa20dd764151fb3d616c81088f91f8df39c3893a536e279b4b984", size = 459128, upload-time = "2026-01-03T17:31:49.2Z" }, + { url = "https://files.pythonhosted.org/packages/6c/2a/3c79b638a9c3d4658d345339d22070241ea341ed4e07b5ac60fb0f418003/aiohttp-3.13.3-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:05861afbbec40650d8a07ea324367cb93e9e8cc7762e04dd4405df99fa65159c", size = 769512, upload-time = "2026-01-03T17:31:51.134Z" }, + { url = "https://files.pythonhosted.org/packages/29/b9/3e5014d46c0ab0db8707e0ac2711ed28c4da0218c358a4e7c17bae0d8722/aiohttp-3.13.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2fc82186fadc4a8316768d61f3722c230e2c1dcab4200d52d2ebdf2482e47592", size = 506444, upload-time = "2026-01-03T17:31:52.85Z" }, + { url = "https://files.pythonhosted.org/packages/90/03/c1d4ef9a054e151cd7839cdc497f2638f00b93cbe8043983986630d7a80c/aiohttp-3.13.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0add0900ff220d1d5c5ebbf99ed88b0c1bbf87aa7e4262300ed1376a6b13414f", size = 510798, upload-time = "2026-01-03T17:31:54.91Z" }, + { url = "https://files.pythonhosted.org/packages/ea/76/8c1e5abbfe8e127c893fe7ead569148a4d5a799f7cf958d8c09f3eedf097/aiohttp-3.13.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:568f416a4072fbfae453dcf9a99194bbb8bdeab718e08ee13dfa2ba0e4bebf29", size = 1868835, upload-time = "2026-01-03T17:31:56.733Z" }, + { url = "https://files.pythonhosted.org/packages/8e/ac/984c5a6f74c363b01ff97adc96a3976d9c98940b8969a1881575b279ac5d/aiohttp-3.13.3-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:add1da70de90a2569c5e15249ff76a631ccacfe198375eead4aadf3b8dc849dc", size = 1720486, upload-time = "2026-01-03T17:31:58.65Z" }, + { url = "https://files.pythonhosted.org/packages/b2/9a/b7039c5f099c4eb632138728828b33428585031a1e658d693d41d07d89d1/aiohttp-3.13.3-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:10b47b7ba335d2e9b1239fa571131a87e2d8ec96b333e68b2a305e7a98b0bae2", size = 1847951, upload-time = "2026-01-03T17:32:00.989Z" }, + { url = "https://files.pythonhosted.org/packages/3c/02/3bec2b9a1ba3c19ff89a43a19324202b8eb187ca1e928d8bdac9bbdddebd/aiohttp-3.13.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3dd4dce1c718e38081c8f35f323209d4c1df7d4db4bab1b5c88a6b4d12b74587", size = 1941001, upload-time = "2026-01-03T17:32:03.122Z" }, + { url = "https://files.pythonhosted.org/packages/37/df/d879401cedeef27ac4717f6426c8c36c3091c6e9f08a9178cc87549c537f/aiohttp-3.13.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34bac00a67a812570d4a460447e1e9e06fae622946955f939051e7cc895cfab8", size = 1797246, upload-time = "2026-01-03T17:32:05.255Z" }, + { url = "https://files.pythonhosted.org/packages/8d/15/be122de1f67e6953add23335c8ece6d314ab67c8bebb3f181063010795a7/aiohttp-3.13.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a19884d2ee70b06d9204b2727a7b9f983d0c684c650254679e716b0b77920632", size = 1627131, upload-time = "2026-01-03T17:32:07.607Z" }, + { url = "https://files.pythonhosted.org/packages/12/12/70eedcac9134cfa3219ab7af31ea56bc877395b1ac30d65b1bc4b27d0438/aiohttp-3.13.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5f8ca7f2bb6ba8348a3614c7918cc4bb73268c5ac2a207576b7afea19d3d9f64", size = 1795196, upload-time = "2026-01-03T17:32:09.59Z" }, + { url = "https://files.pythonhosted.org/packages/32/11/b30e1b1cd1f3054af86ebe60df96989c6a414dd87e27ad16950eee420bea/aiohttp-3.13.3-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:b0d95340658b9d2f11d9697f59b3814a9d3bb4b7a7c20b131df4bcef464037c0", size = 1782841, upload-time = "2026-01-03T17:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/88/0d/d98a9367b38912384a17e287850f5695c528cff0f14f791ce8ee2e4f7796/aiohttp-3.13.3-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:a1e53262fd202e4b40b70c3aff944a8155059beedc8a89bba9dc1f9ef06a1b56", size = 1795193, upload-time = "2026-01-03T17:32:13.705Z" }, + { url = "https://files.pythonhosted.org/packages/43/a5/a2dfd1f5ff5581632c7f6a30e1744deda03808974f94f6534241ef60c751/aiohttp-3.13.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:d60ac9663f44168038586cab2157e122e46bdef09e9368b37f2d82d354c23f72", size = 1621979, upload-time = "2026-01-03T17:32:15.965Z" }, + { url = "https://files.pythonhosted.org/packages/fa/f0/12973c382ae7c1cccbc4417e129c5bf54c374dfb85af70893646e1f0e749/aiohttp-3.13.3-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:90751b8eed69435bac9ff4e3d2f6b3af1f57e37ecb0fbeee59c0174c9e2d41df", size = 1822193, upload-time = "2026-01-03T17:32:18.219Z" }, + { url = "https://files.pythonhosted.org/packages/3c/5f/24155e30ba7f8c96918af1350eb0663e2430aad9e001c0489d89cd708ab1/aiohttp-3.13.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fc353029f176fd2b3ec6cfc71be166aba1936fe5d73dd1992ce289ca6647a9aa", size = 1769801, upload-time = "2026-01-03T17:32:20.25Z" }, + { url = "https://files.pythonhosted.org/packages/eb/f8/7314031ff5c10e6ece114da79b338ec17eeff3a079e53151f7e9f43c4723/aiohttp-3.13.3-cp314-cp314t-win32.whl", hash = "sha256:2e41b18a58da1e474a057b3d35248d8320029f61d70a37629535b16a0c8f3767", size = 466523, upload-time = "2026-01-03T17:32:22.215Z" }, + { url = "https://files.pythonhosted.org/packages/b4/63/278a98c715ae467624eafe375542d8ba9b4383a016df8fdefe0ae28382a7/aiohttp-3.13.3-cp314-cp314t-win_amd64.whl", hash = "sha256:44531a36aa2264a1860089ffd4dce7baf875ee5a6079d5fb42e261c704ef7344", size = 499694, upload-time = "2026-01-03T17:32:24.546Z" }, + { url = "https://files.pythonhosted.org/packages/bf/79/446655656861d3e7e2c32bfcf160c7aa9e9dc63776a691b124dba65cdd77/aiohttp-3.13.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:31a83ea4aead760dfcb6962efb1d861db48c34379f2ff72db9ddddd4cda9ea2e", size = 741433, upload-time = "2026-01-03T17:32:26.453Z" }, + { url = "https://files.pythonhosted.org/packages/cb/49/773c4b310b5140d2fb5e79bb0bf40b7b41dad80a288ca1a8759f5f72bda9/aiohttp-3.13.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:988a8c5e317544fdf0d39871559e67b6341065b87fceac641108c2096d5506b7", size = 497332, upload-time = "2026-01-03T17:32:28.37Z" }, + { url = "https://files.pythonhosted.org/packages/bc/31/1dcbc4b83a4e6f76a0ad883f07f21ffbfe29750c89db97381701508c9f45/aiohttp-3.13.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9b174f267b5cfb9a7dba9ee6859cecd234e9a681841eb85068059bc867fb8f02", size = 492365, upload-time = "2026-01-03T17:32:30.234Z" }, + { url = "https://files.pythonhosted.org/packages/5a/b5/b50657496c8754482cd7964e50aaf3aa84b3db61ed45daec4c1aec5b94b4/aiohttp-3.13.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:947c26539750deeaee933b000fb6517cc770bbd064bad6033f1cff4803881e43", size = 1660440, upload-time = "2026-01-03T17:32:32.586Z" }, + { url = "https://files.pythonhosted.org/packages/2a/73/9b69e5139d89d75127569298931444ad78ea86a5befd5599780b1e9a6880/aiohttp-3.13.3-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9ebf57d09e131f5323464bd347135a88622d1c0976e88ce15b670e7ad57e4bd6", size = 1632740, upload-time = "2026-01-03T17:32:34.793Z" }, + { url = "https://files.pythonhosted.org/packages/ef/fe/3ea9b5af694b4e3aec0d0613a806132ca744747146fca68e96bf056f61a7/aiohttp-3.13.3-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4ae5b5a0e1926e504c81c5b84353e7a5516d8778fbbff00429fe7b05bb25cbce", size = 1719782, upload-time = "2026-01-03T17:32:37.737Z" }, + { url = "https://files.pythonhosted.org/packages/fb/c2/46b3b06e60851cbb71efb0f79a3267279cbef7b12c58e68a1e897f269cca/aiohttp-3.13.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2ba0eea45eb5cc3172dbfc497c066f19c41bac70963ea1a67d51fc92e4cf9a80", size = 1813527, upload-time = "2026-01-03T17:32:39.973Z" }, + { url = "https://files.pythonhosted.org/packages/36/23/71ceb78c769ed65fe4c697692de232b63dab399210678d2b00961ccb0619/aiohttp-3.13.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bae5c2ed2eae26cc382020edad80d01f36cb8e746da40b292e68fec40421dc6a", size = 1661268, upload-time = "2026-01-03T17:32:42.082Z" }, + { url = "https://files.pythonhosted.org/packages/c4/8d/86e929523d955e85ebab7c0e2b9e0cb63604cfc27dc3280e10d0063cf682/aiohttp-3.13.3-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8a60e60746623925eab7d25823329941aee7242d559baa119ca2b253c88a7bd6", size = 1552742, upload-time = "2026-01-03T17:32:44.622Z" }, + { url = "https://files.pythonhosted.org/packages/3a/ea/3f5987cba1bab6bd151f0d97aa60f0ce04d3c83316692a6bb6ba2fb69f92/aiohttp-3.13.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e50a2e1404f063427c9d027378472316201a2290959a295169bcf25992d04558", size = 1632918, upload-time = "2026-01-03T17:32:46.749Z" }, + { url = "https://files.pythonhosted.org/packages/be/2c/7e1e85121f2e31ee938cb83a8f32dfafd4908530c10fabd6d46761c12ac7/aiohttp-3.13.3-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:9a9dc347e5a3dc7dfdbc1f82da0ef29e388ddb2ed281bfce9dd8248a313e62b7", size = 1644446, upload-time = "2026-01-03T17:32:49.063Z" }, + { url = "https://files.pythonhosted.org/packages/5d/35/ce6133d423ad0e8ca976a7c848f7146bca3520eea4ccf6b95e2d077c9d20/aiohttp-3.13.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:b46020d11d23fe16551466c77823df9cc2f2c1e63cc965daf67fa5eec6ca1877", size = 1689487, upload-time = "2026-01-03T17:32:51.113Z" }, + { url = "https://files.pythonhosted.org/packages/50/f7/ff7a27c15603d460fd1366b3c22054f7ae4fa9310aca40b43bde35867fcd/aiohttp-3.13.3-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:69c56fbc1993fa17043e24a546959c0178fe2b5782405ad4559e6c13975c15e3", size = 1540715, upload-time = "2026-01-03T17:32:53.38Z" }, + { url = "https://files.pythonhosted.org/packages/17/02/053f11346e5b962e6d8a1c4f8c70c29d5970a1b4b8e7894c68e12c27a57f/aiohttp-3.13.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:b99281b0704c103d4e11e72a76f1b543d4946fea7dd10767e7e1b5f00d4e5704", size = 1711835, upload-time = "2026-01-03T17:32:56.088Z" }, + { url = "https://files.pythonhosted.org/packages/fb/71/9b9761ddf276fd6708d13720197cbac19b8d67ecfa9116777924056cfcaa/aiohttp-3.13.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:40c5e40ecc29ba010656c18052b877a1c28f84344825efa106705e835c28530f", size = 1649593, upload-time = "2026-01-03T17:32:58.181Z" }, + { url = "https://files.pythonhosted.org/packages/ae/72/5d817e9ea218acae12a5e3b9ad1178cf0c12fc3570c0b47eea2daf95f9ea/aiohttp-3.13.3-cp39-cp39-win32.whl", hash = "sha256:56339a36b9f1fc708260c76c87e593e2afb30d26de9ae1eb445b5e051b98a7a1", size = 434831, upload-time = "2026-01-03T17:33:00.577Z" }, + { url = "https://files.pythonhosted.org/packages/39/cb/22659d9bf3149b7a2927bc2769cc9c8f8f5a80eba098398e03c199a43a85/aiohttp-3.13.3-cp39-cp39-win_amd64.whl", hash = "sha256:c6b8568a3bb5819a0ad087f16d40e5a3fb6099f39ea1d5625a3edc1e923fc538", size = 457697, upload-time = "2026-01-03T17:33:03.167Z" }, +] + +[[package]] +name = "aiosignal" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "frozenlist" }, + { name = "typing-extensions", marker = "python_full_version < '3.13' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007, upload-time = "2025-07-03T22:54:43.528Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" }, +] + +[[package]] +name = "annotated-types" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, +] + +[[package]] +name = "anyio" +version = "4.12.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "exceptiongroup", marker = "python_full_version < '3.11' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, + { name = "idna" }, + { name = "typing-extensions", marker = "python_full_version < '3.13' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/96/f0/5eb65b2bb0d09ac6776f2eb54adee6abe8228ea05b20a5ad0e4945de8aac/anyio-4.12.1.tar.gz", hash = "sha256:41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703", size = 228685, upload-time = "2026-01-06T11:45:21.246Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl", hash = "sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c", size = 113592, upload-time = "2026-01-06T11:45:19.497Z" }, +] + +[[package]] +name = "async-timeout" +version = "5.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a5/ae/136395dfbfe00dfc94da3f3e136d0b13f394cba8f4841120e34226265780/async_timeout-5.0.1.tar.gz", hash = "sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3", size = 9274, upload-time = "2024-11-06T16:41:39.6Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fe/ba/e2081de779ca30d473f21f5b30e0e737c438205440784c7dfc81efc2b029/async_timeout-5.0.1-py3-none-any.whl", hash = "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c", size = 6233, upload-time = "2024-11-06T16:41:37.9Z" }, +] + +[[package]] +name = "attrs" +version = "25.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6b/5c/685e6633917e101e5dcb62b9dd76946cbb57c26e133bae9e0cd36033c0a9/attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11", size = 934251, upload-time = "2025-10-06T13:54:44.725Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615, upload-time = "2025-10-06T13:54:43.17Z" }, +] + +[[package]] +name = "backports-asyncio-runner" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/ff/70dca7d7cb1cbc0edb2c6cc0c38b65cba36cccc491eca64cabd5fe7f8670/backports_asyncio_runner-1.2.0.tar.gz", hash = "sha256:a5aa7b2b7d8f8bfcaa2b57313f70792df84e32a2a746f585213373f900b42162", size = 69893, upload-time = "2025-07-02T02:27:15.685Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/59/76ab57e3fe74484f48a53f8e337171b4a2349e506eabe136d7e01d059086/backports_asyncio_runner-1.2.0-py3-none-any.whl", hash = "sha256:0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5", size = 12313, upload-time = "2025-07-02T02:27:14.263Z" }, +] + +[[package]] +name = "certifi" +version = "2026.1.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/2d/a891ca51311197f6ad14a7ef42e2399f36cf2f9bd44752b3dc4eab60fdc5/certifi-2026.1.4.tar.gz", hash = "sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120", size = 154268, upload-time = "2026-01-04T02:42:41.825Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl", hash = "sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c", size = 152900, upload-time = "2026-01-04T02:42:40.15Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "dirty-equals" +version = "0.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/30/1d/c5913ac9d6615515a00f4bdc71356d302437cb74ff2e9aaccd3c14493b78/dirty_equals-0.11.tar.gz", hash = "sha256:f4ac74ee88f2d11e2fa0f65eb30ee4f07105c5f86f4dc92b09eb1138775027c3", size = 128067, upload-time = "2025-11-17T01:51:24.451Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bb/8d/dbff05239043271dbeace563a7686212a3dd517864a35623fe4d4a64ca19/dirty_equals-0.11-py3-none-any.whl", hash = "sha256:b1d7093273fc2f9be12f443a8ead954ef6daaf6746fd42ef3a5616433ee85286", size = 28051, upload-time = "2025-11-17T01:51:22.849Z" }, +] + +[[package]] +name = "distro" +version = "1.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", size = 60722, upload-time = "2023-12-24T09:54:32.31Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277, upload-time = "2023-12-24T09:54:30.421Z" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.13' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } +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 = "execnet" +version = "2.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bf/89/780e11f9588d9e7128a3f87788354c7946a9cbb1401ad38a48c4db9a4f07/execnet-2.1.2.tar.gz", hash = "sha256:63d83bfdd9a23e35b9c6a3261412324f964c2ec8dcd8d3c6916ee9373e0befcd", size = 166622, upload-time = "2025-11-12T09:56:37.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl", hash = "sha256:67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec", size = 40708, upload-time = "2025-11-12T09:56:36.333Z" }, +] + +[[package]] +name = "frozenlist" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2d/f5/c831fac6cc817d26fd54c7eaccd04ef7e0288806943f7cc5bbf69f3ac1f0/frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad", size = 45875, upload-time = "2025-10-06T05:38:17.865Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/83/4a/557715d5047da48d54e659203b9335be7bfaafda2c3f627b7c47e0b3aaf3/frozenlist-1.8.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b37f6d31b3dcea7deb5e9696e529a6aa4a898adc33db82da12e4c60a7c4d2011", size = 86230, upload-time = "2025-10-06T05:35:23.699Z" }, + { url = "https://files.pythonhosted.org/packages/a2/fb/c85f9fed3ea8fe8740e5b46a59cc141c23b842eca617da8876cfce5f760e/frozenlist-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ef2b7b394f208233e471abc541cc6991f907ffd47dc72584acee3147899d6565", size = 49621, upload-time = "2025-10-06T05:35:25.341Z" }, + { url = "https://files.pythonhosted.org/packages/63/70/26ca3f06aace16f2352796b08704338d74b6d1a24ca38f2771afbb7ed915/frozenlist-1.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a88f062f072d1589b7b46e951698950e7da00442fc1cacbe17e19e025dc327ad", size = 49889, upload-time = "2025-10-06T05:35:26.797Z" }, + { url = "https://files.pythonhosted.org/packages/5d/ed/c7895fd2fde7f3ee70d248175f9b6cdf792fb741ab92dc59cd9ef3bd241b/frozenlist-1.8.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f57fb59d9f385710aa7060e89410aeb5058b99e62f4d16b08b91986b9a2140c2", size = 219464, upload-time = "2025-10-06T05:35:28.254Z" }, + { url = "https://files.pythonhosted.org/packages/6b/83/4d587dccbfca74cb8b810472392ad62bfa100bf8108c7223eb4c4fa2f7b3/frozenlist-1.8.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:799345ab092bee59f01a915620b5d014698547afd011e691a208637312db9186", size = 221649, upload-time = "2025-10-06T05:35:29.454Z" }, + { url = "https://files.pythonhosted.org/packages/6a/c6/fd3b9cd046ec5fff9dab66831083bc2077006a874a2d3d9247dea93ddf7e/frozenlist-1.8.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c23c3ff005322a6e16f71bf8692fcf4d5a304aaafe1e262c98c6d4adc7be863e", size = 219188, upload-time = "2025-10-06T05:35:30.951Z" }, + { url = "https://files.pythonhosted.org/packages/ce/80/6693f55eb2e085fc8afb28cf611448fb5b90e98e068fa1d1b8d8e66e5c7d/frozenlist-1.8.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8a76ea0f0b9dfa06f254ee06053d93a600865b3274358ca48a352ce4f0798450", size = 231748, upload-time = "2025-10-06T05:35:32.101Z" }, + { url = "https://files.pythonhosted.org/packages/97/d6/e9459f7c5183854abd989ba384fe0cc1a0fb795a83c033f0571ec5933ca4/frozenlist-1.8.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c7366fe1418a6133d5aa824ee53d406550110984de7637d65a178010f759c6ef", size = 236351, upload-time = "2025-10-06T05:35:33.834Z" }, + { url = "https://files.pythonhosted.org/packages/97/92/24e97474b65c0262e9ecd076e826bfd1d3074adcc165a256e42e7b8a7249/frozenlist-1.8.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:13d23a45c4cebade99340c4165bd90eeb4a56c6d8a9d8aa49568cac19a6d0dc4", size = 218767, upload-time = "2025-10-06T05:35:35.205Z" }, + { url = "https://files.pythonhosted.org/packages/ee/bf/dc394a097508f15abff383c5108cb8ad880d1f64a725ed3b90d5c2fbf0bb/frozenlist-1.8.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:e4a3408834f65da56c83528fb52ce7911484f0d1eaf7b761fc66001db1646eff", size = 235887, upload-time = "2025-10-06T05:35:36.354Z" }, + { url = "https://files.pythonhosted.org/packages/40/90/25b201b9c015dbc999a5baf475a257010471a1fa8c200c843fd4abbee725/frozenlist-1.8.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:42145cd2748ca39f32801dad54aeea10039da6f86e303659db90db1c4b614c8c", size = 228785, upload-time = "2025-10-06T05:35:37.949Z" }, + { url = "https://files.pythonhosted.org/packages/84/f4/b5bc148df03082f05d2dd30c089e269acdbe251ac9a9cf4e727b2dbb8a3d/frozenlist-1.8.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:e2de870d16a7a53901e41b64ffdf26f2fbb8917b3e6ebf398098d72c5b20bd7f", size = 230312, upload-time = "2025-10-06T05:35:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/db/4b/87e95b5d15097c302430e647136b7d7ab2398a702390cf4c8601975709e7/frozenlist-1.8.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:20e63c9493d33ee48536600d1a5c95eefc870cd71e7ab037763d1fbb89cc51e7", size = 217650, upload-time = "2025-10-06T05:35:40.377Z" }, + { url = "https://files.pythonhosted.org/packages/e5/70/78a0315d1fea97120591a83e0acd644da638c872f142fd72a6cebee825f3/frozenlist-1.8.0-cp310-cp310-win32.whl", hash = "sha256:adbeebaebae3526afc3c96fad434367cafbfd1b25d72369a9e5858453b1bb71a", size = 39659, upload-time = "2025-10-06T05:35:41.863Z" }, + { url = "https://files.pythonhosted.org/packages/66/aa/3f04523fb189a00e147e60c5b2205126118f216b0aa908035c45336e27e4/frozenlist-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:667c3777ca571e5dbeb76f331562ff98b957431df140b54c85fd4d52eea8d8f6", size = 43837, upload-time = "2025-10-06T05:35:43.205Z" }, + { url = "https://files.pythonhosted.org/packages/39/75/1135feecdd7c336938bd55b4dc3b0dfc46d85b9be12ef2628574b28de776/frozenlist-1.8.0-cp310-cp310-win_arm64.whl", hash = "sha256:80f85f0a7cc86e7a54c46d99c9e1318ff01f4687c172ede30fd52d19d1da1c8e", size = 39989, upload-time = "2025-10-06T05:35:44.596Z" }, + { url = "https://files.pythonhosted.org/packages/bc/03/077f869d540370db12165c0aa51640a873fb661d8b315d1d4d67b284d7ac/frozenlist-1.8.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:09474e9831bc2b2199fad6da3c14c7b0fbdd377cce9d3d77131be28906cb7d84", size = 86912, upload-time = "2025-10-06T05:35:45.98Z" }, + { url = "https://files.pythonhosted.org/packages/df/b5/7610b6bd13e4ae77b96ba85abea1c8cb249683217ef09ac9e0ae93f25a91/frozenlist-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:17c883ab0ab67200b5f964d2b9ed6b00971917d5d8a92df149dc2c9779208ee9", size = 50046, upload-time = "2025-10-06T05:35:47.009Z" }, + { url = "https://files.pythonhosted.org/packages/6e/ef/0e8f1fe32f8a53dd26bdd1f9347efe0778b0fddf62789ea683f4cc7d787d/frozenlist-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fa47e444b8ba08fffd1c18e8cdb9a75db1b6a27f17507522834ad13ed5922b93", size = 50119, upload-time = "2025-10-06T05:35:48.38Z" }, + { url = "https://files.pythonhosted.org/packages/11/b1/71a477adc7c36e5fb628245dfbdea2166feae310757dea848d02bd0689fd/frozenlist-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2552f44204b744fba866e573be4c1f9048d6a324dfe14475103fd51613eb1d1f", size = 231067, upload-time = "2025-10-06T05:35:49.97Z" }, + { url = "https://files.pythonhosted.org/packages/45/7e/afe40eca3a2dc19b9904c0f5d7edfe82b5304cb831391edec0ac04af94c2/frozenlist-1.8.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:957e7c38f250991e48a9a73e6423db1bb9dd14e722a10f6b8bb8e16a0f55f695", size = 233160, upload-time = "2025-10-06T05:35:51.729Z" }, + { url = "https://files.pythonhosted.org/packages/a6/aa/7416eac95603ce428679d273255ffc7c998d4132cfae200103f164b108aa/frozenlist-1.8.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8585e3bb2cdea02fc88ffa245069c36555557ad3609e83be0ec71f54fd4abb52", size = 228544, upload-time = "2025-10-06T05:35:53.246Z" }, + { url = "https://files.pythonhosted.org/packages/8b/3d/2a2d1f683d55ac7e3875e4263d28410063e738384d3adc294f5ff3d7105e/frozenlist-1.8.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:edee74874ce20a373d62dc28b0b18b93f645633c2943fd90ee9d898550770581", size = 243797, upload-time = "2025-10-06T05:35:54.497Z" }, + { url = "https://files.pythonhosted.org/packages/78/1e/2d5565b589e580c296d3bb54da08d206e797d941a83a6fdea42af23be79c/frozenlist-1.8.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c9a63152fe95756b85f31186bddf42e4c02c6321207fd6601a1c89ebac4fe567", size = 247923, upload-time = "2025-10-06T05:35:55.861Z" }, + { url = "https://files.pythonhosted.org/packages/aa/c3/65872fcf1d326a7f101ad4d86285c403c87be7d832b7470b77f6d2ed5ddc/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b6db2185db9be0a04fecf2f241c70b63b1a242e2805be291855078f2b404dd6b", size = 230886, upload-time = "2025-10-06T05:35:57.399Z" }, + { url = "https://files.pythonhosted.org/packages/a0/76/ac9ced601d62f6956f03cc794f9e04c81719509f85255abf96e2510f4265/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:f4be2e3d8bc8aabd566f8d5b8ba7ecc09249d74ba3c9ed52e54dc23a293f0b92", size = 245731, upload-time = "2025-10-06T05:35:58.563Z" }, + { url = "https://files.pythonhosted.org/packages/b9/49/ecccb5f2598daf0b4a1415497eba4c33c1e8ce07495eb07d2860c731b8d5/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c8d1634419f39ea6f5c427ea2f90ca85126b54b50837f31497f3bf38266e853d", size = 241544, upload-time = "2025-10-06T05:35:59.719Z" }, + { url = "https://files.pythonhosted.org/packages/53/4b/ddf24113323c0bbcc54cb38c8b8916f1da7165e07b8e24a717b4a12cbf10/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:1a7fa382a4a223773ed64242dbe1c9c326ec09457e6b8428efb4118c685c3dfd", size = 241806, upload-time = "2025-10-06T05:36:00.959Z" }, + { url = "https://files.pythonhosted.org/packages/a7/fb/9b9a084d73c67175484ba2789a59f8eebebd0827d186a8102005ce41e1ba/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:11847b53d722050808926e785df837353bd4d75f1d494377e59b23594d834967", size = 229382, upload-time = "2025-10-06T05:36:02.22Z" }, + { url = "https://files.pythonhosted.org/packages/95/a3/c8fb25aac55bf5e12dae5c5aa6a98f85d436c1dc658f21c3ac73f9fa95e5/frozenlist-1.8.0-cp311-cp311-win32.whl", hash = "sha256:27c6e8077956cf73eadd514be8fb04d77fc946a7fe9f7fe167648b0b9085cc25", size = 39647, upload-time = "2025-10-06T05:36:03.409Z" }, + { url = "https://files.pythonhosted.org/packages/0a/f5/603d0d6a02cfd4c8f2a095a54672b3cf967ad688a60fb9faf04fc4887f65/frozenlist-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:ac913f8403b36a2c8610bbfd25b8013488533e71e62b4b4adce9c86c8cea905b", size = 44064, upload-time = "2025-10-06T05:36:04.368Z" }, + { url = "https://files.pythonhosted.org/packages/5d/16/c2c9ab44e181f043a86f9a8f84d5124b62dbcb3a02c0977ec72b9ac1d3e0/frozenlist-1.8.0-cp311-cp311-win_arm64.whl", hash = "sha256:d4d3214a0f8394edfa3e303136d0575eece0745ff2b47bd2cb2e66dd92d4351a", size = 39937, upload-time = "2025-10-06T05:36:05.669Z" }, + { url = "https://files.pythonhosted.org/packages/69/29/948b9aa87e75820a38650af445d2ef2b6b8a6fab1a23b6bb9e4ef0be2d59/frozenlist-1.8.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:78f7b9e5d6f2fdb88cdde9440dc147259b62b9d3b019924def9f6478be254ac1", size = 87782, upload-time = "2025-10-06T05:36:06.649Z" }, + { url = "https://files.pythonhosted.org/packages/64/80/4f6e318ee2a7c0750ed724fa33a4bdf1eacdc5a39a7a24e818a773cd91af/frozenlist-1.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:229bf37d2e4acdaf808fd3f06e854a4a7a3661e871b10dc1f8f1896a3b05f18b", size = 50594, upload-time = "2025-10-06T05:36:07.69Z" }, + { url = "https://files.pythonhosted.org/packages/2b/94/5c8a2b50a496b11dd519f4a24cb5496cf125681dd99e94c604ccdea9419a/frozenlist-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f833670942247a14eafbb675458b4e61c82e002a148f49e68257b79296e865c4", size = 50448, upload-time = "2025-10-06T05:36:08.78Z" }, + { url = "https://files.pythonhosted.org/packages/6a/bd/d91c5e39f490a49df14320f4e8c80161cfcce09f1e2cde1edd16a551abb3/frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:494a5952b1c597ba44e0e78113a7266e656b9794eec897b19ead706bd7074383", size = 242411, upload-time = "2025-10-06T05:36:09.801Z" }, + { url = "https://files.pythonhosted.org/packages/8f/83/f61505a05109ef3293dfb1ff594d13d64a2324ac3482be2cedc2be818256/frozenlist-1.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96f423a119f4777a4a056b66ce11527366a8bb92f54e541ade21f2374433f6d4", size = 243014, upload-time = "2025-10-06T05:36:11.394Z" }, + { url = "https://files.pythonhosted.org/packages/d8/cb/cb6c7b0f7d4023ddda30cf56b8b17494eb3a79e3fda666bf735f63118b35/frozenlist-1.8.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3462dd9475af2025c31cc61be6652dfa25cbfb56cbbf52f4ccfe029f38decaf8", size = 234909, upload-time = "2025-10-06T05:36:12.598Z" }, + { url = "https://files.pythonhosted.org/packages/31/c5/cd7a1f3b8b34af009fb17d4123c5a778b44ae2804e3ad6b86204255f9ec5/frozenlist-1.8.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4c800524c9cd9bac5166cd6f55285957fcfc907db323e193f2afcd4d9abd69b", size = 250049, upload-time = "2025-10-06T05:36:14.065Z" }, + { url = "https://files.pythonhosted.org/packages/c0/01/2f95d3b416c584a1e7f0e1d6d31998c4a795f7544069ee2e0962a4b60740/frozenlist-1.8.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d6a5df73acd3399d893dafc71663ad22534b5aa4f94e8a2fabfe856c3c1b6a52", size = 256485, upload-time = "2025-10-06T05:36:15.39Z" }, + { url = "https://files.pythonhosted.org/packages/ce/03/024bf7720b3abaebcff6d0793d73c154237b85bdf67b7ed55e5e9596dc9a/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:405e8fe955c2280ce66428b3ca55e12b3c4e9c336fb2103a4937e891c69a4a29", size = 237619, upload-time = "2025-10-06T05:36:16.558Z" }, + { url = "https://files.pythonhosted.org/packages/69/fa/f8abdfe7d76b731f5d8bd217827cf6764d4f1d9763407e42717b4bed50a0/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:908bd3f6439f2fef9e85031b59fd4f1297af54415fb60e4254a95f75b3cab3f3", size = 250320, upload-time = "2025-10-06T05:36:17.821Z" }, + { url = "https://files.pythonhosted.org/packages/f5/3c/b051329f718b463b22613e269ad72138cc256c540f78a6de89452803a47d/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:294e487f9ec720bd8ffcebc99d575f7eff3568a08a253d1ee1a0378754b74143", size = 246820, upload-time = "2025-10-06T05:36:19.046Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ae/58282e8f98e444b3f4dd42448ff36fa38bef29e40d40f330b22e7108f565/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:74c51543498289c0c43656701be6b077f4b265868fa7f8a8859c197006efb608", size = 250518, upload-time = "2025-10-06T05:36:20.763Z" }, + { url = "https://files.pythonhosted.org/packages/8f/96/007e5944694d66123183845a106547a15944fbbb7154788cbf7272789536/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:776f352e8329135506a1d6bf16ac3f87bc25b28e765949282dcc627af36123aa", size = 239096, upload-time = "2025-10-06T05:36:22.129Z" }, + { url = "https://files.pythonhosted.org/packages/66/bb/852b9d6db2fa40be96f29c0d1205c306288f0684df8fd26ca1951d461a56/frozenlist-1.8.0-cp312-cp312-win32.whl", hash = "sha256:433403ae80709741ce34038da08511d4a77062aa924baf411ef73d1146e74faf", size = 39985, upload-time = "2025-10-06T05:36:23.661Z" }, + { url = "https://files.pythonhosted.org/packages/b8/af/38e51a553dd66eb064cdf193841f16f077585d4d28394c2fa6235cb41765/frozenlist-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:34187385b08f866104f0c0617404c8eb08165ab1272e884abc89c112e9c00746", size = 44591, upload-time = "2025-10-06T05:36:24.958Z" }, + { url = "https://files.pythonhosted.org/packages/a7/06/1dc65480ab147339fecc70797e9c2f69d9cea9cf38934ce08df070fdb9cb/frozenlist-1.8.0-cp312-cp312-win_arm64.whl", hash = "sha256:fe3c58d2f5db5fbd18c2987cba06d51b0529f52bc3a6cdc33d3f4eab725104bd", size = 40102, upload-time = "2025-10-06T05:36:26.333Z" }, + { url = "https://files.pythonhosted.org/packages/2d/40/0832c31a37d60f60ed79e9dfb5a92e1e2af4f40a16a29abcc7992af9edff/frozenlist-1.8.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8d92f1a84bb12d9e56f818b3a746f3efba93c1b63c8387a73dde655e1e42282a", size = 85717, upload-time = "2025-10-06T05:36:27.341Z" }, + { url = "https://files.pythonhosted.org/packages/30/ba/b0b3de23f40bc55a7057bd38434e25c34fa48e17f20ee273bbde5e0650f3/frozenlist-1.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96153e77a591c8adc2ee805756c61f59fef4cf4073a9275ee86fe8cba41241f7", size = 49651, upload-time = "2025-10-06T05:36:28.855Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f21f00a91358803399890ab167098c131ec2ddd5f8f5fd5fe9c9f2c6fcd91e40", size = 49417, upload-time = "2025-10-06T05:36:29.877Z" }, + { url = "https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fb30f9626572a76dfe4293c7194a09fb1fe93ba94c7d4f720dfae3b646b45027", size = 234391, upload-time = "2025-10-06T05:36:31.301Z" }, + { url = "https://files.pythonhosted.org/packages/40/76/c202df58e3acdf12969a7895fd6f3bc016c642e6726aa63bd3025e0fc71c/frozenlist-1.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaa352d7047a31d87dafcacbabe89df0aa506abb5b1b85a2fb91bc3faa02d822", size = 233048, upload-time = "2025-10-06T05:36:32.531Z" }, + { url = "https://files.pythonhosted.org/packages/f9/c0/8746afb90f17b73ca5979c7a3958116e105ff796e718575175319b5bb4ce/frozenlist-1.8.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:03ae967b4e297f58f8c774c7eabcce57fe3c2434817d4385c50661845a058121", size = 226549, upload-time = "2025-10-06T05:36:33.706Z" }, + { url = "https://files.pythonhosted.org/packages/7e/eb/4c7eefc718ff72f9b6c4893291abaae5fbc0c82226a32dcd8ef4f7a5dbef/frozenlist-1.8.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f6292f1de555ffcc675941d65fffffb0a5bcd992905015f85d0592201793e0e5", size = 239833, upload-time = "2025-10-06T05:36:34.947Z" }, + { url = "https://files.pythonhosted.org/packages/c2/4e/e5c02187cf704224f8b21bee886f3d713ca379535f16893233b9d672ea71/frozenlist-1.8.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29548f9b5b5e3460ce7378144c3010363d8035cea44bc0bf02d57f5a685e084e", size = 245363, upload-time = "2025-10-06T05:36:36.534Z" }, + { url = "https://files.pythonhosted.org/packages/1f/96/cb85ec608464472e82ad37a17f844889c36100eed57bea094518bf270692/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ec3cc8c5d4084591b4237c0a272cc4f50a5b03396a47d9caaf76f5d7b38a4f11", size = 229314, upload-time = "2025-10-06T05:36:38.582Z" }, + { url = "https://files.pythonhosted.org/packages/5d/6f/4ae69c550e4cee66b57887daeebe006fe985917c01d0fff9caab9883f6d0/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:517279f58009d0b1f2e7c1b130b377a349405da3f7621ed6bfae50b10adf20c1", size = 243365, upload-time = "2025-10-06T05:36:40.152Z" }, + { url = "https://files.pythonhosted.org/packages/7a/58/afd56de246cf11780a40a2c28dc7cbabbf06337cc8ddb1c780a2d97e88d8/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:db1e72ede2d0d7ccb213f218df6a078a9c09a7de257c2fe8fcef16d5925230b1", size = 237763, upload-time = "2025-10-06T05:36:41.355Z" }, + { url = "https://files.pythonhosted.org/packages/cb/36/cdfaf6ed42e2644740d4a10452d8e97fa1c062e2a8006e4b09f1b5fd7d63/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b4dec9482a65c54a5044486847b8a66bf10c9cb4926d42927ec4e8fd5db7fed8", size = 240110, upload-time = "2025-10-06T05:36:42.716Z" }, + { url = "https://files.pythonhosted.org/packages/03/a8/9ea226fbefad669f11b52e864c55f0bd57d3c8d7eb07e9f2e9a0b39502e1/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:21900c48ae04d13d416f0e1e0c4d81f7931f73a9dfa0b7a8746fb2fe7dd970ed", size = 233717, upload-time = "2025-10-06T05:36:44.251Z" }, + { url = "https://files.pythonhosted.org/packages/1e/0b/1b5531611e83ba7d13ccc9988967ea1b51186af64c42b7a7af465dcc9568/frozenlist-1.8.0-cp313-cp313-win32.whl", hash = "sha256:8b7b94a067d1c504ee0b16def57ad5738701e4ba10cec90529f13fa03c833496", size = 39628, upload-time = "2025-10-06T05:36:45.423Z" }, + { url = "https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:878be833caa6a3821caf85eb39c5ba92d28e85df26d57afb06b35b2efd937231", size = 43882, upload-time = "2025-10-06T05:36:46.796Z" }, + { url = "https://files.pythonhosted.org/packages/c1/17/502cd212cbfa96eb1388614fe39a3fc9ab87dbbe042b66f97acb57474834/frozenlist-1.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:44389d135b3ff43ba8cc89ff7f51f5a0bb6b63d829c8300f79a2fe4fe61bcc62", size = 39676, upload-time = "2025-10-06T05:36:47.8Z" }, + { url = "https://files.pythonhosted.org/packages/d2/5c/3bbfaa920dfab09e76946a5d2833a7cbdf7b9b4a91c714666ac4855b88b4/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:e25ac20a2ef37e91c1b39938b591457666a0fa835c7783c3a8f33ea42870db94", size = 89235, upload-time = "2025-10-06T05:36:48.78Z" }, + { url = "https://files.pythonhosted.org/packages/d2/d6/f03961ef72166cec1687e84e8925838442b615bd0b8854b54923ce5b7b8a/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07cdca25a91a4386d2e76ad992916a85038a9b97561bf7a3fd12d5d9ce31870c", size = 50742, upload-time = "2025-10-06T05:36:49.837Z" }, + { url = "https://files.pythonhosted.org/packages/1e/bb/a6d12b7ba4c3337667d0e421f7181c82dda448ce4e7ad7ecd249a16fa806/frozenlist-1.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4e0c11f2cc6717e0a741f84a527c52616140741cd812a50422f83dc31749fb52", size = 51725, upload-time = "2025-10-06T05:36:50.851Z" }, + { url = "https://files.pythonhosted.org/packages/bc/71/d1fed0ffe2c2ccd70b43714c6cab0f4188f09f8a67a7914a6b46ee30f274/frozenlist-1.8.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b3210649ee28062ea6099cfda39e147fa1bc039583c8ee4481cb7811e2448c51", size = 284533, upload-time = "2025-10-06T05:36:51.898Z" }, + { url = "https://files.pythonhosted.org/packages/c9/1f/fb1685a7b009d89f9bf78a42d94461bc06581f6e718c39344754a5d9bada/frozenlist-1.8.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:581ef5194c48035a7de2aefc72ac6539823bb71508189e5de01d60c9dcd5fa65", size = 292506, upload-time = "2025-10-06T05:36:53.101Z" }, + { url = "https://files.pythonhosted.org/packages/e6/3b/b991fe1612703f7e0d05c0cf734c1b77aaf7c7d321df4572e8d36e7048c8/frozenlist-1.8.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3ef2d026f16a2b1866e1d86fc4e1291e1ed8a387b2c333809419a2f8b3a77b82", size = 274161, upload-time = "2025-10-06T05:36:54.309Z" }, + { url = "https://files.pythonhosted.org/packages/ca/ec/c5c618767bcdf66e88945ec0157d7f6c4a1322f1473392319b7a2501ded7/frozenlist-1.8.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5500ef82073f599ac84d888e3a8c1f77ac831183244bfd7f11eaa0289fb30714", size = 294676, upload-time = "2025-10-06T05:36:55.566Z" }, + { url = "https://files.pythonhosted.org/packages/7c/ce/3934758637d8f8a88d11f0585d6495ef54b2044ed6ec84492a91fa3b27aa/frozenlist-1.8.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:50066c3997d0091c411a66e710f4e11752251e6d2d73d70d8d5d4c76442a199d", size = 300638, upload-time = "2025-10-06T05:36:56.758Z" }, + { url = "https://files.pythonhosted.org/packages/fc/4f/a7e4d0d467298f42de4b41cbc7ddaf19d3cfeabaf9ff97c20c6c7ee409f9/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:5c1c8e78426e59b3f8005e9b19f6ff46e5845895adbde20ece9218319eca6506", size = 283067, upload-time = "2025-10-06T05:36:57.965Z" }, + { url = "https://files.pythonhosted.org/packages/dc/48/c7b163063d55a83772b268e6d1affb960771b0e203b632cfe09522d67ea5/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:eefdba20de0d938cec6a89bd4d70f346a03108a19b9df4248d3cf0d88f1b0f51", size = 292101, upload-time = "2025-10-06T05:36:59.237Z" }, + { url = "https://files.pythonhosted.org/packages/9f/d0/2366d3c4ecdc2fd391e0afa6e11500bfba0ea772764d631bbf82f0136c9d/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cf253e0e1c3ceb4aaff6df637ce033ff6535fb8c70a764a8f46aafd3d6ab798e", size = 289901, upload-time = "2025-10-06T05:37:00.811Z" }, + { url = "https://files.pythonhosted.org/packages/b8/94/daff920e82c1b70e3618a2ac39fbc01ae3e2ff6124e80739ce5d71c9b920/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:032efa2674356903cd0261c4317a561a6850f3ac864a63fc1583147fb05a79b0", size = 289395, upload-time = "2025-10-06T05:37:02.115Z" }, + { url = "https://files.pythonhosted.org/packages/e3/20/bba307ab4235a09fdcd3cc5508dbabd17c4634a1af4b96e0f69bfe551ebd/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6da155091429aeba16851ecb10a9104a108bcd32f6c1642867eadaee401c1c41", size = 283659, upload-time = "2025-10-06T05:37:03.711Z" }, + { url = "https://files.pythonhosted.org/packages/fd/00/04ca1c3a7a124b6de4f8a9a17cc2fcad138b4608e7a3fc5877804b8715d7/frozenlist-1.8.0-cp313-cp313t-win32.whl", hash = "sha256:0f96534f8bfebc1a394209427d0f8a63d343c9779cda6fc25e8e121b5fd8555b", size = 43492, upload-time = "2025-10-06T05:37:04.915Z" }, + { url = "https://files.pythonhosted.org/packages/59/5e/c69f733a86a94ab10f68e496dc6b7e8bc078ebb415281d5698313e3af3a1/frozenlist-1.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5d63a068f978fc69421fb0e6eb91a9603187527c86b7cd3f534a5b77a592b888", size = 48034, upload-time = "2025-10-06T05:37:06.343Z" }, + { url = "https://files.pythonhosted.org/packages/16/6c/be9d79775d8abe79b05fa6d23da99ad6e7763a1d080fbae7290b286093fd/frozenlist-1.8.0-cp313-cp313t-win_arm64.whl", hash = "sha256:bf0a7e10b077bf5fb9380ad3ae8ce20ef919a6ad93b4552896419ac7e1d8e042", size = 41749, upload-time = "2025-10-06T05:37:07.431Z" }, + { url = "https://files.pythonhosted.org/packages/f1/c8/85da824b7e7b9b6e7f7705b2ecaf9591ba6f79c1177f324c2735e41d36a2/frozenlist-1.8.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cee686f1f4cadeb2136007ddedd0aaf928ab95216e7691c63e50a8ec066336d0", size = 86127, upload-time = "2025-10-06T05:37:08.438Z" }, + { url = "https://files.pythonhosted.org/packages/8e/e8/a1185e236ec66c20afd72399522f142c3724c785789255202d27ae992818/frozenlist-1.8.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:119fb2a1bd47307e899c2fac7f28e85b9a543864df47aa7ec9d3c1b4545f096f", size = 49698, upload-time = "2025-10-06T05:37:09.48Z" }, + { url = "https://files.pythonhosted.org/packages/a1/93/72b1736d68f03fda5fdf0f2180fb6caaae3894f1b854d006ac61ecc727ee/frozenlist-1.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4970ece02dbc8c3a92fcc5228e36a3e933a01a999f7094ff7c23fbd2beeaa67c", size = 49749, upload-time = "2025-10-06T05:37:10.569Z" }, + { url = "https://files.pythonhosted.org/packages/a7/b2/fabede9fafd976b991e9f1b9c8c873ed86f202889b864756f240ce6dd855/frozenlist-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:cba69cb73723c3f329622e34bdbf5ce1f80c21c290ff04256cff1cd3c2036ed2", size = 231298, upload-time = "2025-10-06T05:37:11.993Z" }, + { url = "https://files.pythonhosted.org/packages/3a/3b/d9b1e0b0eed36e70477ffb8360c49c85c8ca8ef9700a4e6711f39a6e8b45/frozenlist-1.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:778a11b15673f6f1df23d9586f83c4846c471a8af693a22e066508b77d201ec8", size = 232015, upload-time = "2025-10-06T05:37:13.194Z" }, + { url = "https://files.pythonhosted.org/packages/dc/94/be719d2766c1138148564a3960fc2c06eb688da592bdc25adcf856101be7/frozenlist-1.8.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686", size = 225038, upload-time = "2025-10-06T05:37:14.577Z" }, + { url = "https://files.pythonhosted.org/packages/e4/09/6712b6c5465f083f52f50cf74167b92d4ea2f50e46a9eea0523d658454ae/frozenlist-1.8.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:97260ff46b207a82a7567b581ab4190bd4dfa09f4db8a8b49d1a958f6aa4940e", size = 240130, upload-time = "2025-10-06T05:37:15.781Z" }, + { url = "https://files.pythonhosted.org/packages/f8/d4/cd065cdcf21550b54f3ce6a22e143ac9e4836ca42a0de1022da8498eac89/frozenlist-1.8.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:54b2077180eb7f83dd52c40b2750d0a9f175e06a42e3213ce047219de902717a", size = 242845, upload-time = "2025-10-06T05:37:17.037Z" }, + { url = "https://files.pythonhosted.org/packages/62/c3/f57a5c8c70cd1ead3d5d5f776f89d33110b1addae0ab010ad774d9a44fb9/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2f05983daecab868a31e1da44462873306d3cbfd76d1f0b5b69c473d21dbb128", size = 229131, upload-time = "2025-10-06T05:37:18.221Z" }, + { url = "https://files.pythonhosted.org/packages/6c/52/232476fe9cb64f0742f3fde2b7d26c1dac18b6d62071c74d4ded55e0ef94/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:33f48f51a446114bc5d251fb2954ab0164d5be02ad3382abcbfe07e2531d650f", size = 240542, upload-time = "2025-10-06T05:37:19.771Z" }, + { url = "https://files.pythonhosted.org/packages/5f/85/07bf3f5d0fb5414aee5f47d33c6f5c77bfe49aac680bfece33d4fdf6a246/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:154e55ec0655291b5dd1b8731c637ecdb50975a2ae70c606d100750a540082f7", size = 237308, upload-time = "2025-10-06T05:37:20.969Z" }, + { url = "https://files.pythonhosted.org/packages/11/99/ae3a33d5befd41ac0ca2cc7fd3aa707c9c324de2e89db0e0f45db9a64c26/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:4314debad13beb564b708b4a496020e5306c7333fa9a3ab90374169a20ffab30", size = 238210, upload-time = "2025-10-06T05:37:22.252Z" }, + { url = "https://files.pythonhosted.org/packages/b2/60/b1d2da22f4970e7a155f0adde9b1435712ece01b3cd45ba63702aea33938/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:073f8bf8becba60aa931eb3bc420b217bb7d5b8f4750e6f8b3be7f3da85d38b7", size = 231972, upload-time = "2025-10-06T05:37:23.5Z" }, + { url = "https://files.pythonhosted.org/packages/3f/ab/945b2f32de889993b9c9133216c068b7fcf257d8595a0ac420ac8677cab0/frozenlist-1.8.0-cp314-cp314-win32.whl", hash = "sha256:bac9c42ba2ac65ddc115d930c78d24ab8d4f465fd3fc473cdedfccadb9429806", size = 40536, upload-time = "2025-10-06T05:37:25.581Z" }, + { url = "https://files.pythonhosted.org/packages/59/ad/9caa9b9c836d9ad6f067157a531ac48b7d36499f5036d4141ce78c230b1b/frozenlist-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:3e0761f4d1a44f1d1a47996511752cf3dcec5bbdd9cc2b4fe595caf97754b7a0", size = 44330, upload-time = "2025-10-06T05:37:26.928Z" }, + { url = "https://files.pythonhosted.org/packages/82/13/e6950121764f2676f43534c555249f57030150260aee9dcf7d64efda11dd/frozenlist-1.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:d1eaff1d00c7751b7c6662e9c5ba6eb2c17a2306ba5e2a37f24ddf3cc953402b", size = 40627, upload-time = "2025-10-06T05:37:28.075Z" }, + { url = "https://files.pythonhosted.org/packages/c0/c7/43200656ecc4e02d3f8bc248df68256cd9572b3f0017f0a0c4e93440ae23/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d3bb933317c52d7ea5004a1c442eef86f426886fba134ef8cf4226ea6ee1821d", size = 89238, upload-time = "2025-10-06T05:37:29.373Z" }, + { url = "https://files.pythonhosted.org/packages/d1/29/55c5f0689b9c0fb765055629f472c0de484dcaf0acee2f7707266ae3583c/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8009897cdef112072f93a0efdce29cd819e717fd2f649ee3016efd3cd885a7ed", size = 50738, upload-time = "2025-10-06T05:37:30.792Z" }, + { url = "https://files.pythonhosted.org/packages/ba/7d/b7282a445956506fa11da8c2db7d276adcbf2b17d8bb8407a47685263f90/frozenlist-1.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2c5dcbbc55383e5883246d11fd179782a9d07a986c40f49abe89ddf865913930", size = 51739, upload-time = "2025-10-06T05:37:32.127Z" }, + { url = "https://files.pythonhosted.org/packages/62/1c/3d8622e60d0b767a5510d1d3cf21065b9db874696a51ea6d7a43180a259c/frozenlist-1.8.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:39ecbc32f1390387d2aa4f5a995e465e9e2f79ba3adcac92d68e3e0afae6657c", size = 284186, upload-time = "2025-10-06T05:37:33.21Z" }, + { url = "https://files.pythonhosted.org/packages/2d/14/aa36d5f85a89679a85a1d44cd7a6657e0b1c75f61e7cad987b203d2daca8/frozenlist-1.8.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92db2bf818d5cc8d9c1f1fc56b897662e24ea5adb36ad1f1d82875bd64e03c24", size = 292196, upload-time = "2025-10-06T05:37:36.107Z" }, + { url = "https://files.pythonhosted.org/packages/05/23/6bde59eb55abd407d34f77d39a5126fb7b4f109a3f611d3929f14b700c66/frozenlist-1.8.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2dc43a022e555de94c3b68a4ef0b11c4f747d12c024a520c7101709a2144fb37", size = 273830, upload-time = "2025-10-06T05:37:37.663Z" }, + { url = "https://files.pythonhosted.org/packages/d2/3f/22cff331bfad7a8afa616289000ba793347fcd7bc275f3b28ecea2a27909/frozenlist-1.8.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb89a7f2de3602cfed448095bab3f178399646ab7c61454315089787df07733a", size = 294289, upload-time = "2025-10-06T05:37:39.261Z" }, + { url = "https://files.pythonhosted.org/packages/a4/89/5b057c799de4838b6c69aa82b79705f2027615e01be996d2486a69ca99c4/frozenlist-1.8.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:33139dc858c580ea50e7e60a1b0ea003efa1fd42e6ec7fdbad78fff65fad2fd2", size = 300318, upload-time = "2025-10-06T05:37:43.213Z" }, + { url = "https://files.pythonhosted.org/packages/30/de/2c22ab3eb2a8af6d69dc799e48455813bab3690c760de58e1bf43b36da3e/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:168c0969a329b416119507ba30b9ea13688fafffac1b7822802537569a1cb0ef", size = 282814, upload-time = "2025-10-06T05:37:45.337Z" }, + { url = "https://files.pythonhosted.org/packages/59/f7/970141a6a8dbd7f556d94977858cfb36fa9b66e0892c6dd780d2219d8cd8/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:28bd570e8e189d7f7b001966435f9dac6718324b5be2990ac496cf1ea9ddb7fe", size = 291762, upload-time = "2025-10-06T05:37:46.657Z" }, + { url = "https://files.pythonhosted.org/packages/c1/15/ca1adae83a719f82df9116d66f5bb28bb95557b3951903d39135620ef157/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b2a095d45c5d46e5e79ba1e5b9cb787f541a8dee0433836cea4b96a2c439dcd8", size = 289470, upload-time = "2025-10-06T05:37:47.946Z" }, + { url = "https://files.pythonhosted.org/packages/ac/83/dca6dc53bf657d371fbc88ddeb21b79891e747189c5de990b9dfff2ccba1/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:eab8145831a0d56ec9c4139b6c3e594c7a83c2c8be25d5bcf2d86136a532287a", size = 289042, upload-time = "2025-10-06T05:37:49.499Z" }, + { url = "https://files.pythonhosted.org/packages/96/52/abddd34ca99be142f354398700536c5bd315880ed0a213812bc491cff5e4/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:974b28cf63cc99dfb2188d8d222bc6843656188164848c4f679e63dae4b0708e", size = 283148, upload-time = "2025-10-06T05:37:50.745Z" }, + { url = "https://files.pythonhosted.org/packages/af/d3/76bd4ed4317e7119c2b7f57c3f6934aba26d277acc6309f873341640e21f/frozenlist-1.8.0-cp314-cp314t-win32.whl", hash = "sha256:342c97bf697ac5480c0a7ec73cd700ecfa5a8a40ac923bd035484616efecc2df", size = 44676, upload-time = "2025-10-06T05:37:52.222Z" }, + { url = "https://files.pythonhosted.org/packages/89/76/c615883b7b521ead2944bb3480398cbb07e12b7b4e4d073d3752eb721558/frozenlist-1.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:06be8f67f39c8b1dc671f5d83aaefd3358ae5cdcf8314552c57e7ed3e6475bdd", size = 49451, upload-time = "2025-10-06T05:37:53.425Z" }, + { url = "https://files.pythonhosted.org/packages/e0/a3/5982da14e113d07b325230f95060e2169f5311b1017ea8af2a29b374c289/frozenlist-1.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:102e6314ca4da683dca92e3b1355490fed5f313b768500084fbe6371fddfdb79", size = 42507, upload-time = "2025-10-06T05:37:54.513Z" }, + { url = "https://files.pythonhosted.org/packages/c2/59/ae5cdac87a00962122ea37bb346d41b66aec05f9ce328fa2b9e216f8967b/frozenlist-1.8.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d8b7138e5cd0647e4523d6685b0eac5d4be9a184ae9634492f25c6eb38c12a47", size = 86967, upload-time = "2025-10-06T05:37:55.607Z" }, + { url = "https://files.pythonhosted.org/packages/8a/10/17059b2db5a032fd9323c41c39e9d1f5f9d0c8f04d1e4e3e788573086e61/frozenlist-1.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a6483e309ca809f1efd154b4d37dc6d9f61037d6c6a81c2dc7a15cb22c8c5dca", size = 49984, upload-time = "2025-10-06T05:37:57.049Z" }, + { url = "https://files.pythonhosted.org/packages/4b/de/ad9d82ca8e5fa8f0c636e64606553c79e2b859ad253030b62a21fe9986f5/frozenlist-1.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1b9290cf81e95e93fdf90548ce9d3c1211cf574b8e3f4b3b7cb0537cf2227068", size = 50240, upload-time = "2025-10-06T05:37:58.145Z" }, + { url = "https://files.pythonhosted.org/packages/4e/45/3dfb7767c2a67d123650122b62ce13c731b6c745bc14424eea67678b508c/frozenlist-1.8.0-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:59a6a5876ca59d1b63af8cd5e7ffffb024c3dc1e9cf9301b21a2e76286505c95", size = 219472, upload-time = "2025-10-06T05:37:59.239Z" }, + { url = "https://files.pythonhosted.org/packages/0b/bf/5bf23d913a741b960d5c1dac7c1985d8a2a1d015772b2d18ea168b08e7ff/frozenlist-1.8.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6dc4126390929823e2d2d9dc79ab4046ed74680360fc5f38b585c12c66cdf459", size = 221531, upload-time = "2025-10-06T05:38:00.521Z" }, + { url = "https://files.pythonhosted.org/packages/d0/03/27ec393f3b55860859f4b74cdc8c2a4af3dbf3533305e8eacf48a4fd9a54/frozenlist-1.8.0-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:332db6b2563333c5671fecacd085141b5800cb866be16d5e3eb15a2086476675", size = 219211, upload-time = "2025-10-06T05:38:01.842Z" }, + { url = "https://files.pythonhosted.org/packages/3a/ad/0fd00c404fa73fe9b169429e9a972d5ed807973c40ab6b3cf9365a33d360/frozenlist-1.8.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9ff15928d62a0b80bb875655c39bf517938c7d589554cbd2669be42d97c2cb61", size = 231775, upload-time = "2025-10-06T05:38:03.384Z" }, + { url = "https://files.pythonhosted.org/packages/8a/c3/86962566154cb4d2995358bc8331bfc4ea19d07db1a96f64935a1607f2b6/frozenlist-1.8.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7bf6cdf8e07c8151fba6fe85735441240ec7f619f935a5205953d58009aef8c6", size = 236631, upload-time = "2025-10-06T05:38:04.609Z" }, + { url = "https://files.pythonhosted.org/packages/ea/9e/6ffad161dbd83782d2c66dc4d378a9103b31770cb1e67febf43aea42d202/frozenlist-1.8.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:48e6d3f4ec5c7273dfe83ff27c91083c6c9065af655dc2684d2c200c94308bb5", size = 218632, upload-time = "2025-10-06T05:38:05.917Z" }, + { url = "https://files.pythonhosted.org/packages/58/b2/4677eee46e0a97f9b30735e6ad0bf6aba3e497986066eb68807ac85cf60f/frozenlist-1.8.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:1a7607e17ad33361677adcd1443edf6f5da0ce5e5377b798fba20fae194825f3", size = 235967, upload-time = "2025-10-06T05:38:07.614Z" }, + { url = "https://files.pythonhosted.org/packages/05/f3/86e75f8639c5a93745ca7addbbc9de6af56aebb930d233512b17e46f6493/frozenlist-1.8.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:5a3a935c3a4e89c733303a2d5a7c257ea44af3a56c8202df486b7f5de40f37e1", size = 228799, upload-time = "2025-10-06T05:38:08.845Z" }, + { url = "https://files.pythonhosted.org/packages/30/00/39aad3a7f0d98f5eb1d99a3c311215674ed87061aecee7851974b335c050/frozenlist-1.8.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:940d4a017dbfed9daf46a3b086e1d2167e7012ee297fef9e1c545c4d022f5178", size = 230566, upload-time = "2025-10-06T05:38:10.52Z" }, + { url = "https://files.pythonhosted.org/packages/0d/4d/aa144cac44568d137846ddc4d5210fb5d9719eb1d7ec6fa2728a54b5b94a/frozenlist-1.8.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b9be22a69a014bc47e78072d0ecae716f5eb56c15238acca0f43d6eb8e4a5bda", size = 217715, upload-time = "2025-10-06T05:38:11.832Z" }, + { url = "https://files.pythonhosted.org/packages/64/4c/8f665921667509d25a0dd72540513bc86b356c95541686f6442a3283019f/frozenlist-1.8.0-cp39-cp39-win32.whl", hash = "sha256:1aa77cb5697069af47472e39612976ed05343ff2e84a3dcf15437b232cbfd087", size = 39933, upload-time = "2025-10-06T05:38:13.061Z" }, + { url = "https://files.pythonhosted.org/packages/79/bd/bcc926f87027fad5e59926ff12d136e1082a115025d33c032d1cd69ab377/frozenlist-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:7398c222d1d405e796970320036b1b563892b65809d9e5261487bb2c7f7b5c6a", size = 44121, upload-time = "2025-10-06T05:38:14.572Z" }, + { url = "https://files.pythonhosted.org/packages/4c/07/9c2e4eb7584af4b705237b971b89a4155a8e57599c4483a131a39256a9a0/frozenlist-1.8.0-cp39-cp39-win_arm64.whl", hash = "sha256:b4f3b365f31c6cd4af24545ca0a244a53688cad8834e32f56831c4923b50a103", size = 40312, upload-time = "2025-10-06T05:38:15.699Z" }, + { url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409, upload-time = "2025-10-06T05:38:16.721Z" }, +] + +[[package]] +name = "h11" +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, +] + +[[package]] +name = "httpcore" +version = "1.0.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, +] + +[[package]] +name = "httpx" +version = "0.28.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, +] + +[[package]] +name = "httpx-aiohttp" +version = "0.1.12" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohttp" }, + { name = "httpx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/63/2c/b894861cecf030fb45675ea24aa55b5722e97c602a163d872fca66c5a6d8/httpx_aiohttp-0.1.12.tar.gz", hash = "sha256:81feec51fd82c0ecfa0e9aaf1b1a6c2591260d5e2bcbeb7eb0277a78e610df2c", size = 275945, upload-time = "2025-12-12T10:12:15.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/16/8d/85c9701e9af72ca132a1783e2a54364a90c6da832304416a30fc11196ab2/httpx_aiohttp-0.1.12-py3-none-any.whl", hash = "sha256:5b0eac39a7f360fa7867a60bcb46bb1024eada9c01cbfecdb54dc1edb3fb7141", size = 6367, upload-time = "2025-12-12T10:12:14.018Z" }, +] + +[[package]] +name = "idna" +version = "3.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, +] + +[[package]] +name = "importlib-metadata" +version = "8.7.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "zipp" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f3/49/3b30cad09e7771a4982d9975a8cbf64f00d4a1ececb53297f1d9a7be1b10/importlib_metadata-8.7.1.tar.gz", hash = "sha256:49fef1ae6440c182052f407c8d34a68f72efc36db9ca90dc0113398f2fdde8bb", size = 57107, upload-time = "2025-12-21T10:00:19.278Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl", hash = "sha256:5a1f80bf1daa489495071efbb095d75a634cf28a8bc299581244063b53176151", size = 27865, upload-time = "2025-12-21T10:00:18.329Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.10'", +] +sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14' and extra != 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2'", + "python_full_version >= '3.10' and python_full_version < '3.14' and extra != 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2'", + "python_full_version >= '3.10' and extra == 'group-11-phoebe-bird-pydantic-v1' and extra != 'group-11-phoebe-bird-pydantic-v2'", + "python_full_version >= '3.10' and extra != 'group-11-phoebe-bird-pydantic-v1' and extra != 'group-11-phoebe-bird-pydantic-v2'", +] +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.10'", +] +dependencies = [ + { name = "mdurl", marker = "python_full_version < '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload-time = "2023-06-03T06:41:14.443Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528, upload-time = "2023-06-03T06:41:11.019Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.0.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14' and extra != 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2'", + "python_full_version >= '3.10' and python_full_version < '3.14' and extra != 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2'", + "python_full_version >= '3.10' and extra == 'group-11-phoebe-bird-pydantic-v1' and extra != 'group-11-phoebe-bird-pydantic-v2'", + "python_full_version >= '3.10' and extra != 'group-11-phoebe-bird-pydantic-v1' and extra != 'group-11-phoebe-bird-pydantic-v2'", +] +dependencies = [ + { name = "mdurl", marker = "python_full_version >= '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "multidict" +version = "6.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.11' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/80/1e/5492c365f222f907de1039b91f922b93fa4f764c713ee858d235495d8f50/multidict-6.7.0.tar.gz", hash = "sha256:c6e99d9a65ca282e578dfea819cfa9c0a62b2499d8677392e09feaf305e9e6f5", size = 101834, upload-time = "2025-10-06T14:52:30.657Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a9/63/7bdd4adc330abcca54c85728db2327130e49e52e8c3ce685cec44e0f2e9f/multidict-6.7.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9f474ad5acda359c8758c8accc22032c6abe6dc87a8be2440d097785e27a9349", size = 77153, upload-time = "2025-10-06T14:48:26.409Z" }, + { url = "https://files.pythonhosted.org/packages/3f/bb/b6c35ff175ed1a3142222b78455ee31be71a8396ed3ab5280fbe3ebe4e85/multidict-6.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4b7a9db5a870f780220e931d0002bbfd88fb53aceb6293251e2c839415c1b20e", size = 44993, upload-time = "2025-10-06T14:48:28.4Z" }, + { url = "https://files.pythonhosted.org/packages/e0/1f/064c77877c5fa6df6d346e68075c0f6998547afe952d6471b4c5f6a7345d/multidict-6.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:03ca744319864e92721195fa28c7a3b2bc7b686246b35e4078c1e4d0eb5466d3", size = 44607, upload-time = "2025-10-06T14:48:29.581Z" }, + { url = "https://files.pythonhosted.org/packages/04/7a/bf6aa92065dd47f287690000b3d7d332edfccb2277634cadf6a810463c6a/multidict-6.7.0-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f0e77e3c0008bc9316e662624535b88d360c3a5d3f81e15cf12c139a75250046", size = 241847, upload-time = "2025-10-06T14:48:32.107Z" }, + { url = "https://files.pythonhosted.org/packages/94/39/297a8de920f76eda343e4ce05f3b489f0ab3f9504f2576dfb37b7c08ca08/multidict-6.7.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:08325c9e5367aa379a3496aa9a022fe8837ff22e00b94db256d3a1378c76ab32", size = 242616, upload-time = "2025-10-06T14:48:34.054Z" }, + { url = "https://files.pythonhosted.org/packages/39/3a/d0eee2898cfd9d654aea6cb8c4addc2f9756e9a7e09391cfe55541f917f7/multidict-6.7.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e2862408c99f84aa571ab462d25236ef9cb12a602ea959ba9c9009a54902fc73", size = 222333, upload-time = "2025-10-06T14:48:35.9Z" }, + { url = "https://files.pythonhosted.org/packages/05/48/3b328851193c7a4240815b71eea165b49248867bbb6153a0aee227a0bb47/multidict-6.7.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4d72a9a2d885f5c208b0cb91ff2ed43636bb7e345ec839ff64708e04f69a13cc", size = 253239, upload-time = "2025-10-06T14:48:37.302Z" }, + { url = "https://files.pythonhosted.org/packages/b1/ca/0706a98c8d126a89245413225ca4a3fefc8435014de309cf8b30acb68841/multidict-6.7.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:478cc36476687bac1514d651cbbaa94b86b0732fb6855c60c673794c7dd2da62", size = 251618, upload-time = "2025-10-06T14:48:38.963Z" }, + { url = "https://files.pythonhosted.org/packages/5e/4f/9c7992f245554d8b173f6f0a048ad24b3e645d883f096857ec2c0822b8bd/multidict-6.7.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6843b28b0364dc605f21481c90fadb5f60d9123b442eb8a726bb74feef588a84", size = 241655, upload-time = "2025-10-06T14:48:40.312Z" }, + { url = "https://files.pythonhosted.org/packages/31/79/26a85991ae67efd1c0b1fc2e0c275b8a6aceeb155a68861f63f87a798f16/multidict-6.7.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23bfeee5316266e5ee2d625df2d2c602b829435fc3a235c2ba2131495706e4a0", size = 239245, upload-time = "2025-10-06T14:48:41.848Z" }, + { url = "https://files.pythonhosted.org/packages/14/1e/75fa96394478930b79d0302eaf9a6c69f34005a1a5251ac8b9c336486ec9/multidict-6.7.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:680878b9f3d45c31e1f730eef731f9b0bc1da456155688c6745ee84eb818e90e", size = 233523, upload-time = "2025-10-06T14:48:43.749Z" }, + { url = "https://files.pythonhosted.org/packages/b2/5e/085544cb9f9c4ad2b5d97467c15f856df8d9bac410cffd5c43991a5d878b/multidict-6.7.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:eb866162ef2f45063acc7a53a88ef6fe8bf121d45c30ea3c9cd87ce7e191a8d4", size = 243129, upload-time = "2025-10-06T14:48:45.225Z" }, + { url = "https://files.pythonhosted.org/packages/b9/c3/e9d9e2f20c9474e7a8fcef28f863c5cbd29bb5adce6b70cebe8bdad0039d/multidict-6.7.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:df0e3bf7993bdbeca5ac25aa859cf40d39019e015c9c91809ba7093967f7a648", size = 248999, upload-time = "2025-10-06T14:48:46.703Z" }, + { url = "https://files.pythonhosted.org/packages/b5/3f/df171b6efa3239ae33b97b887e42671cd1d94d460614bfb2c30ffdab3b95/multidict-6.7.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:661709cdcd919a2ece2234f9bae7174e5220c80b034585d7d8a755632d3e2111", size = 243711, upload-time = "2025-10-06T14:48:48.146Z" }, + { url = "https://files.pythonhosted.org/packages/3c/2f/9b5564888c4e14b9af64c54acf149263721a283aaf4aa0ae89b091d5d8c1/multidict-6.7.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:096f52730c3fb8ed419db2d44391932b63891b2c5ed14850a7e215c0ba9ade36", size = 237504, upload-time = "2025-10-06T14:48:49.447Z" }, + { url = "https://files.pythonhosted.org/packages/6c/3a/0bd6ca0f7d96d790542d591c8c3354c1e1b6bfd2024d4d92dc3d87485ec7/multidict-6.7.0-cp310-cp310-win32.whl", hash = "sha256:afa8a2978ec65d2336305550535c9c4ff50ee527914328c8677b3973ade52b85", size = 41422, upload-time = "2025-10-06T14:48:50.789Z" }, + { url = "https://files.pythonhosted.org/packages/00/35/f6a637ea2c75f0d3b7c7d41b1189189acff0d9deeb8b8f35536bb30f5e33/multidict-6.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:b15b3afff74f707b9275d5ba6a91ae8f6429c3ffb29bbfd216b0b375a56f13d7", size = 46050, upload-time = "2025-10-06T14:48:51.938Z" }, + { url = "https://files.pythonhosted.org/packages/e7/b8/f7bf8329b39893d02d9d95cf610c75885d12fc0f402b1c894e1c8e01c916/multidict-6.7.0-cp310-cp310-win_arm64.whl", hash = "sha256:4b73189894398d59131a66ff157837b1fafea9974be486d036bb3d32331fdbf0", size = 43153, upload-time = "2025-10-06T14:48:53.146Z" }, + { url = "https://files.pythonhosted.org/packages/34/9e/5c727587644d67b2ed479041e4b1c58e30afc011e3d45d25bbe35781217c/multidict-6.7.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4d409aa42a94c0b3fa617708ef5276dfe81012ba6753a0370fcc9d0195d0a1fc", size = 76604, upload-time = "2025-10-06T14:48:54.277Z" }, + { url = "https://files.pythonhosted.org/packages/17/e4/67b5c27bd17c085a5ea8f1ec05b8a3e5cba0ca734bfcad5560fb129e70ca/multidict-6.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:14c9e076eede3b54c636f8ce1c9c252b5f057c62131211f0ceeec273810c9721", size = 44715, upload-time = "2025-10-06T14:48:55.445Z" }, + { url = "https://files.pythonhosted.org/packages/4d/e1/866a5d77be6ea435711bef2a4291eed11032679b6b28b56b4776ab06ba3e/multidict-6.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4c09703000a9d0fa3c3404b27041e574cc7f4df4c6563873246d0e11812a94b6", size = 44332, upload-time = "2025-10-06T14:48:56.706Z" }, + { url = "https://files.pythonhosted.org/packages/31/61/0c2d50241ada71ff61a79518db85ada85fdabfcf395d5968dae1cbda04e5/multidict-6.7.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a265acbb7bb33a3a2d626afbe756371dce0279e7b17f4f4eda406459c2b5ff1c", size = 245212, upload-time = "2025-10-06T14:48:58.042Z" }, + { url = "https://files.pythonhosted.org/packages/ac/e0/919666a4e4b57fff1b57f279be1c9316e6cdc5de8a8b525d76f6598fefc7/multidict-6.7.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:51cb455de290ae462593e5b1cb1118c5c22ea7f0d3620d9940bf695cea5a4bd7", size = 246671, upload-time = "2025-10-06T14:49:00.004Z" }, + { url = "https://files.pythonhosted.org/packages/a1/cc/d027d9c5a520f3321b65adea289b965e7bcbd2c34402663f482648c716ce/multidict-6.7.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:db99677b4457c7a5c5a949353e125ba72d62b35f74e26da141530fbb012218a7", size = 225491, upload-time = "2025-10-06T14:49:01.393Z" }, + { url = "https://files.pythonhosted.org/packages/75/c4/bbd633980ce6155a28ff04e6a6492dd3335858394d7bb752d8b108708558/multidict-6.7.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f470f68adc395e0183b92a2f4689264d1ea4b40504a24d9882c27375e6662bb9", size = 257322, upload-time = "2025-10-06T14:49:02.745Z" }, + { url = "https://files.pythonhosted.org/packages/4c/6d/d622322d344f1f053eae47e033b0b3f965af01212de21b10bcf91be991fb/multidict-6.7.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0db4956f82723cc1c270de9c6e799b4c341d327762ec78ef82bb962f79cc07d8", size = 254694, upload-time = "2025-10-06T14:49:04.15Z" }, + { url = "https://files.pythonhosted.org/packages/a8/9f/78f8761c2705d4c6d7516faed63c0ebdac569f6db1bef95e0d5218fdc146/multidict-6.7.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3e56d780c238f9e1ae66a22d2adf8d16f485381878250db8d496623cd38b22bd", size = 246715, upload-time = "2025-10-06T14:49:05.967Z" }, + { url = "https://files.pythonhosted.org/packages/78/59/950818e04f91b9c2b95aab3d923d9eabd01689d0dcd889563988e9ea0fd8/multidict-6.7.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9d14baca2ee12c1a64740d4531356ba50b82543017f3ad6de0deb943c5979abb", size = 243189, upload-time = "2025-10-06T14:49:07.37Z" }, + { url = "https://files.pythonhosted.org/packages/7a/3d/77c79e1934cad2ee74991840f8a0110966d9599b3af95964c0cd79bb905b/multidict-6.7.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:295a92a76188917c7f99cda95858c822f9e4aae5824246bba9b6b44004ddd0a6", size = 237845, upload-time = "2025-10-06T14:49:08.759Z" }, + { url = "https://files.pythonhosted.org/packages/63/1b/834ce32a0a97a3b70f86437f685f880136677ac00d8bce0027e9fd9c2db7/multidict-6.7.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39f1719f57adbb767ef592a50ae5ebb794220d1188f9ca93de471336401c34d2", size = 246374, upload-time = "2025-10-06T14:49:10.574Z" }, + { url = "https://files.pythonhosted.org/packages/23/ef/43d1c3ba205b5dec93dc97f3fba179dfa47910fc73aaaea4f7ceb41cec2a/multidict-6.7.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:0a13fb8e748dfc94749f622de065dd5c1def7e0d2216dba72b1d8069a389c6ff", size = 253345, upload-time = "2025-10-06T14:49:12.331Z" }, + { url = "https://files.pythonhosted.org/packages/6b/03/eaf95bcc2d19ead522001f6a650ef32811aa9e3624ff0ad37c445c7a588c/multidict-6.7.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e3aa16de190d29a0ea1b48253c57d99a68492c8dd8948638073ab9e74dc9410b", size = 246940, upload-time = "2025-10-06T14:49:13.821Z" }, + { url = "https://files.pythonhosted.org/packages/e8/df/ec8a5fd66ea6cd6f525b1fcbb23511b033c3e9bc42b81384834ffa484a62/multidict-6.7.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a048ce45dcdaaf1defb76b2e684f997fb5abf74437b6cb7b22ddad934a964e34", size = 242229, upload-time = "2025-10-06T14:49:15.603Z" }, + { url = "https://files.pythonhosted.org/packages/8a/a2/59b405d59fd39ec86d1142630e9049243015a5f5291ba49cadf3c090c541/multidict-6.7.0-cp311-cp311-win32.whl", hash = "sha256:a90af66facec4cebe4181b9e62a68be65e45ac9b52b67de9eec118701856e7ff", size = 41308, upload-time = "2025-10-06T14:49:16.871Z" }, + { url = "https://files.pythonhosted.org/packages/32/0f/13228f26f8b882c34da36efa776c3b7348455ec383bab4a66390e42963ae/multidict-6.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:95b5ffa4349df2887518bb839409bcf22caa72d82beec453216802f475b23c81", size = 46037, upload-time = "2025-10-06T14:49:18.457Z" }, + { url = "https://files.pythonhosted.org/packages/84/1f/68588e31b000535a3207fd3c909ebeec4fb36b52c442107499c18a896a2a/multidict-6.7.0-cp311-cp311-win_arm64.whl", hash = "sha256:329aa225b085b6f004a4955271a7ba9f1087e39dcb7e65f6284a988264a63912", size = 43023, upload-time = "2025-10-06T14:49:19.648Z" }, + { url = "https://files.pythonhosted.org/packages/c2/9e/9f61ac18d9c8b475889f32ccfa91c9f59363480613fc807b6e3023d6f60b/multidict-6.7.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8a3862568a36d26e650a19bb5cbbba14b71789032aebc0423f8cc5f150730184", size = 76877, upload-time = "2025-10-06T14:49:20.884Z" }, + { url = "https://files.pythonhosted.org/packages/38/6f/614f09a04e6184f8824268fce4bc925e9849edfa654ddd59f0b64508c595/multidict-6.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:960c60b5849b9b4f9dcc9bea6e3626143c252c74113df2c1540aebce70209b45", size = 45467, upload-time = "2025-10-06T14:49:22.054Z" }, + { url = "https://files.pythonhosted.org/packages/b3/93/c4f67a436dd026f2e780c433277fff72be79152894d9fc36f44569cab1a6/multidict-6.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2049be98fb57a31b4ccf870bf377af2504d4ae35646a19037ec271e4c07998aa", size = 43834, upload-time = "2025-10-06T14:49:23.566Z" }, + { url = "https://files.pythonhosted.org/packages/7f/f5/013798161ca665e4a422afbc5e2d9e4070142a9ff8905e482139cd09e4d0/multidict-6.7.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0934f3843a1860dd465d38895c17fce1f1cb37295149ab05cd1b9a03afacb2a7", size = 250545, upload-time = "2025-10-06T14:49:24.882Z" }, + { url = "https://files.pythonhosted.org/packages/71/2f/91dbac13e0ba94669ea5119ba267c9a832f0cb65419aca75549fcf09a3dc/multidict-6.7.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b3e34f3a1b8131ba06f1a73adab24f30934d148afcd5f5de9a73565a4404384e", size = 258305, upload-time = "2025-10-06T14:49:26.778Z" }, + { url = "https://files.pythonhosted.org/packages/ef/b0/754038b26f6e04488b48ac621f779c341338d78503fb45403755af2df477/multidict-6.7.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:efbb54e98446892590dc2458c19c10344ee9a883a79b5cec4bc34d6656e8d546", size = 242363, upload-time = "2025-10-06T14:49:28.562Z" }, + { url = "https://files.pythonhosted.org/packages/87/15/9da40b9336a7c9fa606c4cf2ed80a649dffeb42b905d4f63a1d7eb17d746/multidict-6.7.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a35c5fc61d4f51eb045061e7967cfe3123d622cd500e8868e7c0c592a09fedc4", size = 268375, upload-time = "2025-10-06T14:49:29.96Z" }, + { url = "https://files.pythonhosted.org/packages/82/72/c53fcade0cc94dfaad583105fd92b3a783af2091eddcb41a6d5a52474000/multidict-6.7.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29fe6740ebccba4175af1b9b87bf553e9c15cd5868ee967e010efcf94e4fd0f1", size = 269346, upload-time = "2025-10-06T14:49:31.404Z" }, + { url = "https://files.pythonhosted.org/packages/0d/e2/9baffdae21a76f77ef8447f1a05a96ec4bc0a24dae08767abc0a2fe680b8/multidict-6.7.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:123e2a72e20537add2f33a79e605f6191fba2afda4cbb876e35c1a7074298a7d", size = 256107, upload-time = "2025-10-06T14:49:32.974Z" }, + { url = "https://files.pythonhosted.org/packages/3c/06/3f06f611087dc60d65ef775f1fb5aca7c6d61c6db4990e7cda0cef9b1651/multidict-6.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b284e319754366c1aee2267a2036248b24eeb17ecd5dc16022095e747f2f4304", size = 253592, upload-time = "2025-10-06T14:49:34.52Z" }, + { url = "https://files.pythonhosted.org/packages/20/24/54e804ec7945b6023b340c412ce9c3f81e91b3bf5fa5ce65558740141bee/multidict-6.7.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:803d685de7be4303b5a657b76e2f6d1240e7e0a8aa2968ad5811fa2285553a12", size = 251024, upload-time = "2025-10-06T14:49:35.956Z" }, + { url = "https://files.pythonhosted.org/packages/14/48/011cba467ea0b17ceb938315d219391d3e421dfd35928e5dbdc3f4ae76ef/multidict-6.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c04a328260dfd5db8c39538f999f02779012268f54614902d0afc775d44e0a62", size = 251484, upload-time = "2025-10-06T14:49:37.631Z" }, + { url = "https://files.pythonhosted.org/packages/0d/2f/919258b43bb35b99fa127435cfb2d91798eb3a943396631ef43e3720dcf4/multidict-6.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8a19cdb57cd3df4cd865849d93ee14920fb97224300c88501f16ecfa2604b4e0", size = 263579, upload-time = "2025-10-06T14:49:39.502Z" }, + { url = "https://files.pythonhosted.org/packages/31/22/a0e884d86b5242b5a74cf08e876bdf299e413016b66e55511f7a804a366e/multidict-6.7.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9b2fd74c52accced7e75de26023b7dccee62511a600e62311b918ec5c168fc2a", size = 259654, upload-time = "2025-10-06T14:49:41.32Z" }, + { url = "https://files.pythonhosted.org/packages/b2/e5/17e10e1b5c5f5a40f2fcbb45953c9b215f8a4098003915e46a93f5fcaa8f/multidict-6.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3e8bfdd0e487acf992407a140d2589fe598238eaeffa3da8448d63a63cd363f8", size = 251511, upload-time = "2025-10-06T14:49:46.021Z" }, + { url = "https://files.pythonhosted.org/packages/e3/9a/201bb1e17e7af53139597069c375e7b0dcbd47594604f65c2d5359508566/multidict-6.7.0-cp312-cp312-win32.whl", hash = "sha256:dd32a49400a2c3d52088e120ee00c1e3576cbff7e10b98467962c74fdb762ed4", size = 41895, upload-time = "2025-10-06T14:49:48.718Z" }, + { url = "https://files.pythonhosted.org/packages/46/e2/348cd32faad84eaf1d20cce80e2bb0ef8d312c55bca1f7fa9865e7770aaf/multidict-6.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:92abb658ef2d7ef22ac9f8bb88e8b6c3e571671534e029359b6d9e845923eb1b", size = 46073, upload-time = "2025-10-06T14:49:50.28Z" }, + { url = "https://files.pythonhosted.org/packages/25/ec/aad2613c1910dce907480e0c3aa306905830f25df2e54ccc9dea450cb5aa/multidict-6.7.0-cp312-cp312-win_arm64.whl", hash = "sha256:490dab541a6a642ce1a9d61a4781656b346a55c13038f0b1244653828e3a83ec", size = 43226, upload-time = "2025-10-06T14:49:52.304Z" }, + { url = "https://files.pythonhosted.org/packages/d2/86/33272a544eeb36d66e4d9a920602d1a2f57d4ebea4ef3cdfe5a912574c95/multidict-6.7.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:bee7c0588aa0076ce77c0ea5d19a68d76ad81fcd9fe8501003b9a24f9d4000f6", size = 76135, upload-time = "2025-10-06T14:49:54.26Z" }, + { url = "https://files.pythonhosted.org/packages/91/1c/eb97db117a1ebe46d457a3d235a7b9d2e6dcab174f42d1b67663dd9e5371/multidict-6.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7ef6b61cad77091056ce0e7ce69814ef72afacb150b7ac6a3e9470def2198159", size = 45117, upload-time = "2025-10-06T14:49:55.82Z" }, + { url = "https://files.pythonhosted.org/packages/f1/d8/6c3442322e41fb1dd4de8bd67bfd11cd72352ac131f6368315617de752f1/multidict-6.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9c0359b1ec12b1d6849c59f9d319610b7f20ef990a6d454ab151aa0e3b9f78ca", size = 43472, upload-time = "2025-10-06T14:49:57.048Z" }, + { url = "https://files.pythonhosted.org/packages/75/3f/e2639e80325af0b6c6febdf8e57cc07043ff15f57fa1ef808f4ccb5ac4cd/multidict-6.7.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cd240939f71c64bd658f186330603aac1a9a81bf6273f523fca63673cb7378a8", size = 249342, upload-time = "2025-10-06T14:49:58.368Z" }, + { url = "https://files.pythonhosted.org/packages/5d/cc/84e0585f805cbeaa9cbdaa95f9a3d6aed745b9d25700623ac89a6ecff400/multidict-6.7.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a60a4d75718a5efa473ebd5ab685786ba0c67b8381f781d1be14da49f1a2dc60", size = 257082, upload-time = "2025-10-06T14:49:59.89Z" }, + { url = "https://files.pythonhosted.org/packages/b0/9c/ac851c107c92289acbbf5cfb485694084690c1b17e555f44952c26ddc5bd/multidict-6.7.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53a42d364f323275126aff81fb67c5ca1b7a04fda0546245730a55c8c5f24bc4", size = 240704, upload-time = "2025-10-06T14:50:01.485Z" }, + { url = "https://files.pythonhosted.org/packages/50/cc/5f93e99427248c09da95b62d64b25748a5f5c98c7c2ab09825a1d6af0e15/multidict-6.7.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3b29b980d0ddbecb736735ee5bef69bb2ddca56eff603c86f3f29a1128299b4f", size = 266355, upload-time = "2025-10-06T14:50:02.955Z" }, + { url = "https://files.pythonhosted.org/packages/ec/0c/2ec1d883ceb79c6f7f6d7ad90c919c898f5d1c6ea96d322751420211e072/multidict-6.7.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f8a93b1c0ed2d04b97a5e9336fd2d33371b9a6e29ab7dd6503d63407c20ffbaf", size = 267259, upload-time = "2025-10-06T14:50:04.446Z" }, + { url = "https://files.pythonhosted.org/packages/c6/2d/f0b184fa88d6630aa267680bdb8623fb69cb0d024b8c6f0d23f9a0f406d3/multidict-6.7.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9ff96e8815eecacc6645da76c413eb3b3d34cfca256c70b16b286a687d013c32", size = 254903, upload-time = "2025-10-06T14:50:05.98Z" }, + { url = "https://files.pythonhosted.org/packages/06/c9/11ea263ad0df7dfabcad404feb3c0dd40b131bc7f232d5537f2fb1356951/multidict-6.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7516c579652f6a6be0e266aec0acd0db80829ca305c3d771ed898538804c2036", size = 252365, upload-time = "2025-10-06T14:50:07.511Z" }, + { url = "https://files.pythonhosted.org/packages/41/88/d714b86ee2c17d6e09850c70c9d310abac3d808ab49dfa16b43aba9d53fd/multidict-6.7.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:040f393368e63fb0f3330e70c26bfd336656bed925e5cbe17c9da839a6ab13ec", size = 250062, upload-time = "2025-10-06T14:50:09.074Z" }, + { url = "https://files.pythonhosted.org/packages/15/fe/ad407bb9e818c2b31383f6131ca19ea7e35ce93cf1310fce69f12e89de75/multidict-6.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b3bc26a951007b1057a1c543af845f1c7e3e71cc240ed1ace7bf4484aa99196e", size = 249683, upload-time = "2025-10-06T14:50:10.714Z" }, + { url = "https://files.pythonhosted.org/packages/8c/a4/a89abdb0229e533fb925e7c6e5c40201c2873efebc9abaf14046a4536ee6/multidict-6.7.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7b022717c748dd1992a83e219587aabe45980d88969f01b316e78683e6285f64", size = 261254, upload-time = "2025-10-06T14:50:12.28Z" }, + { url = "https://files.pythonhosted.org/packages/8d/aa/0e2b27bd88b40a4fb8dc53dd74eecac70edaa4c1dd0707eb2164da3675b3/multidict-6.7.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:9600082733859f00d79dee64effc7aef1beb26adb297416a4ad2116fd61374bd", size = 257967, upload-time = "2025-10-06T14:50:14.16Z" }, + { url = "https://files.pythonhosted.org/packages/d0/8e/0c67b7120d5d5f6d874ed85a085f9dc770a7f9d8813e80f44a9fec820bb7/multidict-6.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:94218fcec4d72bc61df51c198d098ce2b378e0ccbac41ddbed5ef44092913288", size = 250085, upload-time = "2025-10-06T14:50:15.639Z" }, + { url = "https://files.pythonhosted.org/packages/ba/55/b73e1d624ea4b8fd4dd07a3bb70f6e4c7c6c5d9d640a41c6ffe5cdbd2a55/multidict-6.7.0-cp313-cp313-win32.whl", hash = "sha256:a37bd74c3fa9d00be2d7b8eca074dc56bd8077ddd2917a839bd989612671ed17", size = 41713, upload-time = "2025-10-06T14:50:17.066Z" }, + { url = "https://files.pythonhosted.org/packages/32/31/75c59e7d3b4205075b4c183fa4ca398a2daf2303ddf616b04ae6ef55cffe/multidict-6.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:30d193c6cc6d559db42b6bcec8a5d395d34d60c9877a0b71ecd7c204fcf15390", size = 45915, upload-time = "2025-10-06T14:50:18.264Z" }, + { url = "https://files.pythonhosted.org/packages/31/2a/8987831e811f1184c22bc2e45844934385363ee61c0a2dcfa8f71b87e608/multidict-6.7.0-cp313-cp313-win_arm64.whl", hash = "sha256:ea3334cabe4d41b7ccd01e4d349828678794edbc2d3ae97fc162a3312095092e", size = 43077, upload-time = "2025-10-06T14:50:19.853Z" }, + { url = "https://files.pythonhosted.org/packages/e8/68/7b3a5170a382a340147337b300b9eb25a9ddb573bcdfff19c0fa3f31ffba/multidict-6.7.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:ad9ce259f50abd98a1ca0aa6e490b58c316a0fce0617f609723e40804add2c00", size = 83114, upload-time = "2025-10-06T14:50:21.223Z" }, + { url = "https://files.pythonhosted.org/packages/55/5c/3fa2d07c84df4e302060f555bbf539310980362236ad49f50eeb0a1c1eb9/multidict-6.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07f5594ac6d084cbb5de2df218d78baf55ef150b91f0ff8a21cc7a2e3a5a58eb", size = 48442, upload-time = "2025-10-06T14:50:22.871Z" }, + { url = "https://files.pythonhosted.org/packages/fc/56/67212d33239797f9bd91962bb899d72bb0f4c35a8652dcdb8ed049bef878/multidict-6.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0591b48acf279821a579282444814a2d8d0af624ae0bc600aa4d1b920b6e924b", size = 46885, upload-time = "2025-10-06T14:50:24.258Z" }, + { url = "https://files.pythonhosted.org/packages/46/d1/908f896224290350721597a61a69cd19b89ad8ee0ae1f38b3f5cd12ea2ac/multidict-6.7.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:749a72584761531d2b9467cfbdfd29487ee21124c304c4b6cb760d8777b27f9c", size = 242588, upload-time = "2025-10-06T14:50:25.716Z" }, + { url = "https://files.pythonhosted.org/packages/ab/67/8604288bbd68680eee0ab568fdcb56171d8b23a01bcd5cb0c8fedf6e5d99/multidict-6.7.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b4c3d199f953acd5b446bf7c0de1fe25d94e09e79086f8dc2f48a11a129cdf1", size = 249966, upload-time = "2025-10-06T14:50:28.192Z" }, + { url = "https://files.pythonhosted.org/packages/20/33/9228d76339f1ba51e3efef7da3ebd91964d3006217aae13211653193c3ff/multidict-6.7.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9fb0211dfc3b51efea2f349ec92c114d7754dd62c01f81c3e32b765b70c45c9b", size = 228618, upload-time = "2025-10-06T14:50:29.82Z" }, + { url = "https://files.pythonhosted.org/packages/f8/2d/25d9b566d10cab1c42b3b9e5b11ef79c9111eaf4463b8c257a3bd89e0ead/multidict-6.7.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a027ec240fe73a8d6281872690b988eed307cd7d91b23998ff35ff577ca688b5", size = 257539, upload-time = "2025-10-06T14:50:31.731Z" }, + { url = "https://files.pythonhosted.org/packages/b6/b1/8d1a965e6637fc33de3c0d8f414485c2b7e4af00f42cab3d84e7b955c222/multidict-6.7.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1d964afecdf3a8288789df2f5751dc0a8261138c3768d9af117ed384e538fad", size = 256345, upload-time = "2025-10-06T14:50:33.26Z" }, + { url = "https://files.pythonhosted.org/packages/ba/0c/06b5a8adbdeedada6f4fb8d8f193d44a347223b11939b42953eeb6530b6b/multidict-6.7.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:caf53b15b1b7df9fbd0709aa01409000a2b4dd03a5f6f5cc548183c7c8f8b63c", size = 247934, upload-time = "2025-10-06T14:50:34.808Z" }, + { url = "https://files.pythonhosted.org/packages/8f/31/b2491b5fe167ca044c6eb4b8f2c9f3b8a00b24c432c365358eadac5d7625/multidict-6.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:654030da3197d927f05a536a66186070e98765aa5142794c9904555d3a9d8fb5", size = 245243, upload-time = "2025-10-06T14:50:36.436Z" }, + { url = "https://files.pythonhosted.org/packages/61/1a/982913957cb90406c8c94f53001abd9eafc271cb3e70ff6371590bec478e/multidict-6.7.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:2090d3718829d1e484706a2f525e50c892237b2bf9b17a79b059cb98cddc2f10", size = 235878, upload-time = "2025-10-06T14:50:37.953Z" }, + { url = "https://files.pythonhosted.org/packages/be/c0/21435d804c1a1cf7a2608593f4d19bca5bcbd7a81a70b253fdd1c12af9c0/multidict-6.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:2d2cfeec3f6f45651b3d408c4acec0ebf3daa9bc8a112a084206f5db5d05b754", size = 243452, upload-time = "2025-10-06T14:50:39.574Z" }, + { url = "https://files.pythonhosted.org/packages/54/0a/4349d540d4a883863191be6eb9a928846d4ec0ea007d3dcd36323bb058ac/multidict-6.7.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:4ef089f985b8c194d341eb2c24ae6e7408c9a0e2e5658699c92f497437d88c3c", size = 252312, upload-time = "2025-10-06T14:50:41.612Z" }, + { url = "https://files.pythonhosted.org/packages/26/64/d5416038dbda1488daf16b676e4dbfd9674dde10a0cc8f4fc2b502d8125d/multidict-6.7.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e93a0617cd16998784bf4414c7e40f17a35d2350e5c6f0bd900d3a8e02bd3762", size = 246935, upload-time = "2025-10-06T14:50:43.972Z" }, + { url = "https://files.pythonhosted.org/packages/9f/8c/8290c50d14e49f35e0bd4abc25e1bc7711149ca9588ab7d04f886cdf03d9/multidict-6.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f0feece2ef8ebc42ed9e2e8c78fc4aa3cf455733b507c09ef7406364c94376c6", size = 243385, upload-time = "2025-10-06T14:50:45.648Z" }, + { url = "https://files.pythonhosted.org/packages/ef/a0/f83ae75e42d694b3fbad3e047670e511c138be747bc713cf1b10d5096416/multidict-6.7.0-cp313-cp313t-win32.whl", hash = "sha256:19a1d55338ec1be74ef62440ca9e04a2f001a04d0cc49a4983dc320ff0f3212d", size = 47777, upload-time = "2025-10-06T14:50:47.154Z" }, + { url = "https://files.pythonhosted.org/packages/dc/80/9b174a92814a3830b7357307a792300f42c9e94664b01dee8e457551fa66/multidict-6.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3da4fb467498df97e986af166b12d01f05d2e04f978a9c1c680ea1988e0bc4b6", size = 53104, upload-time = "2025-10-06T14:50:48.851Z" }, + { url = "https://files.pythonhosted.org/packages/cc/28/04baeaf0428d95bb7a7bea0e691ba2f31394338ba424fb0679a9ed0f4c09/multidict-6.7.0-cp313-cp313t-win_arm64.whl", hash = "sha256:b4121773c49a0776461f4a904cdf6264c88e42218aaa8407e803ca8025872792", size = 45503, upload-time = "2025-10-06T14:50:50.16Z" }, + { url = "https://files.pythonhosted.org/packages/e2/b1/3da6934455dd4b261d4c72f897e3a5728eba81db59959f3a639245891baa/multidict-6.7.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3bab1e4aff7adaa34410f93b1f8e57c4b36b9af0426a76003f441ee1d3c7e842", size = 75128, upload-time = "2025-10-06T14:50:51.92Z" }, + { url = "https://files.pythonhosted.org/packages/14/2c/f069cab5b51d175a1a2cb4ccdf7a2c2dabd58aa5bd933fa036a8d15e2404/multidict-6.7.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b8512bac933afc3e45fb2b18da8e59b78d4f408399a960339598374d4ae3b56b", size = 44410, upload-time = "2025-10-06T14:50:53.275Z" }, + { url = "https://files.pythonhosted.org/packages/42/e2/64bb41266427af6642b6b128e8774ed84c11b80a90702c13ac0a86bb10cc/multidict-6.7.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:79dcf9e477bc65414ebfea98ffd013cb39552b5ecd62908752e0e413d6d06e38", size = 43205, upload-time = "2025-10-06T14:50:54.911Z" }, + { url = "https://files.pythonhosted.org/packages/02/68/6b086fef8a3f1a8541b9236c594f0c9245617c29841f2e0395d979485cde/multidict-6.7.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:31bae522710064b5cbeddaf2e9f32b1abab70ac6ac91d42572502299e9953128", size = 245084, upload-time = "2025-10-06T14:50:56.369Z" }, + { url = "https://files.pythonhosted.org/packages/15/ee/f524093232007cd7a75c1d132df70f235cfd590a7c9eaccd7ff422ef4ae8/multidict-6.7.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a0df7ff02397bb63e2fd22af2c87dfa39e8c7f12947bc524dbdc528282c7e34", size = 252667, upload-time = "2025-10-06T14:50:57.991Z" }, + { url = "https://files.pythonhosted.org/packages/02/a5/eeb3f43ab45878f1895118c3ef157a480db58ede3f248e29b5354139c2c9/multidict-6.7.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7a0222514e8e4c514660e182d5156a415c13ef0aabbd71682fc714e327b95e99", size = 233590, upload-time = "2025-10-06T14:50:59.589Z" }, + { url = "https://files.pythonhosted.org/packages/6a/1e/76d02f8270b97269d7e3dbd45644b1785bda457b474315f8cf999525a193/multidict-6.7.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2397ab4daaf2698eb51a76721e98db21ce4f52339e535725de03ea962b5a3202", size = 264112, upload-time = "2025-10-06T14:51:01.183Z" }, + { url = "https://files.pythonhosted.org/packages/76/0b/c28a70ecb58963847c2a8efe334904cd254812b10e535aefb3bcce513918/multidict-6.7.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8891681594162635948a636c9fe0ff21746aeb3dd5463f6e25d9bea3a8a39ca1", size = 261194, upload-time = "2025-10-06T14:51:02.794Z" }, + { url = "https://files.pythonhosted.org/packages/b4/63/2ab26e4209773223159b83aa32721b4021ffb08102f8ac7d689c943fded1/multidict-6.7.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18706cc31dbf402a7945916dd5cddf160251b6dab8a2c5f3d6d5a55949f676b3", size = 248510, upload-time = "2025-10-06T14:51:04.724Z" }, + { url = "https://files.pythonhosted.org/packages/93/cd/06c1fa8282af1d1c46fd55c10a7930af652afdce43999501d4d68664170c/multidict-6.7.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f844a1bbf1d207dd311a56f383f7eda2d0e134921d45751842d8235e7778965d", size = 248395, upload-time = "2025-10-06T14:51:06.306Z" }, + { url = "https://files.pythonhosted.org/packages/99/ac/82cb419dd6b04ccf9e7e61befc00c77614fc8134362488b553402ecd55ce/multidict-6.7.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:d4393e3581e84e5645506923816b9cc81f5609a778c7e7534054091acc64d1c6", size = 239520, upload-time = "2025-10-06T14:51:08.091Z" }, + { url = "https://files.pythonhosted.org/packages/fa/f3/a0f9bf09493421bd8716a362e0cd1d244f5a6550f5beffdd6b47e885b331/multidict-6.7.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:fbd18dc82d7bf274b37aa48d664534330af744e03bccf696d6f4c6042e7d19e7", size = 245479, upload-time = "2025-10-06T14:51:10.365Z" }, + { url = "https://files.pythonhosted.org/packages/8d/01/476d38fc73a212843f43c852b0eee266b6971f0e28329c2184a8df90c376/multidict-6.7.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:b6234e14f9314731ec45c42fc4554b88133ad53a09092cc48a88e771c125dadb", size = 258903, upload-time = "2025-10-06T14:51:12.466Z" }, + { url = "https://files.pythonhosted.org/packages/49/6d/23faeb0868adba613b817d0e69c5f15531b24d462af8012c4f6de4fa8dc3/multidict-6.7.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:08d4379f9744d8f78d98c8673c06e202ffa88296f009c71bbafe8a6bf847d01f", size = 252333, upload-time = "2025-10-06T14:51:14.48Z" }, + { url = "https://files.pythonhosted.org/packages/1e/cc/48d02ac22b30fa247f7dad82866e4b1015431092f4ba6ebc7e77596e0b18/multidict-6.7.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9fe04da3f79387f450fd0061d4dd2e45a72749d31bf634aecc9e27f24fdc4b3f", size = 243411, upload-time = "2025-10-06T14:51:16.072Z" }, + { url = "https://files.pythonhosted.org/packages/4a/03/29a8bf5a18abf1fe34535c88adbdfa88c9fb869b5a3b120692c64abe8284/multidict-6.7.0-cp314-cp314-win32.whl", hash = "sha256:fbafe31d191dfa7c4c51f7a6149c9fb7e914dcf9ffead27dcfd9f1ae382b3885", size = 40940, upload-time = "2025-10-06T14:51:17.544Z" }, + { url = "https://files.pythonhosted.org/packages/82/16/7ed27b680791b939de138f906d5cf2b4657b0d45ca6f5dd6236fdddafb1a/multidict-6.7.0-cp314-cp314-win_amd64.whl", hash = "sha256:2f67396ec0310764b9222a1728ced1ab638f61aadc6226f17a71dd9324f9a99c", size = 45087, upload-time = "2025-10-06T14:51:18.875Z" }, + { url = "https://files.pythonhosted.org/packages/cd/3c/e3e62eb35a1950292fe39315d3c89941e30a9d07d5d2df42965ab041da43/multidict-6.7.0-cp314-cp314-win_arm64.whl", hash = "sha256:ba672b26069957ee369cfa7fc180dde1fc6f176eaf1e6beaf61fbebbd3d9c000", size = 42368, upload-time = "2025-10-06T14:51:20.225Z" }, + { url = "https://files.pythonhosted.org/packages/8b/40/cd499bd0dbc5f1136726db3153042a735fffd0d77268e2ee20d5f33c010f/multidict-6.7.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:c1dcc7524066fa918c6a27d61444d4ee7900ec635779058571f70d042d86ed63", size = 82326, upload-time = "2025-10-06T14:51:21.588Z" }, + { url = "https://files.pythonhosted.org/packages/13/8a/18e031eca251c8df76daf0288e6790561806e439f5ce99a170b4af30676b/multidict-6.7.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:27e0b36c2d388dc7b6ced3406671b401e84ad7eb0656b8f3a2f46ed0ce483718", size = 48065, upload-time = "2025-10-06T14:51:22.93Z" }, + { url = "https://files.pythonhosted.org/packages/40/71/5e6701277470a87d234e433fb0a3a7deaf3bcd92566e421e7ae9776319de/multidict-6.7.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2a7baa46a22e77f0988e3b23d4ede5513ebec1929e34ee9495be535662c0dfe2", size = 46475, upload-time = "2025-10-06T14:51:24.352Z" }, + { url = "https://files.pythonhosted.org/packages/fe/6a/bab00cbab6d9cfb57afe1663318f72ec28289ea03fd4e8236bb78429893a/multidict-6.7.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7bf77f54997a9166a2f5675d1201520586439424c2511723a7312bdb4bcc034e", size = 239324, upload-time = "2025-10-06T14:51:25.822Z" }, + { url = "https://files.pythonhosted.org/packages/2a/5f/8de95f629fc22a7769ade8b41028e3e5a822c1f8904f618d175945a81ad3/multidict-6.7.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e011555abada53f1578d63389610ac8a5400fc70ce71156b0aa30d326f1a5064", size = 246877, upload-time = "2025-10-06T14:51:27.604Z" }, + { url = "https://files.pythonhosted.org/packages/23/b4/38881a960458f25b89e9f4a4fdcb02ac101cfa710190db6e5528841e67de/multidict-6.7.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:28b37063541b897fd6a318007373930a75ca6d6ac7c940dbe14731ffdd8d498e", size = 225824, upload-time = "2025-10-06T14:51:29.664Z" }, + { url = "https://files.pythonhosted.org/packages/1e/39/6566210c83f8a261575f18e7144736059f0c460b362e96e9cf797a24b8e7/multidict-6.7.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:05047ada7a2fde2631a0ed706f1fd68b169a681dfe5e4cf0f8e4cb6618bbc2cd", size = 253558, upload-time = "2025-10-06T14:51:31.684Z" }, + { url = "https://files.pythonhosted.org/packages/00/a3/67f18315100f64c269f46e6c0319fa87ba68f0f64f2b8e7fd7c72b913a0b/multidict-6.7.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:716133f7d1d946a4e1b91b1756b23c088881e70ff180c24e864c26192ad7534a", size = 252339, upload-time = "2025-10-06T14:51:33.699Z" }, + { url = "https://files.pythonhosted.org/packages/c8/2a/1cb77266afee2458d82f50da41beba02159b1d6b1f7973afc9a1cad1499b/multidict-6.7.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d1bed1b467ef657f2a0ae62844a607909ef1c6889562de5e1d505f74457d0b96", size = 244895, upload-time = "2025-10-06T14:51:36.189Z" }, + { url = "https://files.pythonhosted.org/packages/dd/72/09fa7dd487f119b2eb9524946ddd36e2067c08510576d43ff68469563b3b/multidict-6.7.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ca43bdfa5d37bd6aee89d85e1d0831fb86e25541be7e9d376ead1b28974f8e5e", size = 241862, upload-time = "2025-10-06T14:51:41.291Z" }, + { url = "https://files.pythonhosted.org/packages/65/92/bc1f8bd0853d8669300f732c801974dfc3702c3eeadae2f60cef54dc69d7/multidict-6.7.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:44b546bd3eb645fd26fb949e43c02a25a2e632e2ca21a35e2e132c8105dc8599", size = 232376, upload-time = "2025-10-06T14:51:43.55Z" }, + { url = "https://files.pythonhosted.org/packages/09/86/ac39399e5cb9d0c2ac8ef6e10a768e4d3bc933ac808d49c41f9dc23337eb/multidict-6.7.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:a6ef16328011d3f468e7ebc326f24c1445f001ca1dec335b2f8e66bed3006394", size = 240272, upload-time = "2025-10-06T14:51:45.265Z" }, + { url = "https://files.pythonhosted.org/packages/3d/b6/fed5ac6b8563ec72df6cb1ea8dac6d17f0a4a1f65045f66b6d3bf1497c02/multidict-6.7.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:5aa873cbc8e593d361ae65c68f85faadd755c3295ea2c12040ee146802f23b38", size = 248774, upload-time = "2025-10-06T14:51:46.836Z" }, + { url = "https://files.pythonhosted.org/packages/6b/8d/b954d8c0dc132b68f760aefd45870978deec6818897389dace00fcde32ff/multidict-6.7.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:3d7b6ccce016e29df4b7ca819659f516f0bc7a4b3efa3bb2012ba06431b044f9", size = 242731, upload-time = "2025-10-06T14:51:48.541Z" }, + { url = "https://files.pythonhosted.org/packages/16/9d/a2dac7009125d3540c2f54e194829ea18ac53716c61b655d8ed300120b0f/multidict-6.7.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:171b73bd4ee683d307599b66793ac80981b06f069b62eea1c9e29c9241aa66b0", size = 240193, upload-time = "2025-10-06T14:51:50.355Z" }, + { url = "https://files.pythonhosted.org/packages/39/ca/c05f144128ea232ae2178b008d5011d4e2cea86e4ee8c85c2631b1b94802/multidict-6.7.0-cp314-cp314t-win32.whl", hash = "sha256:b2d7f80c4e1fd010b07cb26820aae86b7e73b681ee4889684fb8d2d4537aab13", size = 48023, upload-time = "2025-10-06T14:51:51.883Z" }, + { url = "https://files.pythonhosted.org/packages/ba/8f/0a60e501584145588be1af5cc829265701ba3c35a64aec8e07cbb71d39bb/multidict-6.7.0-cp314-cp314t-win_amd64.whl", hash = "sha256:09929cab6fcb68122776d575e03c6cc64ee0b8fca48d17e135474b042ce515cd", size = 53507, upload-time = "2025-10-06T14:51:53.672Z" }, + { url = "https://files.pythonhosted.org/packages/7f/ae/3148b988a9c6239903e786eac19c889fab607c31d6efa7fb2147e5680f23/multidict-6.7.0-cp314-cp314t-win_arm64.whl", hash = "sha256:cc41db090ed742f32bd2d2c721861725e6109681eddf835d0a82bd3a5c382827", size = 44804, upload-time = "2025-10-06T14:51:55.415Z" }, + { url = "https://files.pythonhosted.org/packages/90/d7/4cf84257902265c4250769ac49f4eaab81c182ee9aff8bf59d2714dbb174/multidict-6.7.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:363eb68a0a59bd2303216d2346e6c441ba10d36d1f9969fcb6f1ba700de7bb5c", size = 77073, upload-time = "2025-10-06T14:51:57.386Z" }, + { url = "https://files.pythonhosted.org/packages/6d/51/194e999630a656e76c2965a1590d12faa5cd528170f2abaa04423e09fe8d/multidict-6.7.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d874eb056410ca05fed180b6642e680373688efafc7f077b2a2f61811e873a40", size = 44928, upload-time = "2025-10-06T14:51:58.791Z" }, + { url = "https://files.pythonhosted.org/packages/e5/6b/2a195373c33068c9158e0941d0b46cfcc9c1d894ca2eb137d1128081dff0/multidict-6.7.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8b55d5497b51afdfde55925e04a022f1de14d4f4f25cdfd4f5d9b0aa96166851", size = 44581, upload-time = "2025-10-06T14:52:00.174Z" }, + { url = "https://files.pythonhosted.org/packages/69/7b/7f4f2e644b6978bf011a5fd9a5ebb7c21de3f38523b1f7897d36a1ac1311/multidict-6.7.0-cp39-cp39-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f8e5c0031b90ca9ce555e2e8fd5c3b02a25f14989cbc310701823832c99eb687", size = 239901, upload-time = "2025-10-06T14:52:02.416Z" }, + { url = "https://files.pythonhosted.org/packages/3c/b5/952c72786710a031aa204a9adf7db66d7f97a2c6573889d58b9e60fe6702/multidict-6.7.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cf41880c991716f3c7cec48e2f19ae4045fc9db5fc9cff27347ada24d710bb5", size = 240534, upload-time = "2025-10-06T14:52:04.105Z" }, + { url = "https://files.pythonhosted.org/packages/f3/ef/109fe1f2471e4c458c74242c7e4a833f2d9fc8a6813cd7ee345b0bad18f9/multidict-6.7.0-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8cfc12a8630a29d601f48d47787bd7eb730e475e83edb5d6c5084317463373eb", size = 219545, upload-time = "2025-10-06T14:52:06.208Z" }, + { url = "https://files.pythonhosted.org/packages/42/bd/327d91288114967f9fe90dc53de70aa3fec1b9073e46aa32c4828f771a87/multidict-6.7.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3996b50c3237c4aec17459217c1e7bbdead9a22a0fcd3c365564fbd16439dde6", size = 251187, upload-time = "2025-10-06T14:52:08.049Z" }, + { url = "https://files.pythonhosted.org/packages/f4/13/a8b078ebbaceb7819fd28cd004413c33b98f1b70d542a62e6a00b74fb09f/multidict-6.7.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7f5170993a0dd3ab871c74f45c0a21a4e2c37a2f2b01b5f722a2ad9c6650469e", size = 249379, upload-time = "2025-10-06T14:52:09.831Z" }, + { url = "https://files.pythonhosted.org/packages/e3/6d/ab12e1246be4d65d1f55de1e6f6aaa9b8120eddcfdd1d290439c7833d5ce/multidict-6.7.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ec81878ddf0e98817def1e77d4f50dae5ef5b0e4fe796fae3bd674304172416e", size = 239241, upload-time = "2025-10-06T14:52:11.561Z" }, + { url = "https://files.pythonhosted.org/packages/bb/d7/079a93625208c173b8fa756396814397c0fd9fee61ef87b75a748820b86e/multidict-6.7.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:9281bf5b34f59afbc6b1e477a372e9526b66ca446f4bf62592839c195a718b32", size = 237418, upload-time = "2025-10-06T14:52:13.671Z" }, + { url = "https://files.pythonhosted.org/packages/c9/29/03777c2212274aa9440918d604dc9d6af0e6b4558c611c32c3dcf1a13870/multidict-6.7.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:68af405971779d8b37198726f2b6fe3955db846fee42db7a4286fc542203934c", size = 232987, upload-time = "2025-10-06T14:52:15.708Z" }, + { url = "https://files.pythonhosted.org/packages/d9/00/11188b68d85a84e8050ee34724d6ded19ad03975caebe0c8dcb2829b37bf/multidict-6.7.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3ba3ef510467abb0667421a286dc906e30eb08569365f5cdb131d7aff7c2dd84", size = 240985, upload-time = "2025-10-06T14:52:17.317Z" }, + { url = "https://files.pythonhosted.org/packages/df/0c/12eef6aeda21859c6cdf7d75bd5516d83be3efe3d8cc45fd1a3037f5b9dc/multidict-6.7.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:b61189b29081a20c7e4e0b49b44d5d44bb0dc92be3c6d06a11cc043f81bf9329", size = 246855, upload-time = "2025-10-06T14:52:19.096Z" }, + { url = "https://files.pythonhosted.org/packages/69/f6/076120fd8bb3975f09228e288e08bff6b9f1bfd5166397c7ba284f622ab2/multidict-6.7.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:fb287618b9c7aa3bf8d825f02d9201b2f13078a5ed3b293c8f4d953917d84d5e", size = 241804, upload-time = "2025-10-06T14:52:21.166Z" }, + { url = "https://files.pythonhosted.org/packages/5f/51/41bb950c81437b88a93e6ddfca1d8763569ae861e638442838c4375f7497/multidict-6.7.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:521f33e377ff64b96c4c556b81c55d0cfffb96a11c194fd0c3f1e56f3d8dd5a4", size = 235321, upload-time = "2025-10-06T14:52:23.208Z" }, + { url = "https://files.pythonhosted.org/packages/5a/cf/5bbd31f055199d56c1f6b04bbadad3ccb24e6d5d4db75db774fc6d6674b8/multidict-6.7.0-cp39-cp39-win32.whl", hash = "sha256:ce8fdc2dca699f8dbf055a61d73eaa10482569ad20ee3c36ef9641f69afa8c91", size = 41435, upload-time = "2025-10-06T14:52:24.735Z" }, + { url = "https://files.pythonhosted.org/packages/af/01/547ffe9c2faec91c26965c152f3fea6cff068b6037401f61d310cc861ff4/multidict-6.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:7e73299c99939f089dd9b2120a04a516b95cdf8c1cd2b18c53ebf0de80b1f18f", size = 46193, upload-time = "2025-10-06T14:52:26.101Z" }, + { url = "https://files.pythonhosted.org/packages/27/77/cfa5461d1d2651d6fc24216c92b4a21d4e385a41c46e0d9f3b070675167b/multidict-6.7.0-cp39-cp39-win_arm64.whl", hash = "sha256:6bdce131e14b04fd34a809b6380dbfd826065c3e2fe8a50dbae659fa0c390546", size = 43118, upload-time = "2025-10-06T14:52:27.876Z" }, + { url = "https://files.pythonhosted.org/packages/b7/da/7d22601b625e241d4f23ef1ebff8acfc60da633c9e7e7922e24d10f592b3/multidict-6.7.0-py3-none-any.whl", hash = "sha256:394fc5c42a333c9ffc3e421a4c85e08580d990e08b99f6bf35b4132114c5dcb3", size = 12317, upload-time = "2025-10-06T14:52:29.272Z" }, +] + +[[package]] +name = "mypy" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mypy-extensions" }, + { name = "pathspec" }, + { name = "tomli", marker = "python_full_version < '3.11' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1e/e3/034322d5a779685218ed69286c32faa505247f1f096251ef66c8fd203b08/mypy-1.17.0.tar.gz", hash = "sha256:e5d7ccc08ba089c06e2f5629c660388ef1fee708444f1dee0b9203fa031dee03", size = 3352114, upload-time = "2025-07-14T20:34:30.181Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/31/e762baa3b73905c856d45ab77b4af850e8159dffffd86a52879539a08c6b/mypy-1.17.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f8e08de6138043108b3b18f09d3f817a4783912e48828ab397ecf183135d84d6", size = 10998313, upload-time = "2025-07-14T20:33:24.519Z" }, + { url = "https://files.pythonhosted.org/packages/1c/c1/25b2f0d46fb7e0b5e2bee61ec3a47fe13eff9e3c2f2234f144858bbe6485/mypy-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ce4a17920ec144647d448fc43725b5873548b1aae6c603225626747ededf582d", size = 10128922, upload-time = "2025-07-14T20:34:06.414Z" }, + { url = "https://files.pythonhosted.org/packages/02/78/6d646603a57aa8a2886df1b8881fe777ea60f28098790c1089230cd9c61d/mypy-1.17.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6ff25d151cc057fdddb1cb1881ef36e9c41fa2a5e78d8dd71bee6e4dcd2bc05b", size = 11913524, upload-time = "2025-07-14T20:33:19.109Z" }, + { url = "https://files.pythonhosted.org/packages/4f/19/dae6c55e87ee426fb76980f7e78484450cad1c01c55a1dc4e91c930bea01/mypy-1.17.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93468cf29aa9a132bceb103bd8475f78cacde2b1b9a94fd978d50d4bdf616c9a", size = 12650527, upload-time = "2025-07-14T20:32:44.095Z" }, + { url = "https://files.pythonhosted.org/packages/86/e1/f916845a235235a6c1e4d4d065a3930113767001d491b8b2e1b61ca56647/mypy-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:98189382b310f16343151f65dd7e6867386d3e35f7878c45cfa11383d175d91f", size = 12897284, upload-time = "2025-07-14T20:33:38.168Z" }, + { url = "https://files.pythonhosted.org/packages/ae/dc/414760708a4ea1b096bd214d26a24e30ac5e917ef293bc33cdb6fe22d2da/mypy-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:c004135a300ab06a045c1c0d8e3f10215e71d7b4f5bb9a42ab80236364429937", size = 9506493, upload-time = "2025-07-14T20:34:01.093Z" }, + { url = "https://files.pythonhosted.org/packages/d4/24/82efb502b0b0f661c49aa21cfe3e1999ddf64bf5500fc03b5a1536a39d39/mypy-1.17.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9d4fe5c72fd262d9c2c91c1117d16aac555e05f5beb2bae6a755274c6eec42be", size = 10914150, upload-time = "2025-07-14T20:31:51.985Z" }, + { url = "https://files.pythonhosted.org/packages/03/96/8ef9a6ff8cedadff4400e2254689ca1dc4b420b92c55255b44573de10c54/mypy-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d96b196e5c16f41b4f7736840e8455958e832871990c7ba26bf58175e357ed61", size = 10039845, upload-time = "2025-07-14T20:32:30.527Z" }, + { url = "https://files.pythonhosted.org/packages/df/32/7ce359a56be779d38021d07941cfbb099b41411d72d827230a36203dbb81/mypy-1.17.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:73a0ff2dd10337ceb521c080d4147755ee302dcde6e1a913babd59473904615f", size = 11837246, upload-time = "2025-07-14T20:32:01.28Z" }, + { url = "https://files.pythonhosted.org/packages/82/16/b775047054de4d8dbd668df9137707e54b07fe18c7923839cd1e524bf756/mypy-1.17.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:24cfcc1179c4447854e9e406d3af0f77736d631ec87d31c6281ecd5025df625d", size = 12571106, upload-time = "2025-07-14T20:34:26.942Z" }, + { url = "https://files.pythonhosted.org/packages/a1/cf/fa33eaf29a606102c8d9ffa45a386a04c2203d9ad18bf4eef3e20c43ebc8/mypy-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3c56f180ff6430e6373db7a1d569317675b0a451caf5fef6ce4ab365f5f2f6c3", size = 12759960, upload-time = "2025-07-14T20:33:42.882Z" }, + { url = "https://files.pythonhosted.org/packages/94/75/3f5a29209f27e739ca57e6350bc6b783a38c7621bdf9cac3ab8a08665801/mypy-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:eafaf8b9252734400f9b77df98b4eee3d2eecab16104680d51341c75702cad70", size = 9503888, upload-time = "2025-07-14T20:32:34.392Z" }, + { url = "https://files.pythonhosted.org/packages/12/e9/e6824ed620bbf51d3bf4d6cbbe4953e83eaf31a448d1b3cfb3620ccb641c/mypy-1.17.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f986f1cab8dbec39ba6e0eaa42d4d3ac6686516a5d3dccd64be095db05ebc6bb", size = 11086395, upload-time = "2025-07-14T20:34:11.452Z" }, + { url = "https://files.pythonhosted.org/packages/ba/51/a4afd1ae279707953be175d303f04a5a7bd7e28dc62463ad29c1c857927e/mypy-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:51e455a54d199dd6e931cd7ea987d061c2afbaf0960f7f66deef47c90d1b304d", size = 10120052, upload-time = "2025-07-14T20:33:09.897Z" }, + { url = "https://files.pythonhosted.org/packages/8a/71/19adfeac926ba8205f1d1466d0d360d07b46486bf64360c54cb5a2bd86a8/mypy-1.17.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3204d773bab5ff4ebbd1f8efa11b498027cd57017c003ae970f310e5b96be8d8", size = 11861806, upload-time = "2025-07-14T20:32:16.028Z" }, + { url = "https://files.pythonhosted.org/packages/0b/64/d6120eca3835baf7179e6797a0b61d6c47e0bc2324b1f6819d8428d5b9ba/mypy-1.17.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1051df7ec0886fa246a530ae917c473491e9a0ba6938cfd0ec2abc1076495c3e", size = 12744371, upload-time = "2025-07-14T20:33:33.503Z" }, + { url = "https://files.pythonhosted.org/packages/1f/dc/56f53b5255a166f5bd0f137eed960e5065f2744509dfe69474ff0ba772a5/mypy-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f773c6d14dcc108a5b141b4456b0871df638eb411a89cd1c0c001fc4a9d08fc8", size = 12914558, upload-time = "2025-07-14T20:33:56.961Z" }, + { url = "https://files.pythonhosted.org/packages/69/ac/070bad311171badc9add2910e7f89271695a25c136de24bbafc7eded56d5/mypy-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:1619a485fd0e9c959b943c7b519ed26b712de3002d7de43154a489a2d0fd817d", size = 9585447, upload-time = "2025-07-14T20:32:20.594Z" }, + { url = "https://files.pythonhosted.org/packages/be/7b/5f8ab461369b9e62157072156935cec9d272196556bdc7c2ff5f4c7c0f9b/mypy-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2c41aa59211e49d717d92b3bb1238c06d387c9325d3122085113c79118bebb06", size = 11070019, upload-time = "2025-07-14T20:32:07.99Z" }, + { url = "https://files.pythonhosted.org/packages/9c/f8/c49c9e5a2ac0badcc54beb24e774d2499748302c9568f7f09e8730e953fa/mypy-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0e69db1fb65b3114f98c753e3930a00514f5b68794ba80590eb02090d54a5d4a", size = 10114457, upload-time = "2025-07-14T20:33:47.285Z" }, + { url = "https://files.pythonhosted.org/packages/89/0c/fb3f9c939ad9beed3e328008b3fb90b20fda2cddc0f7e4c20dbefefc3b33/mypy-1.17.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:03ba330b76710f83d6ac500053f7727270b6b8553b0423348ffb3af6f2f7b889", size = 11857838, upload-time = "2025-07-14T20:33:14.462Z" }, + { url = "https://files.pythonhosted.org/packages/4c/66/85607ab5137d65e4f54d9797b77d5a038ef34f714929cf8ad30b03f628df/mypy-1.17.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:037bc0f0b124ce46bfde955c647f3e395c6174476a968c0f22c95a8d2f589bba", size = 12731358, upload-time = "2025-07-14T20:32:25.579Z" }, + { url = "https://files.pythonhosted.org/packages/73/d0/341dbbfb35ce53d01f8f2969facbb66486cee9804048bf6c01b048127501/mypy-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c38876106cb6132259683632b287238858bd58de267d80defb6f418e9ee50658", size = 12917480, upload-time = "2025-07-14T20:34:21.868Z" }, + { url = "https://files.pythonhosted.org/packages/64/63/70c8b7dbfc520089ac48d01367a97e8acd734f65bd07813081f508a8c94c/mypy-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:d30ba01c0f151998f367506fab31c2ac4527e6a7b2690107c7a7f9e3cb419a9c", size = 9589666, upload-time = "2025-07-14T20:34:16.841Z" }, + { url = "https://files.pythonhosted.org/packages/9f/a0/6263dd11941231f688f0a8f2faf90ceac1dc243d148d314a089d2fe25108/mypy-1.17.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:63e751f1b5ab51d6f3d219fe3a2fe4523eaa387d854ad06906c63883fde5b1ab", size = 10988185, upload-time = "2025-07-14T20:33:04.797Z" }, + { url = "https://files.pythonhosted.org/packages/02/13/b8f16d6b0dc80277129559c8e7dbc9011241a0da8f60d031edb0e6e9ac8f/mypy-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f7fb09d05e0f1c329a36dcd30e27564a3555717cde87301fae4fb542402ddfad", size = 10120169, upload-time = "2025-07-14T20:32:38.84Z" }, + { url = "https://files.pythonhosted.org/packages/14/ef/978ba79df0d65af680e20d43121363cf643eb79b04bf3880d01fc8afeb6f/mypy-1.17.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b72c34ce05ac3a1361ae2ebb50757fb6e3624032d91488d93544e9f82db0ed6c", size = 11918121, upload-time = "2025-07-14T20:33:52.328Z" }, + { url = "https://files.pythonhosted.org/packages/f4/10/55ef70b104151a0d8280474f05268ff0a2a79be8d788d5e647257d121309/mypy-1.17.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:434ad499ad8dde8b2f6391ddfa982f41cb07ccda8e3c67781b1bfd4e5f9450a8", size = 12648821, upload-time = "2025-07-14T20:32:59.631Z" }, + { url = "https://files.pythonhosted.org/packages/26/8c/7781fcd2e1eef48fbedd3a422c21fe300a8e03ed5be2eb4bd10246a77f4e/mypy-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f105f61a5eff52e137fd73bee32958b2add9d9f0a856f17314018646af838e97", size = 12896955, upload-time = "2025-07-14T20:32:49.543Z" }, + { url = "https://files.pythonhosted.org/packages/78/13/03ac759dabe86e98ca7b6681f114f90ee03f3ff8365a57049d311bd4a4e3/mypy-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:ba06254a5a22729853209550d80f94e28690d5530c661f9416a68ac097b13fc4", size = 9512957, upload-time = "2025-07-14T20:33:28.619Z" }, + { url = "https://files.pythonhosted.org/packages/e3/fc/ee058cc4316f219078464555873e99d170bde1d9569abd833300dbeb484a/mypy-1.17.0-py3-none-any.whl", hash = "sha256:15d9d0018237ab058e5de3d8fce61b6fa72cc59cc78fd91f1b474bce12abf496", size = 2283195, upload-time = "2025-07-14T20:31:54.753Z" }, +] + +[[package]] +name = "mypy-extensions" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, +] + +[[package]] +name = "nodeenv" +version = "1.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/24/bf/d1bda4f6168e0b2e9e5958945e01910052158313224ada5ce1fb2e1113b8/nodeenv-1.10.0.tar.gz", hash = "sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb", size = 55611, upload-time = "2025-12-20T14:08:54.006Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438, upload-time = "2025-12-20T14:08:52.782Z" }, +] + +[[package]] +name = "packaging" +version = "25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, +] + +[[package]] +name = "pathspec" +version = "1.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4c/b2/bb8e495d5262bfec41ab5cb18f522f1012933347fb5d9e62452d446baca2/pathspec-1.0.3.tar.gz", hash = "sha256:bac5cf97ae2c2876e2d25ebb15078eb04d76e4b98921ee31c6f85ade8b59444d", size = 130841, upload-time = "2026-01-09T15:46:46.009Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/2b/121e912bd60eebd623f873fd090de0e84f322972ab25a7f9044c056804ed/pathspec-1.0.3-py3-none-any.whl", hash = "sha256:e80767021c1cc524aa3fb14bedda9c34406591343cc42797b386ce7b9354fb6c", size = 55021, upload-time = "2026-01-09T15:46:44.652Z" }, +] + +[[package]] +name = "phoebe-bird" +version = "0.1.0a12" +source = { editable = "." } +dependencies = [ + { name = "anyio" }, + { name = "distro" }, + { name = "httpx" }, + { name = "pydantic", version = "1.10.26", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'group-11-phoebe-bird-pydantic-v1'" }, + { name = "pydantic", version = "2.12.5", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'group-11-phoebe-bird-pydantic-v2' or extra != 'group-11-phoebe-bird-pydantic-v1'" }, + { name = "sniffio" }, + { name = "typing-extensions" }, +] + +[package.optional-dependencies] +aiohttp = [ + { name = "aiohttp" }, + { name = "httpx-aiohttp" }, +] + +[package.dev-dependencies] +dev = [ + { name = "dirty-equals" }, + { name = "importlib-metadata" }, + { name = "mypy" }, + { name = "pyright" }, + { name = "pytest", version = "8.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, + { name = "pytest", version = "9.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, + { name = "pytest-asyncio", version = "1.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, + { name = "pytest-asyncio", version = "1.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, + { name = "pytest-xdist" }, + { name = "respx" }, + { name = "rich" }, + { name = "ruff" }, + { name = "time-machine", version = "2.19.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, + { name = "time-machine", version = "3.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, +] +pydantic-v1 = [ + { name = "pydantic", version = "1.10.26", source = { registry = "https://pypi.org/simple" } }, +] +pydantic-v2 = [ + { name = "pydantic", version = "2.12.5", source = { registry = "https://pypi.org/simple" } }, +] + +[package.metadata] +requires-dist = [ + { name = "aiohttp", marker = "extra == 'aiohttp'" }, + { name = "anyio", specifier = ">=3.5.0,<5" }, + { name = "distro", specifier = ">=1.7.0,<2" }, + { name = "httpx", specifier = ">=0.23.0,<1" }, + { name = "httpx-aiohttp", marker = "extra == 'aiohttp'", specifier = ">=0.1.9" }, + { name = "pydantic", specifier = ">=1.9.0,<3" }, + { name = "sniffio" }, + { name = "typing-extensions", specifier = ">=4.14,<5" }, +] +provides-extras = ["aiohttp"] + +[package.metadata.requires-dev] +dev = [ + { name = "dirty-equals", specifier = ">=0.6.0" }, + { name = "importlib-metadata", specifier = ">=6.7.0" }, + { name = "mypy", specifier = "==1.17" }, + { name = "pyright", specifier = "==1.1.399" }, + { name = "pytest" }, + { name = "pytest-asyncio" }, + { name = "pytest-xdist", specifier = ">=3.6.1" }, + { name = "respx" }, + { name = "rich", specifier = ">=13.7.1" }, + { name = "ruff" }, + { name = "time-machine" }, +] +pydantic-v1 = [{ name = "pydantic", specifier = ">=1.9.0,<2" }] +pydantic-v2 = [ + { name = "pydantic", marker = "python_full_version < '3.14'", specifier = "~=2.0" }, + { name = "pydantic", marker = "python_full_version >= '3.14'", specifier = "~=2.12" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "propcache" +version = "0.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9e/da/e9fc233cf63743258bff22b3dfa7ea5baef7b5bc324af47a0ad89b8ffc6f/propcache-0.4.1.tar.gz", hash = "sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d", size = 46442, upload-time = "2025-10-08T19:49:02.291Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/0e/934b541323035566a9af292dba85a195f7b78179114f2c6ebb24551118a9/propcache-0.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7c2d1fa3201efaf55d730400d945b5b3ab6e672e100ba0f9a409d950ab25d7db", size = 79534, upload-time = "2025-10-08T19:46:02.083Z" }, + { url = "https://files.pythonhosted.org/packages/a1/6b/db0d03d96726d995dc7171286c6ba9d8d14251f37433890f88368951a44e/propcache-0.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1eb2994229cc8ce7fe9b3db88f5465f5fd8651672840b2e426b88cdb1a30aac8", size = 45526, upload-time = "2025-10-08T19:46:03.884Z" }, + { url = "https://files.pythonhosted.org/packages/e4/c3/82728404aea669e1600f304f2609cde9e665c18df5a11cdd57ed73c1dceb/propcache-0.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:66c1f011f45a3b33d7bcb22daed4b29c0c9e2224758b6be00686731e1b46f925", size = 47263, upload-time = "2025-10-08T19:46:05.405Z" }, + { url = "https://files.pythonhosted.org/packages/df/1b/39313ddad2bf9187a1432654c38249bab4562ef535ef07f5eb6eb04d0b1b/propcache-0.4.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9a52009f2adffe195d0b605c25ec929d26b36ef986ba85244891dee3b294df21", size = 201012, upload-time = "2025-10-08T19:46:07.165Z" }, + { url = "https://files.pythonhosted.org/packages/5b/01/f1d0b57d136f294a142acf97f4ed58c8e5b974c21e543000968357115011/propcache-0.4.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5d4e2366a9c7b837555cf02fb9be2e3167d333aff716332ef1b7c3a142ec40c5", size = 209491, upload-time = "2025-10-08T19:46:08.909Z" }, + { url = "https://files.pythonhosted.org/packages/a1/c8/038d909c61c5bb039070b3fb02ad5cccdb1dde0d714792e251cdb17c9c05/propcache-0.4.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9d2b6caef873b4f09e26ea7e33d65f42b944837563a47a94719cc3544319a0db", size = 215319, upload-time = "2025-10-08T19:46:10.7Z" }, + { url = "https://files.pythonhosted.org/packages/08/57/8c87e93142b2c1fa2408e45695205a7ba05fb5db458c0bf5c06ba0e09ea6/propcache-0.4.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2b16ec437a8c8a965ecf95739448dd938b5c7f56e67ea009f4300d8df05f32b7", size = 196856, upload-time = "2025-10-08T19:46:12.003Z" }, + { url = "https://files.pythonhosted.org/packages/42/df/5615fec76aa561987a534759b3686008a288e73107faa49a8ae5795a9f7a/propcache-0.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:296f4c8ed03ca7476813fe666c9ea97869a8d7aec972618671b33a38a5182ef4", size = 193241, upload-time = "2025-10-08T19:46:13.495Z" }, + { url = "https://files.pythonhosted.org/packages/d5/21/62949eb3a7a54afe8327011c90aca7e03547787a88fb8bd9726806482fea/propcache-0.4.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:1f0978529a418ebd1f49dad413a2b68af33f85d5c5ca5c6ca2a3bed375a7ac60", size = 190552, upload-time = "2025-10-08T19:46:14.938Z" }, + { url = "https://files.pythonhosted.org/packages/30/ee/ab4d727dd70806e5b4de96a798ae7ac6e4d42516f030ee60522474b6b332/propcache-0.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fd138803047fb4c062b1c1dd95462f5209456bfab55c734458f15d11da288f8f", size = 200113, upload-time = "2025-10-08T19:46:16.695Z" }, + { url = "https://files.pythonhosted.org/packages/8a/0b/38b46208e6711b016aa8966a3ac793eee0d05c7159d8342aa27fc0bc365e/propcache-0.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8c9b3cbe4584636d72ff556d9036e0c9317fa27b3ac1f0f558e7e84d1c9c5900", size = 200778, upload-time = "2025-10-08T19:46:18.023Z" }, + { url = "https://files.pythonhosted.org/packages/cf/81/5abec54355ed344476bee711e9f04815d4b00a311ab0535599204eecc257/propcache-0.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f93243fdc5657247533273ac4f86ae106cc6445a0efacb9a1bfe982fcfefd90c", size = 193047, upload-time = "2025-10-08T19:46:19.449Z" }, + { url = "https://files.pythonhosted.org/packages/ec/b6/1f237c04e32063cb034acd5f6ef34ef3a394f75502e72703545631ab1ef6/propcache-0.4.1-cp310-cp310-win32.whl", hash = "sha256:a0ee98db9c5f80785b266eb805016e36058ac72c51a064040f2bc43b61101cdb", size = 38093, upload-time = "2025-10-08T19:46:20.643Z" }, + { url = "https://files.pythonhosted.org/packages/a6/67/354aac4e0603a15f76439caf0427781bcd6797f370377f75a642133bc954/propcache-0.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:1cdb7988c4e5ac7f6d175a28a9aa0c94cb6f2ebe52756a3c0cda98d2809a9e37", size = 41638, upload-time = "2025-10-08T19:46:21.935Z" }, + { url = "https://files.pythonhosted.org/packages/e0/e1/74e55b9fd1a4c209ff1a9a824bf6c8b3d1fc5a1ac3eabe23462637466785/propcache-0.4.1-cp310-cp310-win_arm64.whl", hash = "sha256:d82ad62b19645419fe79dd63b3f9253e15b30e955c0170e5cebc350c1844e581", size = 38229, upload-time = "2025-10-08T19:46:23.368Z" }, + { url = "https://files.pythonhosted.org/packages/8c/d4/4e2c9aaf7ac2242b9358f98dccd8f90f2605402f5afeff6c578682c2c491/propcache-0.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:60a8fda9644b7dfd5dece8c61d8a85e271cb958075bfc4e01083c148b61a7caf", size = 80208, upload-time = "2025-10-08T19:46:24.597Z" }, + { url = "https://files.pythonhosted.org/packages/c2/21/d7b68e911f9c8e18e4ae43bdbc1e1e9bbd971f8866eb81608947b6f585ff/propcache-0.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c30b53e7e6bda1d547cabb47c825f3843a0a1a42b0496087bb58d8fedf9f41b5", size = 45777, upload-time = "2025-10-08T19:46:25.733Z" }, + { url = "https://files.pythonhosted.org/packages/d3/1d/11605e99ac8ea9435651ee71ab4cb4bf03f0949586246476a25aadfec54a/propcache-0.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e", size = 47647, upload-time = "2025-10-08T19:46:27.304Z" }, + { url = "https://files.pythonhosted.org/packages/58/1a/3c62c127a8466c9c843bccb503d40a273e5cc69838805f322e2826509e0d/propcache-0.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3d902a36df4e5989763425a8ab9e98cd8ad5c52c823b34ee7ef307fd50582566", size = 214929, upload-time = "2025-10-08T19:46:28.62Z" }, + { url = "https://files.pythonhosted.org/packages/56/b9/8fa98f850960b367c4b8fe0592e7fc341daa7a9462e925228f10a60cf74f/propcache-0.4.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a9695397f85973bb40427dedddf70d8dc4a44b22f1650dd4af9eedf443d45165", size = 221778, upload-time = "2025-10-08T19:46:30.358Z" }, + { url = "https://files.pythonhosted.org/packages/46/a6/0ab4f660eb59649d14b3d3d65c439421cf2f87fe5dd68591cbe3c1e78a89/propcache-0.4.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2bb07ffd7eaad486576430c89f9b215f9e4be68c4866a96e97db9e97fead85dc", size = 228144, upload-time = "2025-10-08T19:46:32.607Z" }, + { url = "https://files.pythonhosted.org/packages/52/6a/57f43e054fb3d3a56ac9fc532bc684fc6169a26c75c353e65425b3e56eef/propcache-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fd6f30fdcf9ae2a70abd34da54f18da086160e4d7d9251f81f3da0ff84fc5a48", size = 210030, upload-time = "2025-10-08T19:46:33.969Z" }, + { url = "https://files.pythonhosted.org/packages/40/e2/27e6feebb5f6b8408fa29f5efbb765cd54c153ac77314d27e457a3e993b7/propcache-0.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fc38cba02d1acba4e2869eef1a57a43dfbd3d49a59bf90dda7444ec2be6a5570", size = 208252, upload-time = "2025-10-08T19:46:35.309Z" }, + { url = "https://files.pythonhosted.org/packages/9e/f8/91c27b22ccda1dbc7967f921c42825564fa5336a01ecd72eb78a9f4f53c2/propcache-0.4.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:67fad6162281e80e882fb3ec355398cf72864a54069d060321f6cd0ade95fe85", size = 202064, upload-time = "2025-10-08T19:46:36.993Z" }, + { url = "https://files.pythonhosted.org/packages/f2/26/7f00bd6bd1adba5aafe5f4a66390f243acab58eab24ff1a08bebb2ef9d40/propcache-0.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f10207adf04d08bec185bae14d9606a1444715bc99180f9331c9c02093e1959e", size = 212429, upload-time = "2025-10-08T19:46:38.398Z" }, + { url = "https://files.pythonhosted.org/packages/84/89/fd108ba7815c1117ddca79c228f3f8a15fc82a73bca8b142eb5de13b2785/propcache-0.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e9b0d8d0845bbc4cfcdcbcdbf5086886bc8157aa963c31c777ceff7846c77757", size = 216727, upload-time = "2025-10-08T19:46:39.732Z" }, + { url = "https://files.pythonhosted.org/packages/79/37/3ec3f7e3173e73f1d600495d8b545b53802cbf35506e5732dd8578db3724/propcache-0.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:981333cb2f4c1896a12f4ab92a9cc8f09ea664e9b7dbdc4eff74627af3a11c0f", size = 205097, upload-time = "2025-10-08T19:46:41.025Z" }, + { url = "https://files.pythonhosted.org/packages/61/b0/b2631c19793f869d35f47d5a3a56fb19e9160d3c119f15ac7344fc3ccae7/propcache-0.4.1-cp311-cp311-win32.whl", hash = "sha256:f1d2f90aeec838a52f1c1a32fe9a619fefd5e411721a9117fbf82aea638fe8a1", size = 38084, upload-time = "2025-10-08T19:46:42.693Z" }, + { url = "https://files.pythonhosted.org/packages/f4/78/6cce448e2098e9f3bfc91bb877f06aa24b6ccace872e39c53b2f707c4648/propcache-0.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6", size = 41637, upload-time = "2025-10-08T19:46:43.778Z" }, + { url = "https://files.pythonhosted.org/packages/9c/e9/754f180cccd7f51a39913782c74717c581b9cc8177ad0e949f4d51812383/propcache-0.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:e53f3a38d3510c11953f3e6a33f205c6d1b001129f972805ca9b42fc308bc239", size = 38064, upload-time = "2025-10-08T19:46:44.872Z" }, + { url = "https://files.pythonhosted.org/packages/a2/0f/f17b1b2b221d5ca28b4b876e8bb046ac40466513960646bda8e1853cdfa2/propcache-0.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2", size = 80061, upload-time = "2025-10-08T19:46:46.075Z" }, + { url = "https://files.pythonhosted.org/packages/76/47/8ccf75935f51448ba9a16a71b783eb7ef6b9ee60f5d14c7f8a8a79fbeed7/propcache-0.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403", size = 46037, upload-time = "2025-10-08T19:46:47.23Z" }, + { url = "https://files.pythonhosted.org/packages/0a/b6/5c9a0e42df4d00bfb4a3cbbe5cf9f54260300c88a0e9af1f47ca5ce17ac0/propcache-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207", size = 47324, upload-time = "2025-10-08T19:46:48.384Z" }, + { url = "https://files.pythonhosted.org/packages/9e/d3/6c7ee328b39a81ee877c962469f1e795f9db87f925251efeb0545e0020d0/propcache-0.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72", size = 225505, upload-time = "2025-10-08T19:46:50.055Z" }, + { url = "https://files.pythonhosted.org/packages/01/5d/1c53f4563490b1d06a684742cc6076ef944bc6457df6051b7d1a877c057b/propcache-0.4.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367", size = 230242, upload-time = "2025-10-08T19:46:51.815Z" }, + { url = "https://files.pythonhosted.org/packages/20/e1/ce4620633b0e2422207c3cb774a0ee61cac13abc6217763a7b9e2e3f4a12/propcache-0.4.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4", size = 238474, upload-time = "2025-10-08T19:46:53.208Z" }, + { url = "https://files.pythonhosted.org/packages/46/4b/3aae6835b8e5f44ea6a68348ad90f78134047b503765087be2f9912140ea/propcache-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf", size = 221575, upload-time = "2025-10-08T19:46:54.511Z" }, + { url = "https://files.pythonhosted.org/packages/6e/a5/8a5e8678bcc9d3a1a15b9a29165640d64762d424a16af543f00629c87338/propcache-0.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3", size = 216736, upload-time = "2025-10-08T19:46:56.212Z" }, + { url = "https://files.pythonhosted.org/packages/f1/63/b7b215eddeac83ca1c6b934f89d09a625aa9ee4ba158338854c87210cc36/propcache-0.4.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778", size = 213019, upload-time = "2025-10-08T19:46:57.595Z" }, + { url = "https://files.pythonhosted.org/packages/57/74/f580099a58c8af587cac7ba19ee7cb418506342fbbe2d4a4401661cca886/propcache-0.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6", size = 220376, upload-time = "2025-10-08T19:46:59.067Z" }, + { url = "https://files.pythonhosted.org/packages/c4/ee/542f1313aff7eaf19c2bb758c5d0560d2683dac001a1c96d0774af799843/propcache-0.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9", size = 226988, upload-time = "2025-10-08T19:47:00.544Z" }, + { url = "https://files.pythonhosted.org/packages/8f/18/9c6b015dd9c6930f6ce2229e1f02fb35298b847f2087ea2b436a5bfa7287/propcache-0.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75", size = 215615, upload-time = "2025-10-08T19:47:01.968Z" }, + { url = "https://files.pythonhosted.org/packages/80/9e/e7b85720b98c45a45e1fca6a177024934dc9bc5f4d5dd04207f216fc33ed/propcache-0.4.1-cp312-cp312-win32.whl", hash = "sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8", size = 38066, upload-time = "2025-10-08T19:47:03.503Z" }, + { url = "https://files.pythonhosted.org/packages/54/09/d19cff2a5aaac632ec8fc03737b223597b1e347416934c1b3a7df079784c/propcache-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db", size = 41655, upload-time = "2025-10-08T19:47:04.973Z" }, + { url = "https://files.pythonhosted.org/packages/68/ab/6b5c191bb5de08036a8c697b265d4ca76148efb10fa162f14af14fb5f076/propcache-0.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1", size = 37789, upload-time = "2025-10-08T19:47:06.077Z" }, + { url = "https://files.pythonhosted.org/packages/bf/df/6d9c1b6ac12b003837dde8a10231a7344512186e87b36e855bef32241942/propcache-0.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf", size = 77750, upload-time = "2025-10-08T19:47:07.648Z" }, + { url = "https://files.pythonhosted.org/packages/8b/e8/677a0025e8a2acf07d3418a2e7ba529c9c33caf09d3c1f25513023c1db56/propcache-0.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311", size = 44780, upload-time = "2025-10-08T19:47:08.851Z" }, + { url = "https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74", size = 46308, upload-time = "2025-10-08T19:47:09.982Z" }, + { url = "https://files.pythonhosted.org/packages/2d/48/c5ac64dee5262044348d1d78a5f85dd1a57464a60d30daee946699963eb3/propcache-0.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe", size = 208182, upload-time = "2025-10-08T19:47:11.319Z" }, + { url = "https://files.pythonhosted.org/packages/c6/0c/cd762dd011a9287389a6a3eb43aa30207bde253610cca06824aeabfe9653/propcache-0.4.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af", size = 211215, upload-time = "2025-10-08T19:47:13.146Z" }, + { url = "https://files.pythonhosted.org/packages/30/3e/49861e90233ba36890ae0ca4c660e95df565b2cd15d4a68556ab5865974e/propcache-0.4.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c", size = 218112, upload-time = "2025-10-08T19:47:14.913Z" }, + { url = "https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f", size = 204442, upload-time = "2025-10-08T19:47:16.277Z" }, + { url = "https://files.pythonhosted.org/packages/50/a6/4282772fd016a76d3e5c0df58380a5ea64900afd836cec2c2f662d1b9bb3/propcache-0.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1", size = 199398, upload-time = "2025-10-08T19:47:17.962Z" }, + { url = "https://files.pythonhosted.org/packages/3e/ec/d8a7cd406ee1ddb705db2139f8a10a8a427100347bd698e7014351c7af09/propcache-0.4.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24", size = 196920, upload-time = "2025-10-08T19:47:19.355Z" }, + { url = "https://files.pythonhosted.org/packages/f6/6c/f38ab64af3764f431e359f8baf9e0a21013e24329e8b85d2da32e8ed07ca/propcache-0.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa", size = 203748, upload-time = "2025-10-08T19:47:21.338Z" }, + { url = "https://files.pythonhosted.org/packages/d6/e3/fa846bd70f6534d647886621388f0a265254d30e3ce47e5c8e6e27dbf153/propcache-0.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61", size = 205877, upload-time = "2025-10-08T19:47:23.059Z" }, + { url = "https://files.pythonhosted.org/packages/e2/39/8163fc6f3133fea7b5f2827e8eba2029a0277ab2c5beee6c1db7b10fc23d/propcache-0.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66", size = 199437, upload-time = "2025-10-08T19:47:24.445Z" }, + { url = "https://files.pythonhosted.org/packages/93/89/caa9089970ca49c7c01662bd0eeedfe85494e863e8043565aeb6472ce8fe/propcache-0.4.1-cp313-cp313-win32.whl", hash = "sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81", size = 37586, upload-time = "2025-10-08T19:47:25.736Z" }, + { url = "https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e", size = 40790, upload-time = "2025-10-08T19:47:26.847Z" }, + { url = "https://files.pythonhosted.org/packages/59/1b/e71ae98235f8e2ba5004d8cb19765a74877abf189bc53fc0c80d799e56c3/propcache-0.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1", size = 37158, upload-time = "2025-10-08T19:47:27.961Z" }, + { url = "https://files.pythonhosted.org/packages/83/ce/a31bbdfc24ee0dcbba458c8175ed26089cf109a55bbe7b7640ed2470cfe9/propcache-0.4.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b", size = 81451, upload-time = "2025-10-08T19:47:29.445Z" }, + { url = "https://files.pythonhosted.org/packages/25/9c/442a45a470a68456e710d96cacd3573ef26a1d0a60067e6a7d5e655621ed/propcache-0.4.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566", size = 46374, upload-time = "2025-10-08T19:47:30.579Z" }, + { url = "https://files.pythonhosted.org/packages/f4/bf/b1d5e21dbc3b2e889ea4327044fb16312a736d97640fb8b6aa3f9c7b3b65/propcache-0.4.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835", size = 48396, upload-time = "2025-10-08T19:47:31.79Z" }, + { url = "https://files.pythonhosted.org/packages/f4/04/5b4c54a103d480e978d3c8a76073502b18db0c4bc17ab91b3cb5092ad949/propcache-0.4.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e", size = 275950, upload-time = "2025-10-08T19:47:33.481Z" }, + { url = "https://files.pythonhosted.org/packages/b4/c1/86f846827fb969c4b78b0af79bba1d1ea2156492e1b83dea8b8a6ae27395/propcache-0.4.1-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859", size = 273856, upload-time = "2025-10-08T19:47:34.906Z" }, + { url = "https://files.pythonhosted.org/packages/36/1d/fc272a63c8d3bbad6878c336c7a7dea15e8f2d23a544bda43205dfa83ada/propcache-0.4.1-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b", size = 280420, upload-time = "2025-10-08T19:47:36.338Z" }, + { url = "https://files.pythonhosted.org/packages/07/0c/01f2219d39f7e53d52e5173bcb09c976609ba30209912a0680adfb8c593a/propcache-0.4.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0", size = 263254, upload-time = "2025-10-08T19:47:37.692Z" }, + { url = "https://files.pythonhosted.org/packages/2d/18/cd28081658ce597898f0c4d174d4d0f3c5b6d4dc27ffafeef835c95eb359/propcache-0.4.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af", size = 261205, upload-time = "2025-10-08T19:47:39.659Z" }, + { url = "https://files.pythonhosted.org/packages/7a/71/1f9e22eb8b8316701c2a19fa1f388c8a3185082607da8e406a803c9b954e/propcache-0.4.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393", size = 247873, upload-time = "2025-10-08T19:47:41.084Z" }, + { url = "https://files.pythonhosted.org/packages/4a/65/3d4b61f36af2b4eddba9def857959f1016a51066b4f1ce348e0cf7881f58/propcache-0.4.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874", size = 262739, upload-time = "2025-10-08T19:47:42.51Z" }, + { url = "https://files.pythonhosted.org/packages/2a/42/26746ab087faa77c1c68079b228810436ccd9a5ce9ac85e2b7307195fd06/propcache-0.4.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7", size = 263514, upload-time = "2025-10-08T19:47:43.927Z" }, + { url = "https://files.pythonhosted.org/packages/94/13/630690fe201f5502d2403dd3cfd451ed8858fe3c738ee88d095ad2ff407b/propcache-0.4.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1", size = 257781, upload-time = "2025-10-08T19:47:45.448Z" }, + { url = "https://files.pythonhosted.org/packages/92/f7/1d4ec5841505f423469efbfc381d64b7b467438cd5a4bbcbb063f3b73d27/propcache-0.4.1-cp313-cp313t-win32.whl", hash = "sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717", size = 41396, upload-time = "2025-10-08T19:47:47.202Z" }, + { url = "https://files.pythonhosted.org/packages/48/f0/615c30622316496d2cbbc29f5985f7777d3ada70f23370608c1d3e081c1f/propcache-0.4.1-cp313-cp313t-win_amd64.whl", hash = "sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37", size = 44897, upload-time = "2025-10-08T19:47:48.336Z" }, + { url = "https://files.pythonhosted.org/packages/fd/ca/6002e46eccbe0e33dcd4069ef32f7f1c9e243736e07adca37ae8c4830ec3/propcache-0.4.1-cp313-cp313t-win_arm64.whl", hash = "sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a", size = 39789, upload-time = "2025-10-08T19:47:49.876Z" }, + { url = "https://files.pythonhosted.org/packages/8e/5c/bca52d654a896f831b8256683457ceddd490ec18d9ec50e97dfd8fc726a8/propcache-0.4.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12", size = 78152, upload-time = "2025-10-08T19:47:51.051Z" }, + { url = "https://files.pythonhosted.org/packages/65/9b/03b04e7d82a5f54fb16113d839f5ea1ede58a61e90edf515f6577c66fa8f/propcache-0.4.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c", size = 44869, upload-time = "2025-10-08T19:47:52.594Z" }, + { url = "https://files.pythonhosted.org/packages/b2/fa/89a8ef0468d5833a23fff277b143d0573897cf75bd56670a6d28126c7d68/propcache-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded", size = 46596, upload-time = "2025-10-08T19:47:54.073Z" }, + { url = "https://files.pythonhosted.org/packages/86/bd/47816020d337f4a746edc42fe8d53669965138f39ee117414c7d7a340cfe/propcache-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641", size = 206981, upload-time = "2025-10-08T19:47:55.715Z" }, + { url = "https://files.pythonhosted.org/packages/df/f6/c5fa1357cc9748510ee55f37173eb31bfde6d94e98ccd9e6f033f2fc06e1/propcache-0.4.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4", size = 211490, upload-time = "2025-10-08T19:47:57.499Z" }, + { url = "https://files.pythonhosted.org/packages/80/1e/e5889652a7c4a3846683401a48f0f2e5083ce0ec1a8a5221d8058fbd1adf/propcache-0.4.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44", size = 215371, upload-time = "2025-10-08T19:47:59.317Z" }, + { url = "https://files.pythonhosted.org/packages/b2/f2/889ad4b2408f72fe1a4f6a19491177b30ea7bf1a0fd5f17050ca08cfc882/propcache-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d", size = 201424, upload-time = "2025-10-08T19:48:00.67Z" }, + { url = "https://files.pythonhosted.org/packages/27/73/033d63069b57b0812c8bd19f311faebeceb6ba31b8f32b73432d12a0b826/propcache-0.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b", size = 197566, upload-time = "2025-10-08T19:48:02.604Z" }, + { url = "https://files.pythonhosted.org/packages/dc/89/ce24f3dc182630b4e07aa6d15f0ff4b14ed4b9955fae95a0b54c58d66c05/propcache-0.4.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e", size = 193130, upload-time = "2025-10-08T19:48:04.499Z" }, + { url = "https://files.pythonhosted.org/packages/a9/24/ef0d5fd1a811fb5c609278d0209c9f10c35f20581fcc16f818da959fc5b4/propcache-0.4.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f", size = 202625, upload-time = "2025-10-08T19:48:06.213Z" }, + { url = "https://files.pythonhosted.org/packages/f5/02/98ec20ff5546f68d673df2f7a69e8c0d076b5abd05ca882dc7ee3a83653d/propcache-0.4.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49", size = 204209, upload-time = "2025-10-08T19:48:08.432Z" }, + { url = "https://files.pythonhosted.org/packages/a0/87/492694f76759b15f0467a2a93ab68d32859672b646aa8a04ce4864e7932d/propcache-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144", size = 197797, upload-time = "2025-10-08T19:48:09.968Z" }, + { url = "https://files.pythonhosted.org/packages/ee/36/66367de3575db1d2d3f3d177432bd14ee577a39d3f5d1b3d5df8afe3b6e2/propcache-0.4.1-cp314-cp314-win32.whl", hash = "sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f", size = 38140, upload-time = "2025-10-08T19:48:11.232Z" }, + { url = "https://files.pythonhosted.org/packages/0c/2a/a758b47de253636e1b8aef181c0b4f4f204bf0dd964914fb2af90a95b49b/propcache-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153", size = 41257, upload-time = "2025-10-08T19:48:12.707Z" }, + { url = "https://files.pythonhosted.org/packages/34/5e/63bd5896c3fec12edcbd6f12508d4890d23c265df28c74b175e1ef9f4f3b/propcache-0.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992", size = 38097, upload-time = "2025-10-08T19:48:13.923Z" }, + { url = "https://files.pythonhosted.org/packages/99/85/9ff785d787ccf9bbb3f3106f79884a130951436f58392000231b4c737c80/propcache-0.4.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f", size = 81455, upload-time = "2025-10-08T19:48:15.16Z" }, + { url = "https://files.pythonhosted.org/packages/90/85/2431c10c8e7ddb1445c1f7c4b54d886e8ad20e3c6307e7218f05922cad67/propcache-0.4.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393", size = 46372, upload-time = "2025-10-08T19:48:16.424Z" }, + { url = "https://files.pythonhosted.org/packages/01/20/b0972d902472da9bcb683fa595099911f4d2e86e5683bcc45de60dd05dc3/propcache-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0", size = 48411, upload-time = "2025-10-08T19:48:17.577Z" }, + { url = "https://files.pythonhosted.org/packages/e2/e3/7dc89f4f21e8f99bad3d5ddb3a3389afcf9da4ac69e3deb2dcdc96e74169/propcache-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a", size = 275712, upload-time = "2025-10-08T19:48:18.901Z" }, + { url = "https://files.pythonhosted.org/packages/20/67/89800c8352489b21a8047c773067644e3897f02ecbbd610f4d46b7f08612/propcache-0.4.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be", size = 273557, upload-time = "2025-10-08T19:48:20.762Z" }, + { url = "https://files.pythonhosted.org/packages/e2/a1/b52b055c766a54ce6d9c16d9aca0cad8059acd9637cdf8aa0222f4a026ef/propcache-0.4.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc", size = 280015, upload-time = "2025-10-08T19:48:22.592Z" }, + { url = "https://files.pythonhosted.org/packages/48/c8/33cee30bd890672c63743049f3c9e4be087e6780906bfc3ec58528be59c1/propcache-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a", size = 262880, upload-time = "2025-10-08T19:48:23.947Z" }, + { url = "https://files.pythonhosted.org/packages/0c/b1/8f08a143b204b418285c88b83d00edbd61afbc2c6415ffafc8905da7038b/propcache-0.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89", size = 260938, upload-time = "2025-10-08T19:48:25.656Z" }, + { url = "https://files.pythonhosted.org/packages/cf/12/96e4664c82ca2f31e1c8dff86afb867348979eb78d3cb8546a680287a1e9/propcache-0.4.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726", size = 247641, upload-time = "2025-10-08T19:48:27.207Z" }, + { url = "https://files.pythonhosted.org/packages/18/ed/e7a9cfca28133386ba52278136d42209d3125db08d0a6395f0cba0c0285c/propcache-0.4.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367", size = 262510, upload-time = "2025-10-08T19:48:28.65Z" }, + { url = "https://files.pythonhosted.org/packages/f5/76/16d8bf65e8845dd62b4e2b57444ab81f07f40caa5652b8969b87ddcf2ef6/propcache-0.4.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36", size = 263161, upload-time = "2025-10-08T19:48:30.133Z" }, + { url = "https://files.pythonhosted.org/packages/e7/70/c99e9edb5d91d5ad8a49fa3c1e8285ba64f1476782fed10ab251ff413ba1/propcache-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455", size = 257393, upload-time = "2025-10-08T19:48:31.567Z" }, + { url = "https://files.pythonhosted.org/packages/08/02/87b25304249a35c0915d236575bc3574a323f60b47939a2262b77632a3ee/propcache-0.4.1-cp314-cp314t-win32.whl", hash = "sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85", size = 42546, upload-time = "2025-10-08T19:48:32.872Z" }, + { url = "https://files.pythonhosted.org/packages/cb/ef/3c6ecf8b317aa982f309835e8f96987466123c6e596646d4e6a1dfcd080f/propcache-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1", size = 46259, upload-time = "2025-10-08T19:48:34.226Z" }, + { url = "https://files.pythonhosted.org/packages/c4/2d/346e946d4951f37eca1e4f55be0f0174c52cd70720f84029b02f296f4a38/propcache-0.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9", size = 40428, upload-time = "2025-10-08T19:48:35.441Z" }, + { url = "https://files.pythonhosted.org/packages/9b/01/0ebaec9003f5d619a7475165961f8e3083cf8644d704b60395df3601632d/propcache-0.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3d233076ccf9e450c8b3bc6720af226b898ef5d051a2d145f7d765e6e9f9bcff", size = 80277, upload-time = "2025-10-08T19:48:36.647Z" }, + { url = "https://files.pythonhosted.org/packages/34/58/04af97ac586b4ef6b9026c3fd36ee7798b737a832f5d3440a4280dcebd3a/propcache-0.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:357f5bb5c377a82e105e44bd3d52ba22b616f7b9773714bff93573988ef0a5fb", size = 45865, upload-time = "2025-10-08T19:48:37.859Z" }, + { url = "https://files.pythonhosted.org/packages/7c/19/b65d98ae21384518b291d9939e24a8aeac4fdb5101b732576f8f7540e834/propcache-0.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cbc3b6dfc728105b2a57c06791eb07a94229202ea75c59db644d7d496b698cac", size = 47636, upload-time = "2025-10-08T19:48:39.038Z" }, + { url = "https://files.pythonhosted.org/packages/b3/0f/317048c6d91c356c7154dca5af019e6effeb7ee15fa6a6db327cc19e12b4/propcache-0.4.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:182b51b421f0501952d938dc0b0eb45246a5b5153c50d42b495ad5fb7517c888", size = 201126, upload-time = "2025-10-08T19:48:40.774Z" }, + { url = "https://files.pythonhosted.org/packages/71/69/0b2a7a5a6ee83292b4b997dbd80549d8ce7d40b6397c1646c0d9495f5a85/propcache-0.4.1-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4b536b39c5199b96fc6245eb5fb796c497381d3942f169e44e8e392b29c9ebcc", size = 209837, upload-time = "2025-10-08T19:48:42.167Z" }, + { url = "https://files.pythonhosted.org/packages/a5/92/c699ac495a6698df6e497fc2de27af4b6ace10d8e76528357ce153722e45/propcache-0.4.1-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:db65d2af507bbfbdcedb254a11149f894169d90488dd3e7190f7cdcb2d6cd57a", size = 215578, upload-time = "2025-10-08T19:48:43.56Z" }, + { url = "https://files.pythonhosted.org/packages/b3/ee/14de81c5eb02c0ee4f500b4e39c4e1bd0677c06e72379e6ab18923c773fc/propcache-0.4.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fd2dbc472da1f772a4dae4fa24be938a6c544671a912e30529984dd80400cd88", size = 197187, upload-time = "2025-10-08T19:48:45.309Z" }, + { url = "https://files.pythonhosted.org/packages/1d/94/48dce9aaa6d8dd5a0859bad75158ec522546d4ac23f8e2f05fac469477dd/propcache-0.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:daede9cd44e0f8bdd9e6cc9a607fc81feb80fae7a5fc6cecaff0e0bb32e42d00", size = 193478, upload-time = "2025-10-08T19:48:47.743Z" }, + { url = "https://files.pythonhosted.org/packages/60/b5/0516b563e801e1ace212afde869a0596a0d7115eec0b12d296d75633fb29/propcache-0.4.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:71b749281b816793678ae7f3d0d84bd36e694953822eaad408d682efc5ca18e0", size = 190650, upload-time = "2025-10-08T19:48:49.373Z" }, + { url = "https://files.pythonhosted.org/packages/24/89/e0f7d4a5978cd56f8cd67735f74052f257dc471ec901694e430f0d1572fe/propcache-0.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:0002004213ee1f36cfb3f9a42b5066100c44276b9b72b4e1504cddd3d692e86e", size = 200251, upload-time = "2025-10-08T19:48:51.4Z" }, + { url = "https://files.pythonhosted.org/packages/06/7d/a1fac863d473876ed4406c914f2e14aa82d2f10dd207c9e16fc383cc5a24/propcache-0.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:fe49d0a85038f36ba9e3ffafa1103e61170b28e95b16622e11be0a0ea07c6781", size = 200919, upload-time = "2025-10-08T19:48:53.227Z" }, + { url = "https://files.pythonhosted.org/packages/c3/4e/f86a256ff24944cf5743e4e6c6994e3526f6acfcfb55e21694c2424f758c/propcache-0.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:99d43339c83aaf4d32bda60928231848eee470c6bda8d02599cc4cebe872d183", size = 193211, upload-time = "2025-10-08T19:48:55.027Z" }, + { url = "https://files.pythonhosted.org/packages/6e/3f/3fbad5f4356b068f1b047d300a6ff2c66614d7030f078cd50be3fec04228/propcache-0.4.1-cp39-cp39-win32.whl", hash = "sha256:a129e76735bc792794d5177069691c3217898b9f5cee2b2661471e52ffe13f19", size = 38314, upload-time = "2025-10-08T19:48:56.792Z" }, + { url = "https://files.pythonhosted.org/packages/a4/45/d78d136c3a3d215677abb886785aae744da2c3005bcb99e58640c56529b1/propcache-0.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:948dab269721ae9a87fd16c514a0a2c2a1bdb23a9a61b969b0f9d9ee2968546f", size = 41912, upload-time = "2025-10-08T19:48:57.995Z" }, + { url = "https://files.pythonhosted.org/packages/fc/2a/b0632941f25139f4e58450b307242951f7c2717a5704977c6d5323a800af/propcache-0.4.1-cp39-cp39-win_arm64.whl", hash = "sha256:5fd37c406dd6dc85aa743e214cef35dc54bbdd1419baac4f6ae5e5b1a2976938", size = 38450, upload-time = "2025-10-08T19:48:59.349Z" }, + { url = "https://files.pythonhosted.org/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload-time = "2025-10-08T19:49:00.792Z" }, +] + +[[package]] +name = "pydantic" +version = "1.10.26" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.10'", + "python_full_version < '3.10'", +] +dependencies = [ + { name = "typing-extensions", marker = "extra == 'group-11-phoebe-bird-pydantic-v1'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7b/da/fd89f987a376c807cd81ea0eff4589aade783bbb702637b4734ef2c743a2/pydantic-1.10.26.tar.gz", hash = "sha256:8c6aa39b494c5af092e690127c283d84f363ac36017106a9e66cb33a22ac412e", size = 357906, upload-time = "2025-12-18T15:47:46.557Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/08/2587a6d4314e7539eec84acd062cb7b037638edb57a0335d20e4c5b8878c/pydantic-1.10.26-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f7ae36fa0ecef8d39884120f212e16c06bb096a38f523421278e2f39c1784546", size = 2444588, upload-time = "2025-12-18T15:46:28.882Z" }, + { url = "https://files.pythonhosted.org/packages/47/e6/10df5f08c105bcbb4adbee7d1108ff4b347702b110fed058f6a03f1c6b73/pydantic-1.10.26-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d95a76cf503f0f72ed7812a91de948440b2bf564269975738a4751e4fadeb572", size = 2255972, upload-time = "2025-12-18T15:46:31.72Z" }, + { url = "https://files.pythonhosted.org/packages/ba/7d/fdb961e7adc2c31f394feba6f560ef2c74c446f0285e2c2eb87d2b7206c7/pydantic-1.10.26-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a943ce8e00ad708ed06a1d9df5b4fd28f5635a003b82a4908ece6f24c0b18464", size = 2857175, upload-time = "2025-12-18T15:46:34Z" }, + { url = "https://files.pythonhosted.org/packages/8f/6c/f21e27dda475d4c562bd01b5874284dd3180f336c1e669413b743ca8b278/pydantic-1.10.26-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:465ad8edb29b15c10b779b16431fe8e77c380098badf6db367b7a1d3e572cf53", size = 2947001, upload-time = "2025-12-18T15:46:35.922Z" }, + { url = "https://files.pythonhosted.org/packages/6d/f6/27ea206232cbb6ec24dc4e4e8888a9a734f96a1eaf13504be4b30ef26aa7/pydantic-1.10.26-cp310-cp310-win_amd64.whl", hash = "sha256:80e6be6272839c8a7641d26ad569ab77772809dd78f91d0068dc0fc97f071945", size = 2066217, upload-time = "2025-12-18T15:46:37.614Z" }, + { url = "https://files.pythonhosted.org/packages/1d/c1/d521e64c8130e1ad9d22c270bed3fabcc0940c9539b076b639c88fd32a8d/pydantic-1.10.26-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:116233e53889bcc536f617e38c1b8337d7fa9c280f0fd7a4045947515a785637", size = 2428347, upload-time = "2025-12-18T15:46:39.41Z" }, + { url = "https://files.pythonhosted.org/packages/2c/08/f4b804a00c16e3ea994cb640a7c25c579b4f1fa674cde6a19fa0dfb0ae4f/pydantic-1.10.26-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c3cfdd361addb6eb64ccd26ac356ad6514cee06a61ab26b27e16b5ed53108f77", size = 2212605, upload-time = "2025-12-18T15:46:41.006Z" }, + { url = "https://files.pythonhosted.org/packages/5d/78/0df4b9efef29bbc5e39f247fcba99060d15946b4463d82a5589cf7923d71/pydantic-1.10.26-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0e4451951a9a93bf9a90576f3e25240b47ee49ab5236adccb8eff6ac943adf0f", size = 2753560, upload-time = "2025-12-18T15:46:43.215Z" }, + { url = "https://files.pythonhosted.org/packages/68/66/6ab6c1d3a116d05d2508fce64f96e35242938fac07544d611e11d0d363a0/pydantic-1.10.26-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9858ed44c6bea5f29ffe95308db9e62060791c877766c67dd5f55d072c8612b5", size = 2859235, upload-time = "2025-12-18T15:46:45.112Z" }, + { url = "https://files.pythonhosted.org/packages/61/4e/f1676bb0fcdf6ed2ce4670d7d1fc1d6c3a06d84497644acfbe02649503f1/pydantic-1.10.26-cp311-cp311-win_amd64.whl", hash = "sha256:ac1089f723e2106ebde434377d31239e00870a7563245072968e5af5cc4d33df", size = 2066646, upload-time = "2025-12-18T15:46:46.816Z" }, + { url = "https://files.pythonhosted.org/packages/02/6c/cd97a5a776c4515e6ee2ae81c2f2c5be51376dda6c31f965d7746ce0019f/pydantic-1.10.26-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:468d5b9cacfcaadc76ed0a4645354ab6f263ec01a63fb6d05630ea1df6ae453f", size = 2433795, upload-time = "2025-12-18T15:46:49.321Z" }, + { url = "https://files.pythonhosted.org/packages/47/12/de20affa30dcef728fcf9cc98e13ff4438c7a630de8d2f90eb38eba0891c/pydantic-1.10.26-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2c1b0b914be31671000ca25cf7ea17fcaaa68cfeadf6924529c5c5aa24b7ab1f", size = 2227387, upload-time = "2025-12-18T15:46:50.877Z" }, + { url = "https://files.pythonhosted.org/packages/7b/1d/9d65dcc5b8c17ba590f1f9f486e9306346831902318b7ee93f63516f4003/pydantic-1.10.26-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:15b13b9f8ba8867095769e1156e0d7fbafa1f65b898dd40fd1c02e34430973cb", size = 2629594, upload-time = "2025-12-18T15:46:53.42Z" }, + { url = "https://files.pythonhosted.org/packages/3f/76/acb41409356789e23e1a7ef58f93821410c96409183ce314ddb58d97f23e/pydantic-1.10.26-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad7025ca324ae263d4313998e25078dcaec5f9ed0392c06dedb57e053cc8086b", size = 2745305, upload-time = "2025-12-18T15:46:55.987Z" }, + { url = "https://files.pythonhosted.org/packages/22/72/a98c0c5e527a66057d969fedd61675223c7975ade61acebbca9f1abd6dc0/pydantic-1.10.26-cp312-cp312-win_amd64.whl", hash = "sha256:4482b299874dabb88a6c3759e3d85c6557c407c3b586891f7d808d8a38b66b9c", size = 1937647, upload-time = "2025-12-18T15:46:57.905Z" }, + { url = "https://files.pythonhosted.org/packages/28/b9/17a5a5a421c23ac27486b977724a42c9d5f8b7f0f4aab054251066223900/pydantic-1.10.26-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1ae7913bb40a96c87e3d3f6fe4e918ef53bf181583de4e71824360a9b11aef1c", size = 2494599, upload-time = "2025-12-18T15:47:00.209Z" }, + { url = "https://files.pythonhosted.org/packages/e6/8e/6e3bd4241076cf227b443d7577245dd5d181ecf40b3182fcb908bc8c197d/pydantic-1.10.26-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8154c13f58d4de5d3a856bb6c909c7370f41fb876a5952a503af6b975265f4ba", size = 2254391, upload-time = "2025-12-18T15:47:02.268Z" }, + { url = "https://files.pythonhosted.org/packages/a8/30/a1c4092eda2145ecbead6c92db489b223e101e1ba0da82576d0cf73dd422/pydantic-1.10.26-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f8af0507bf6118b054a9765fb2e402f18a8b70c964f420d95b525eb711122d62", size = 2609445, upload-time = "2025-12-18T15:47:04.909Z" }, + { url = "https://files.pythonhosted.org/packages/3a/2a/0491f1729ee4b7b6bc859ec22f69752f0c09bee1b66ac6f5f701136f34c3/pydantic-1.10.26-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:dcb5a7318fb43189fde6af6f21ac7149c4bcbcfffc54bc87b5becddc46084847", size = 2732124, upload-time = "2025-12-18T15:47:07.464Z" }, + { url = "https://files.pythonhosted.org/packages/2a/56/b59f3b2f84e1df2b04ae768a1bb04d9f0288ff71b67cdcbb07683757b2c0/pydantic-1.10.26-cp313-cp313-win_amd64.whl", hash = "sha256:71cde228bc0600cf8619f0ee62db050d1880dcc477eba0e90b23011b4ee0f314", size = 1939888, upload-time = "2025-12-18T15:47:09.618Z" }, + { url = "https://files.pythonhosted.org/packages/d2/8b/0c3dc02d4b97790b0f199bf933f677c14e7be4a8d21307c5f2daae06aa41/pydantic-1.10.26-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:6b40730cc81d53d515dc0b8bb5c9b43fadb9bed46de4a3c03bd95e8571616dba", size = 2502689, upload-time = "2025-12-18T15:47:12.308Z" }, + { url = "https://files.pythonhosted.org/packages/d4/9d/d31aeea45542b2ae4b09ecba92b88aaba696b801c31919811aa979a1242d/pydantic-1.10.26-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c3bbb9c0eecdf599e4db9b372fa9cc55be12e80a0d9c6d307950a39050cb0e37", size = 2269494, upload-time = "2025-12-18T15:47:14.53Z" }, + { url = "https://files.pythonhosted.org/packages/78/c1/3a4d069593283ca4dd0006039ba33644e21e432cddc09da706ac50441610/pydantic-1.10.26-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc2e3fe7bc4993626ef6b6fa855defafa1d6f8996aa1caef2deb83c5ac4d043a", size = 2620047, upload-time = "2025-12-18T15:47:17.089Z" }, + { url = "https://files.pythonhosted.org/packages/e0/0e/340c3d29197d99c15ab04093d43bb9c9d0fd17c2a34b80cb9d36ed732b09/pydantic-1.10.26-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:36d9e46b588aaeb1dcd2409fa4c467fe0b331f3cc9f227b03a7a00643704e962", size = 2747625, upload-time = "2025-12-18T15:47:19.21Z" }, + { url = "https://files.pythonhosted.org/packages/1e/58/f12ab3727339b172c830b32151919456b67787cdfe8808b2568b322fb15c/pydantic-1.10.26-cp314-cp314-win_amd64.whl", hash = "sha256:81ce3c8616d12a7be31b4aadfd3434f78f6b44b75adbfaec2fe1ad4f7f999b8c", size = 1976436, upload-time = "2025-12-18T15:47:21.384Z" }, + { url = "https://files.pythonhosted.org/packages/e1/8a/3a5a6267d5f03617b5c0f1985aa9fdfbafd33a50ef6dadd866a15ed4d123/pydantic-1.10.26-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:502b9d30d18a2dfaf81b7302f6ba0e5853474b1c96212449eb4db912cb604b7d", size = 2457039, upload-time = "2025-12-18T15:47:34.584Z" }, + { url = "https://files.pythonhosted.org/packages/f3/fa/343ac0db26918a033ac6256c036d72c3b6eb1196b7de622e2e8a94b19079/pydantic-1.10.26-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0d8f6087bf697dec3bf7ffcd7fe8362674f16519f3151789f33cbe8f1d19fc15", size = 2266441, upload-time = "2025-12-18T15:47:36.807Z" }, + { url = "https://files.pythonhosted.org/packages/fc/36/1ab48136578608dba2f2a62e452f3db2083b474d4e49be5749c6ae0c123c/pydantic-1.10.26-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:dd40a99c358419910c85e6f5d22f9c56684c25b5e7abc40879b3b4a52f34ae90", size = 2869383, upload-time = "2025-12-18T15:47:38.883Z" }, + { url = "https://files.pythonhosted.org/packages/a2/25/41dbf1bffc31eb242cece8080561a4133eaeb513372dec36a84477a3fb71/pydantic-1.10.26-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ce3293b86ca9f4125df02ff0a70be91bc7946522467cbd98e7f1493f340616ba", size = 2963582, upload-time = "2025-12-18T15:47:40.854Z" }, + { url = "https://files.pythonhosted.org/packages/61/2f/f072ae160a300c85eb9f059915101fd33dacf12d8df08c2b804acb3b95d1/pydantic-1.10.26-cp39-cp39-win_amd64.whl", hash = "sha256:1a4e3062b71ab1d5df339ba12c48f9ed5817c5de6cb92a961dd5c64bb32e7b96", size = 2075530, upload-time = "2025-12-18T15:47:43.181Z" }, + { url = "https://files.pythonhosted.org/packages/1f/98/556e82f00b98486def0b8af85da95e69d2be7e367cf2431408e108bc3095/pydantic-1.10.26-py3-none-any.whl", hash = "sha256:c43ad70dc3ce7787543d563792426a16fd7895e14be4b194b5665e36459dd917", size = 166975, upload-time = "2025-12-18T15:47:44.927Z" }, +] + +[[package]] +name = "pydantic" +version = "2.12.5" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14' and extra != 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2'", + "python_full_version >= '3.10' and python_full_version < '3.14' and extra != 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2'", + "python_full_version < '3.10' and extra != 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2'", + "python_full_version >= '3.10' and extra != 'group-11-phoebe-bird-pydantic-v1' and extra != 'group-11-phoebe-bird-pydantic-v2'", + "python_full_version < '3.10' and extra != 'group-11-phoebe-bird-pydantic-v1' and extra != 'group-11-phoebe-bird-pydantic-v2'", +] +dependencies = [ + { name = "annotated-types", marker = "extra == 'group-11-phoebe-bird-pydantic-v2' or extra != 'group-11-phoebe-bird-pydantic-v1'" }, + { name = "pydantic-core", marker = "extra == 'group-11-phoebe-bird-pydantic-v2' or extra != 'group-11-phoebe-bird-pydantic-v1'" }, + { name = "typing-extensions", marker = "extra == 'group-11-phoebe-bird-pydantic-v2' or extra != 'group-11-phoebe-bird-pydantic-v1'" }, + { name = "typing-inspection", marker = "extra == 'group-11-phoebe-bird-pydantic-v2' or extra != 'group-11-phoebe-bird-pydantic-v1'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/69/44/36f1a6e523abc58ae5f928898e4aca2e0ea509b5aa6f6f392a5d882be928/pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49", size = 821591, upload-time = "2025-11-26T15:11:46.471Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d", size = 463580, upload-time = "2025-11-26T15:11:44.605Z" }, +] + +[[package]] +name = "pydantic-core" +version = "2.41.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "extra == 'group-11-phoebe-bird-pydantic-v2' or extra != 'group-11-phoebe-bird-pydantic-v1'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/71/70/23b021c950c2addd24ec408e9ab05d59b035b39d97cdc1130e1bce647bb6/pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e", size = 460952, upload-time = "2025-11-04T13:43:49.098Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c6/90/32c9941e728d564b411d574d8ee0cf09b12ec978cb22b294995bae5549a5/pydantic_core-2.41.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146", size = 2107298, upload-time = "2025-11-04T13:39:04.116Z" }, + { url = "https://files.pythonhosted.org/packages/fb/a8/61c96a77fe28993d9a6fb0f4127e05430a267b235a124545d79fea46dd65/pydantic_core-2.41.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2", size = 1901475, upload-time = "2025-11-04T13:39:06.055Z" }, + { url = "https://files.pythonhosted.org/packages/5d/b6/338abf60225acc18cdc08b4faef592d0310923d19a87fba1faf05af5346e/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5921a4d3ca3aee735d9fd163808f5e8dd6c6972101e4adbda9a4667908849b97", size = 1918815, upload-time = "2025-11-04T13:39:10.41Z" }, + { url = "https://files.pythonhosted.org/packages/d1/1c/2ed0433e682983d8e8cba9c8d8ef274d4791ec6a6f24c58935b90e780e0a/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e25c479382d26a2a41b7ebea1043564a937db462816ea07afa8a44c0866d52f9", size = 2065567, upload-time = "2025-11-04T13:39:12.244Z" }, + { url = "https://files.pythonhosted.org/packages/b3/24/cf84974ee7d6eae06b9e63289b7b8f6549d416b5c199ca2d7ce13bbcf619/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f547144f2966e1e16ae626d8ce72b4cfa0caedc7fa28052001c94fb2fcaa1c52", size = 2230442, upload-time = "2025-11-04T13:39:13.962Z" }, + { url = "https://files.pythonhosted.org/packages/fd/21/4e287865504b3edc0136c89c9c09431be326168b1eb7841911cbc877a995/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f52298fbd394f9ed112d56f3d11aabd0d5bd27beb3084cc3d8ad069483b8941", size = 2350956, upload-time = "2025-11-04T13:39:15.889Z" }, + { url = "https://files.pythonhosted.org/packages/a8/76/7727ef2ffa4b62fcab916686a68a0426b9b790139720e1934e8ba797e238/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a", size = 2068253, upload-time = "2025-11-04T13:39:17.403Z" }, + { url = "https://files.pythonhosted.org/packages/d5/8c/a4abfc79604bcb4c748e18975c44f94f756f08fb04218d5cb87eb0d3a63e/pydantic_core-2.41.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:05a2c8852530ad2812cb7914dc61a1125dc4e06252ee98e5638a12da6cc6fb6c", size = 2177050, upload-time = "2025-11-04T13:39:19.351Z" }, + { url = "https://files.pythonhosted.org/packages/67/b1/de2e9a9a79b480f9cb0b6e8b6ba4c50b18d4e89852426364c66aa82bb7b3/pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:29452c56df2ed968d18d7e21f4ab0ac55e71dc59524872f6fc57dcf4a3249ed2", size = 2147178, upload-time = "2025-11-04T13:39:21Z" }, + { url = "https://files.pythonhosted.org/packages/16/c1/dfb33f837a47b20417500efaa0378adc6635b3c79e8369ff7a03c494b4ac/pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:d5160812ea7a8a2ffbe233d8da666880cad0cbaf5d4de74ae15c313213d62556", size = 2341833, upload-time = "2025-11-04T13:39:22.606Z" }, + { url = "https://files.pythonhosted.org/packages/47/36/00f398642a0f4b815a9a558c4f1dca1b4020a7d49562807d7bc9ff279a6c/pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:df3959765b553b9440adfd3c795617c352154e497a4eaf3752555cfb5da8fc49", size = 2321156, upload-time = "2025-11-04T13:39:25.843Z" }, + { url = "https://files.pythonhosted.org/packages/7e/70/cad3acd89fde2010807354d978725ae111ddf6d0ea46d1ea1775b5c1bd0c/pydantic_core-2.41.5-cp310-cp310-win32.whl", hash = "sha256:1f8d33a7f4d5a7889e60dc39856d76d09333d8a6ed0f5f1190635cbec70ec4ba", size = 1989378, upload-time = "2025-11-04T13:39:27.92Z" }, + { url = "https://files.pythonhosted.org/packages/76/92/d338652464c6c367e5608e4488201702cd1cbb0f33f7b6a85a60fe5f3720/pydantic_core-2.41.5-cp310-cp310-win_amd64.whl", hash = "sha256:62de39db01b8d593e45871af2af9e497295db8d73b085f6bfd0b18c83c70a8f9", size = 2013622, upload-time = "2025-11-04T13:39:29.848Z" }, + { url = "https://files.pythonhosted.org/packages/e8/72/74a989dd9f2084b3d9530b0915fdda64ac48831c30dbf7c72a41a5232db8/pydantic_core-2.41.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6", size = 2105873, upload-time = "2025-11-04T13:39:31.373Z" }, + { url = "https://files.pythonhosted.org/packages/12/44/37e403fd9455708b3b942949e1d7febc02167662bf1a7da5b78ee1ea2842/pydantic_core-2.41.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b", size = 1899826, upload-time = "2025-11-04T13:39:32.897Z" }, + { url = "https://files.pythonhosted.org/packages/33/7f/1d5cab3ccf44c1935a359d51a8a2a9e1a654b744b5e7f80d41b88d501eec/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a", size = 1917869, upload-time = "2025-11-04T13:39:34.469Z" }, + { url = "https://files.pythonhosted.org/packages/6e/6a/30d94a9674a7fe4f4744052ed6c5e083424510be1e93da5bc47569d11810/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8", size = 2063890, upload-time = "2025-11-04T13:39:36.053Z" }, + { url = "https://files.pythonhosted.org/packages/50/be/76e5d46203fcb2750e542f32e6c371ffa9b8ad17364cf94bb0818dbfb50c/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e", size = 2229740, upload-time = "2025-11-04T13:39:37.753Z" }, + { url = "https://files.pythonhosted.org/packages/d3/ee/fed784df0144793489f87db310a6bbf8118d7b630ed07aa180d6067e653a/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1", size = 2350021, upload-time = "2025-11-04T13:39:40.94Z" }, + { url = "https://files.pythonhosted.org/packages/c8/be/8fed28dd0a180dca19e72c233cbf58efa36df055e5b9d90d64fd1740b828/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b", size = 2066378, upload-time = "2025-11-04T13:39:42.523Z" }, + { url = "https://files.pythonhosted.org/packages/b0/3b/698cf8ae1d536a010e05121b4958b1257f0b5522085e335360e53a6b1c8b/pydantic_core-2.41.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b", size = 2175761, upload-time = "2025-11-04T13:39:44.553Z" }, + { url = "https://files.pythonhosted.org/packages/b8/ba/15d537423939553116dea94ce02f9c31be0fa9d0b806d427e0308ec17145/pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284", size = 2146303, upload-time = "2025-11-04T13:39:46.238Z" }, + { url = "https://files.pythonhosted.org/packages/58/7f/0de669bf37d206723795f9c90c82966726a2ab06c336deba4735b55af431/pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594", size = 2340355, upload-time = "2025-11-04T13:39:48.002Z" }, + { url = "https://files.pythonhosted.org/packages/e5/de/e7482c435b83d7e3c3ee5ee4451f6e8973cff0eb6007d2872ce6383f6398/pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e", size = 2319875, upload-time = "2025-11-04T13:39:49.705Z" }, + { url = "https://files.pythonhosted.org/packages/fe/e6/8c9e81bb6dd7560e33b9053351c29f30c8194b72f2d6932888581f503482/pydantic_core-2.41.5-cp311-cp311-win32.whl", hash = "sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b", size = 1987549, upload-time = "2025-11-04T13:39:51.842Z" }, + { url = "https://files.pythonhosted.org/packages/11/66/f14d1d978ea94d1bc21fc98fcf570f9542fe55bfcc40269d4e1a21c19bf7/pydantic_core-2.41.5-cp311-cp311-win_amd64.whl", hash = "sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe", size = 2011305, upload-time = "2025-11-04T13:39:53.485Z" }, + { url = "https://files.pythonhosted.org/packages/56/d8/0e271434e8efd03186c5386671328154ee349ff0354d83c74f5caaf096ed/pydantic_core-2.41.5-cp311-cp311-win_arm64.whl", hash = "sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f", size = 1972902, upload-time = "2025-11-04T13:39:56.488Z" }, + { url = "https://files.pythonhosted.org/packages/5f/5d/5f6c63eebb5afee93bcaae4ce9a898f3373ca23df3ccaef086d0233a35a7/pydantic_core-2.41.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7", size = 2110990, upload-time = "2025-11-04T13:39:58.079Z" }, + { url = "https://files.pythonhosted.org/packages/aa/32/9c2e8ccb57c01111e0fd091f236c7b371c1bccea0fa85247ac55b1e2b6b6/pydantic_core-2.41.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0", size = 1896003, upload-time = "2025-11-04T13:39:59.956Z" }, + { url = "https://files.pythonhosted.org/packages/68/b8/a01b53cb0e59139fbc9e4fda3e9724ede8de279097179be4ff31f1abb65a/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69", size = 1919200, upload-time = "2025-11-04T13:40:02.241Z" }, + { url = "https://files.pythonhosted.org/packages/38/de/8c36b5198a29bdaade07b5985e80a233a5ac27137846f3bc2d3b40a47360/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75", size = 2052578, upload-time = "2025-11-04T13:40:04.401Z" }, + { url = "https://files.pythonhosted.org/packages/00/b5/0e8e4b5b081eac6cb3dbb7e60a65907549a1ce035a724368c330112adfdd/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05", size = 2208504, upload-time = "2025-11-04T13:40:06.072Z" }, + { url = "https://files.pythonhosted.org/packages/77/56/87a61aad59c7c5b9dc8caad5a41a5545cba3810c3e828708b3d7404f6cef/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc", size = 2335816, upload-time = "2025-11-04T13:40:07.835Z" }, + { url = "https://files.pythonhosted.org/packages/0d/76/941cc9f73529988688a665a5c0ecff1112b3d95ab48f81db5f7606f522d3/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c", size = 2075366, upload-time = "2025-11-04T13:40:09.804Z" }, + { url = "https://files.pythonhosted.org/packages/d3/43/ebef01f69baa07a482844faaa0a591bad1ef129253ffd0cdaa9d8a7f72d3/pydantic_core-2.41.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5", size = 2171698, upload-time = "2025-11-04T13:40:12.004Z" }, + { url = "https://files.pythonhosted.org/packages/b1/87/41f3202e4193e3bacfc2c065fab7706ebe81af46a83d3e27605029c1f5a6/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c", size = 2132603, upload-time = "2025-11-04T13:40:13.868Z" }, + { url = "https://files.pythonhosted.org/packages/49/7d/4c00df99cb12070b6bccdef4a195255e6020a550d572768d92cc54dba91a/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294", size = 2329591, upload-time = "2025-11-04T13:40:15.672Z" }, + { url = "https://files.pythonhosted.org/packages/cc/6a/ebf4b1d65d458f3cda6a7335d141305dfa19bdc61140a884d165a8a1bbc7/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1", size = 2319068, upload-time = "2025-11-04T13:40:17.532Z" }, + { url = "https://files.pythonhosted.org/packages/49/3b/774f2b5cd4192d5ab75870ce4381fd89cf218af999515baf07e7206753f0/pydantic_core-2.41.5-cp312-cp312-win32.whl", hash = "sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d", size = 1985908, upload-time = "2025-11-04T13:40:19.309Z" }, + { url = "https://files.pythonhosted.org/packages/86/45/00173a033c801cacf67c190fef088789394feaf88a98a7035b0e40d53dc9/pydantic_core-2.41.5-cp312-cp312-win_amd64.whl", hash = "sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815", size = 2020145, upload-time = "2025-11-04T13:40:21.548Z" }, + { url = "https://files.pythonhosted.org/packages/f9/22/91fbc821fa6d261b376a3f73809f907cec5ca6025642c463d3488aad22fb/pydantic_core-2.41.5-cp312-cp312-win_arm64.whl", hash = "sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3", size = 1976179, upload-time = "2025-11-04T13:40:23.393Z" }, + { url = "https://files.pythonhosted.org/packages/87/06/8806241ff1f70d9939f9af039c6c35f2360cf16e93c2ca76f184e76b1564/pydantic_core-2.41.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9", size = 2120403, upload-time = "2025-11-04T13:40:25.248Z" }, + { url = "https://files.pythonhosted.org/packages/94/02/abfa0e0bda67faa65fef1c84971c7e45928e108fe24333c81f3bfe35d5f5/pydantic_core-2.41.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34", size = 1896206, upload-time = "2025-11-04T13:40:27.099Z" }, + { url = "https://files.pythonhosted.org/packages/15/df/a4c740c0943e93e6500f9eb23f4ca7ec9bf71b19e608ae5b579678c8d02f/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0", size = 1919307, upload-time = "2025-11-04T13:40:29.806Z" }, + { url = "https://files.pythonhosted.org/packages/9a/e3/6324802931ae1d123528988e0e86587c2072ac2e5394b4bc2bc34b61ff6e/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33", size = 2063258, upload-time = "2025-11-04T13:40:33.544Z" }, + { url = "https://files.pythonhosted.org/packages/c9/d4/2230d7151d4957dd79c3044ea26346c148c98fbf0ee6ebd41056f2d62ab5/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e", size = 2214917, upload-time = "2025-11-04T13:40:35.479Z" }, + { url = "https://files.pythonhosted.org/packages/e6/9f/eaac5df17a3672fef0081b6c1bb0b82b33ee89aa5cec0d7b05f52fd4a1fa/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2", size = 2332186, upload-time = "2025-11-04T13:40:37.436Z" }, + { url = "https://files.pythonhosted.org/packages/cf/4e/35a80cae583a37cf15604b44240e45c05e04e86f9cfd766623149297e971/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586", size = 2073164, upload-time = "2025-11-04T13:40:40.289Z" }, + { url = "https://files.pythonhosted.org/packages/bf/e3/f6e262673c6140dd3305d144d032f7bd5f7497d3871c1428521f19f9efa2/pydantic_core-2.41.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d", size = 2179146, upload-time = "2025-11-04T13:40:42.809Z" }, + { url = "https://files.pythonhosted.org/packages/75/c7/20bd7fc05f0c6ea2056a4565c6f36f8968c0924f19b7d97bbfea55780e73/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740", size = 2137788, upload-time = "2025-11-04T13:40:44.752Z" }, + { url = "https://files.pythonhosted.org/packages/3a/8d/34318ef985c45196e004bc46c6eab2eda437e744c124ef0dbe1ff2c9d06b/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e", size = 2340133, upload-time = "2025-11-04T13:40:46.66Z" }, + { url = "https://files.pythonhosted.org/packages/9c/59/013626bf8c78a5a5d9350d12e7697d3d4de951a75565496abd40ccd46bee/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858", size = 2324852, upload-time = "2025-11-04T13:40:48.575Z" }, + { url = "https://files.pythonhosted.org/packages/1a/d9/c248c103856f807ef70c18a4f986693a46a8ffe1602e5d361485da502d20/pydantic_core-2.41.5-cp313-cp313-win32.whl", hash = "sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36", size = 1994679, upload-time = "2025-11-04T13:40:50.619Z" }, + { url = "https://files.pythonhosted.org/packages/9e/8b/341991b158ddab181cff136acd2552c9f35bd30380422a639c0671e99a91/pydantic_core-2.41.5-cp313-cp313-win_amd64.whl", hash = "sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11", size = 2019766, upload-time = "2025-11-04T13:40:52.631Z" }, + { url = "https://files.pythonhosted.org/packages/73/7d/f2f9db34af103bea3e09735bb40b021788a5e834c81eedb541991badf8f5/pydantic_core-2.41.5-cp313-cp313-win_arm64.whl", hash = "sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd", size = 1981005, upload-time = "2025-11-04T13:40:54.734Z" }, + { url = "https://files.pythonhosted.org/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a", size = 2119622, upload-time = "2025-11-04T13:40:56.68Z" }, + { url = "https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14", size = 1891725, upload-time = "2025-11-04T13:40:58.807Z" }, + { url = "https://files.pythonhosted.org/packages/23/04/e89c29e267b8060b40dca97bfc64a19b2a3cf99018167ea1677d96368273/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1", size = 1915040, upload-time = "2025-11-04T13:41:00.853Z" }, + { url = "https://files.pythonhosted.org/packages/84/a3/15a82ac7bd97992a82257f777b3583d3e84bdb06ba6858f745daa2ec8a85/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66", size = 2063691, upload-time = "2025-11-04T13:41:03.504Z" }, + { url = "https://files.pythonhosted.org/packages/74/9b/0046701313c6ef08c0c1cf0e028c67c770a4e1275ca73131563c5f2a310a/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869", size = 2213897, upload-time = "2025-11-04T13:41:05.804Z" }, + { url = "https://files.pythonhosted.org/packages/8a/cd/6bac76ecd1b27e75a95ca3a9a559c643b3afcd2dd62086d4b7a32a18b169/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2", size = 2333302, upload-time = "2025-11-04T13:41:07.809Z" }, + { url = "https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375", size = 2064877, upload-time = "2025-11-04T13:41:09.827Z" }, + { url = "https://files.pythonhosted.org/packages/18/66/e9db17a9a763d72f03de903883c057b2592c09509ccfe468187f2a2eef29/pydantic_core-2.41.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553", size = 2180680, upload-time = "2025-11-04T13:41:12.379Z" }, + { url = "https://files.pythonhosted.org/packages/d3/9e/3ce66cebb929f3ced22be85d4c2399b8e85b622db77dad36b73c5387f8f8/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90", size = 2138960, upload-time = "2025-11-04T13:41:14.627Z" }, + { url = "https://files.pythonhosted.org/packages/a6/62/205a998f4327d2079326b01abee48e502ea739d174f0a89295c481a2272e/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07", size = 2339102, upload-time = "2025-11-04T13:41:16.868Z" }, + { url = "https://files.pythonhosted.org/packages/3c/0d/f05e79471e889d74d3d88f5bd20d0ed189ad94c2423d81ff8d0000aab4ff/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb", size = 2326039, upload-time = "2025-11-04T13:41:18.934Z" }, + { url = "https://files.pythonhosted.org/packages/ec/e1/e08a6208bb100da7e0c4b288eed624a703f4d129bde2da475721a80cab32/pydantic_core-2.41.5-cp314-cp314-win32.whl", hash = "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23", size = 1995126, upload-time = "2025-11-04T13:41:21.418Z" }, + { url = "https://files.pythonhosted.org/packages/48/5d/56ba7b24e9557f99c9237e29f5c09913c81eeb2f3217e40e922353668092/pydantic_core-2.41.5-cp314-cp314-win_amd64.whl", hash = "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf", size = 2015489, upload-time = "2025-11-04T13:41:24.076Z" }, + { url = "https://files.pythonhosted.org/packages/4e/bb/f7a190991ec9e3e0ba22e4993d8755bbc4a32925c0b5b42775c03e8148f9/pydantic_core-2.41.5-cp314-cp314-win_arm64.whl", hash = "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0", size = 1977288, upload-time = "2025-11-04T13:41:26.33Z" }, + { url = "https://files.pythonhosted.org/packages/92/ed/77542d0c51538e32e15afe7899d79efce4b81eee631d99850edc2f5e9349/pydantic_core-2.41.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a", size = 2120255, upload-time = "2025-11-04T13:41:28.569Z" }, + { url = "https://files.pythonhosted.org/packages/bb/3d/6913dde84d5be21e284439676168b28d8bbba5600d838b9dca99de0fad71/pydantic_core-2.41.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3", size = 1863760, upload-time = "2025-11-04T13:41:31.055Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f0/e5e6b99d4191da102f2b0eb9687aaa7f5bea5d9964071a84effc3e40f997/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c", size = 1878092, upload-time = "2025-11-04T13:41:33.21Z" }, + { url = "https://files.pythonhosted.org/packages/71/48/36fb760642d568925953bcc8116455513d6e34c4beaa37544118c36aba6d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612", size = 2053385, upload-time = "2025-11-04T13:41:35.508Z" }, + { url = "https://files.pythonhosted.org/packages/20/25/92dc684dd8eb75a234bc1c764b4210cf2646479d54b47bf46061657292a8/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d", size = 2218832, upload-time = "2025-11-04T13:41:37.732Z" }, + { url = "https://files.pythonhosted.org/packages/e2/09/f53e0b05023d3e30357d82eb35835d0f6340ca344720a4599cd663dca599/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9", size = 2327585, upload-time = "2025-11-04T13:41:40Z" }, + { url = "https://files.pythonhosted.org/packages/aa/4e/2ae1aa85d6af35a39b236b1b1641de73f5a6ac4d5a7509f77b814885760c/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660", size = 2041078, upload-time = "2025-11-04T13:41:42.323Z" }, + { url = "https://files.pythonhosted.org/packages/cd/13/2e215f17f0ef326fc72afe94776edb77525142c693767fc347ed6288728d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9", size = 2173914, upload-time = "2025-11-04T13:41:45.221Z" }, + { url = "https://files.pythonhosted.org/packages/02/7a/f999a6dcbcd0e5660bc348a3991c8915ce6599f4f2c6ac22f01d7a10816c/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3", size = 2129560, upload-time = "2025-11-04T13:41:47.474Z" }, + { url = "https://files.pythonhosted.org/packages/3a/b1/6c990ac65e3b4c079a4fb9f5b05f5b013afa0f4ed6780a3dd236d2cbdc64/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf", size = 2329244, upload-time = "2025-11-04T13:41:49.992Z" }, + { url = "https://files.pythonhosted.org/packages/d9/02/3c562f3a51afd4d88fff8dffb1771b30cfdfd79befd9883ee094f5b6c0d8/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470", size = 2331955, upload-time = "2025-11-04T13:41:54.079Z" }, + { url = "https://files.pythonhosted.org/packages/5c/96/5fb7d8c3c17bc8c62fdb031c47d77a1af698f1d7a406b0f79aaa1338f9ad/pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa", size = 1988906, upload-time = "2025-11-04T13:41:56.606Z" }, + { url = "https://files.pythonhosted.org/packages/22/ed/182129d83032702912c2e2d8bbe33c036f342cc735737064668585dac28f/pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c", size = 1981607, upload-time = "2025-11-04T13:41:58.889Z" }, + { url = "https://files.pythonhosted.org/packages/9f/ed/068e41660b832bb0b1aa5b58011dea2a3fe0ba7861ff38c4d4904c1c1a99/pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008", size = 1974769, upload-time = "2025-11-04T13:42:01.186Z" }, + { url = "https://files.pythonhosted.org/packages/54/db/160dffb57ed9a3705c4cbcbff0ac03bdae45f1ca7d58ab74645550df3fbd/pydantic_core-2.41.5-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:8bfeaf8735be79f225f3fefab7f941c712aaca36f1128c9d7e2352ee1aa87bdf", size = 2107999, upload-time = "2025-11-04T13:42:03.885Z" }, + { url = "https://files.pythonhosted.org/packages/a3/7d/88e7de946f60d9263cc84819f32513520b85c0f8322f9b8f6e4afc938383/pydantic_core-2.41.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:346285d28e4c8017da95144c7f3acd42740d637ff41946af5ce6e5e420502dd5", size = 1929745, upload-time = "2025-11-04T13:42:06.075Z" }, + { url = "https://files.pythonhosted.org/packages/d5/c2/aef51e5b283780e85e99ff19db0f05842d2d4a8a8cd15e63b0280029b08f/pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a75dafbf87d6276ddc5b2bf6fae5254e3d0876b626eb24969a574fff9149ee5d", size = 1920220, upload-time = "2025-11-04T13:42:08.457Z" }, + { url = "https://files.pythonhosted.org/packages/c7/97/492ab10f9ac8695cd76b2fdb24e9e61f394051df71594e9bcc891c9f586e/pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7b93a4d08587e2b7e7882de461e82b6ed76d9026ce91ca7915e740ecc7855f60", size = 2067296, upload-time = "2025-11-04T13:42:10.817Z" }, + { url = "https://files.pythonhosted.org/packages/ec/23/984149650e5269c59a2a4c41d234a9570adc68ab29981825cfaf4cfad8f4/pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8465ab91a4bd96d36dde3263f06caa6a8a6019e4113f24dc753d79a8b3a3f82", size = 2231548, upload-time = "2025-11-04T13:42:13.843Z" }, + { url = "https://files.pythonhosted.org/packages/71/0c/85bcbb885b9732c28bec67a222dbed5ed2d77baee1f8bba2002e8cd00c5c/pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:299e0a22e7ae2b85c1a57f104538b2656e8ab1873511fd718a1c1c6f149b77b5", size = 2362571, upload-time = "2025-11-04T13:42:16.208Z" }, + { url = "https://files.pythonhosted.org/packages/c0/4a/412d2048be12c334003e9b823a3fa3d038e46cc2d64dd8aab50b31b65499/pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:707625ef0983fcfb461acfaf14de2067c5942c6bb0f3b4c99158bed6fedd3cf3", size = 2068175, upload-time = "2025-11-04T13:42:18.911Z" }, + { url = "https://files.pythonhosted.org/packages/73/f4/c58b6a776b502d0a5540ad02e232514285513572060f0d78f7832ca3c98b/pydantic_core-2.41.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f41eb9797986d6ebac5e8edff36d5cef9de40def462311b3eb3eeded1431e425", size = 2177203, upload-time = "2025-11-04T13:42:22.578Z" }, + { url = "https://files.pythonhosted.org/packages/ed/ae/f06ea4c7e7a9eead3d165e7623cd2ea0cb788e277e4f935af63fc98fa4e6/pydantic_core-2.41.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0384e2e1021894b1ff5a786dbf94771e2986ebe2869533874d7e43bc79c6f504", size = 2148191, upload-time = "2025-11-04T13:42:24.89Z" }, + { url = "https://files.pythonhosted.org/packages/c1/57/25a11dcdc656bf5f8b05902c3c2934ac3ea296257cc4a3f79a6319e61856/pydantic_core-2.41.5-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:f0cd744688278965817fd0839c4a4116add48d23890d468bc436f78beb28abf5", size = 2343907, upload-time = "2025-11-04T13:42:27.683Z" }, + { url = "https://files.pythonhosted.org/packages/96/82/e33d5f4933d7a03327c0c43c65d575e5919d4974ffc026bc917a5f7b9f61/pydantic_core-2.41.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:753e230374206729bf0a807954bcc6c150d3743928a73faffee51ac6557a03c3", size = 2322174, upload-time = "2025-11-04T13:42:30.776Z" }, + { url = "https://files.pythonhosted.org/packages/81/45/4091be67ce9f469e81656f880f3506f6a5624121ec5eb3eab37d7581897d/pydantic_core-2.41.5-cp39-cp39-win32.whl", hash = "sha256:873e0d5b4fb9b89ef7c2d2a963ea7d02879d9da0da8d9d4933dee8ee86a8b460", size = 1990353, upload-time = "2025-11-04T13:42:33.111Z" }, + { url = "https://files.pythonhosted.org/packages/44/8a/a98aede18db6e9cd5d66bcacd8a409fcf8134204cdede2e7de35c5a2c5ef/pydantic_core-2.41.5-cp39-cp39-win_amd64.whl", hash = "sha256:e4f4a984405e91527a0d62649ee21138f8e3d0ef103be488c1dc11a80d7f184b", size = 2015698, upload-time = "2025-11-04T13:42:35.484Z" }, + { url = "https://files.pythonhosted.org/packages/11/72/90fda5ee3b97e51c494938a4a44c3a35a9c96c19bba12372fb9c634d6f57/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034", size = 2115441, upload-time = "2025-11-04T13:42:39.557Z" }, + { url = "https://files.pythonhosted.org/packages/1f/53/8942f884fa33f50794f119012dc6a1a02ac43a56407adaac20463df8e98f/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c", size = 1930291, upload-time = "2025-11-04T13:42:42.169Z" }, + { url = "https://files.pythonhosted.org/packages/79/c8/ecb9ed9cd942bce09fc888ee960b52654fbdbede4ba6c2d6e0d3b1d8b49c/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2", size = 1948632, upload-time = "2025-11-04T13:42:44.564Z" }, + { url = "https://files.pythonhosted.org/packages/2e/1b/687711069de7efa6af934e74f601e2a4307365e8fdc404703afc453eab26/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad", size = 2138905, upload-time = "2025-11-04T13:42:47.156Z" }, + { url = "https://files.pythonhosted.org/packages/09/32/59b0c7e63e277fa7911c2fc70ccfb45ce4b98991e7ef37110663437005af/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd", size = 2110495, upload-time = "2025-11-04T13:42:49.689Z" }, + { url = "https://files.pythonhosted.org/packages/aa/81/05e400037eaf55ad400bcd318c05bb345b57e708887f07ddb2d20e3f0e98/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc", size = 1915388, upload-time = "2025-11-04T13:42:52.215Z" }, + { url = "https://files.pythonhosted.org/packages/6e/0d/e3549b2399f71d56476b77dbf3cf8937cec5cd70536bdc0e374a421d0599/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56", size = 1942879, upload-time = "2025-11-04T13:42:56.483Z" }, + { url = "https://files.pythonhosted.org/packages/f7/07/34573da085946b6a313d7c42f82f16e8920bfd730665de2d11c0c37a74b5/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b", size = 2139017, upload-time = "2025-11-04T13:42:59.471Z" }, + { url = "https://files.pythonhosted.org/packages/e6/b0/1a2aa41e3b5a4ba11420aba2d091b2d17959c8d1519ece3627c371951e73/pydantic_core-2.41.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8", size = 2103351, upload-time = "2025-11-04T13:43:02.058Z" }, + { url = "https://files.pythonhosted.org/packages/a4/ee/31b1f0020baaf6d091c87900ae05c6aeae101fa4e188e1613c80e4f1ea31/pydantic_core-2.41.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a", size = 1925363, upload-time = "2025-11-04T13:43:05.159Z" }, + { url = "https://files.pythonhosted.org/packages/e1/89/ab8e86208467e467a80deaca4e434adac37b10a9d134cd2f99b28a01e483/pydantic_core-2.41.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b", size = 2135615, upload-time = "2025-11-04T13:43:08.116Z" }, + { url = "https://files.pythonhosted.org/packages/99/0a/99a53d06dd0348b2008f2f30884b34719c323f16c3be4e6cc1203b74a91d/pydantic_core-2.41.5-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:16f80f7abe3351f8ea6858914ddc8c77e02578544a0ebc15b4c2e1a0e813b0b2", size = 2175369, upload-time = "2025-11-04T13:43:12.49Z" }, + { url = "https://files.pythonhosted.org/packages/6d/94/30ca3b73c6d485b9bb0bc66e611cff4a7138ff9736b7e66bcf0852151636/pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:33cb885e759a705b426baada1fe68cbb0a2e68e34c5d0d0289a364cf01709093", size = 2144218, upload-time = "2025-11-04T13:43:15.431Z" }, + { url = "https://files.pythonhosted.org/packages/87/57/31b4f8e12680b739a91f472b5671294236b82586889ef764b5fbc6669238/pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:c8d8b4eb992936023be7dee581270af5c6e0697a8559895f527f5b7105ecd36a", size = 2329951, upload-time = "2025-11-04T13:43:18.062Z" }, + { url = "https://files.pythonhosted.org/packages/7d/73/3c2c8edef77b8f7310e6fb012dbc4b8551386ed575b9eb6fb2506e28a7eb/pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:242a206cd0318f95cd21bdacff3fcc3aab23e79bba5cac3db5a841c9ef9c6963", size = 2318428, upload-time = "2025-11-04T13:43:20.679Z" }, + { url = "https://files.pythonhosted.org/packages/2f/02/8559b1f26ee0d502c74f9cca5c0d2fd97e967e083e006bbbb4e97f3a043a/pydantic_core-2.41.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d3a978c4f57a597908b7e697229d996d77a6d3c94901e9edee593adada95ce1a", size = 2147009, upload-time = "2025-11-04T13:43:23.286Z" }, + { url = "https://files.pythonhosted.org/packages/5f/9b/1b3f0e9f9305839d7e84912f9e8bfbd191ed1b1ef48083609f0dabde978c/pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26", size = 2101980, upload-time = "2025-11-04T13:43:25.97Z" }, + { url = "https://files.pythonhosted.org/packages/a4/ed/d71fefcb4263df0da6a85b5d8a7508360f2f2e9b3bf5814be9c8bccdccc1/pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808", size = 1923865, upload-time = "2025-11-04T13:43:28.763Z" }, + { url = "https://files.pythonhosted.org/packages/ce/3a/626b38db460d675f873e4444b4bb030453bbe7b4ba55df821d026a0493c4/pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc", size = 2134256, upload-time = "2025-11-04T13:43:31.71Z" }, + { url = "https://files.pythonhosted.org/packages/83/d9/8412d7f06f616bbc053d30cb4e5f76786af3221462ad5eee1f202021eb4e/pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1", size = 2174762, upload-time = "2025-11-04T13:43:34.744Z" }, + { url = "https://files.pythonhosted.org/packages/55/4c/162d906b8e3ba3a99354e20faa1b49a85206c47de97a639510a0e673f5da/pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84", size = 2143141, upload-time = "2025-11-04T13:43:37.701Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f2/f11dd73284122713f5f89fc940f370d035fa8e1e078d446b3313955157fe/pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770", size = 2330317, upload-time = "2025-11-04T13:43:40.406Z" }, + { url = "https://files.pythonhosted.org/packages/88/9d/b06ca6acfe4abb296110fb1273a4d848a0bfb2ff65f3ee92127b3244e16b/pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f", size = 2316992, upload-time = "2025-11-04T13:43:43.602Z" }, + { url = "https://files.pythonhosted.org/packages/36/c7/cfc8e811f061c841d7990b0201912c3556bfeb99cdcb7ed24adc8d6f8704/pydantic_core-2.41.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51", size = 2145302, upload-time = "2025-11-04T13:43:46.64Z" }, +] + +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, +] + +[[package]] +name = "pyright" +version = "1.1.399" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nodeenv" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/9d/d91d5f6d26b2db95476fefc772e2b9a16d54c6bd0ea6bb5c1b6d635ab8b4/pyright-1.1.399.tar.gz", hash = "sha256:439035d707a36c3d1b443aec980bc37053fbda88158eded24b8eedcf1c7b7a1b", size = 3856954, upload-time = "2025-04-10T04:40:25.703Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2f/b5/380380c9e7a534cb1783c70c3e8ac6d1193c599650a55838d0557586796e/pyright-1.1.399-py3-none-any.whl", hash = "sha256:55f9a875ddf23c9698f24208c764465ffdfd38be6265f7faf9a176e1dc549f3b", size = 5592584, upload-time = "2025-04-10T04:40:23.502Z" }, +] + +[[package]] +name = "pytest" +version = "8.4.2" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.10'", +] +dependencies = [ + { name = "colorama", marker = "(python_full_version < '3.10' and sys_platform == 'win32') or (python_full_version >= '3.10' and extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2') or (sys_platform != 'win32' and extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, + { name = "exceptiongroup", marker = "python_full_version < '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, + { name = "iniconfig", version = "2.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, + { name = "packaging", marker = "python_full_version < '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, + { name = "pluggy", marker = "python_full_version < '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, + { name = "pygments", marker = "python_full_version < '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, + { name = "tomli", marker = "python_full_version < '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618, upload-time = "2025-09-04T14:34:22.711Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750, upload-time = "2025-09-04T14:34:20.226Z" }, +] + +[[package]] +name = "pytest" +version = "9.0.2" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14' and extra != 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2'", + "python_full_version >= '3.10' and python_full_version < '3.14' and extra != 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2'", + "python_full_version >= '3.10' and extra == 'group-11-phoebe-bird-pydantic-v1' and extra != 'group-11-phoebe-bird-pydantic-v2'", + "python_full_version >= '3.10' and extra != 'group-11-phoebe-bird-pydantic-v1' and extra != 'group-11-phoebe-bird-pydantic-v2'", +] +dependencies = [ + { name = "colorama", marker = "(python_full_version >= '3.10' and sys_platform == 'win32') or (python_full_version < '3.10' and extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2') or (sys_platform != 'win32' and extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, + { name = "exceptiongroup", marker = "python_full_version == '3.10.*' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, + { name = "iniconfig", version = "2.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, + { name = "packaging", marker = "python_full_version >= '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, + { name = "pluggy", marker = "python_full_version >= '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, + { name = "pygments", marker = "python_full_version >= '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, + { name = "tomli", marker = "python_full_version == '3.10.*' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11", size = 1568901, upload-time = "2025-12-06T21:30:51.014Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl", hash = "sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b", size = 374801, upload-time = "2025-12-06T21:30:49.154Z" }, +] + +[[package]] +name = "pytest-asyncio" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.10'", +] +dependencies = [ + { name = "backports-asyncio-runner", marker = "python_full_version < '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, + { name = "pytest", version = "8.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, + { name = "typing-extensions", marker = "python_full_version < '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/86/9e3c5f48f7b7b638b216e4b9e645f54d199d7abbbab7a64a13b4e12ba10f/pytest_asyncio-1.2.0.tar.gz", hash = "sha256:c609a64a2a8768462d0c99811ddb8bd2583c33fd33cf7f21af1c142e824ffb57", size = 50119, upload-time = "2025-09-12T07:33:53.816Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/93/2fa34714b7a4ae72f2f8dad66ba17dd9a2c793220719e736dda28b7aec27/pytest_asyncio-1.2.0-py3-none-any.whl", hash = "sha256:8e17ae5e46d8e7efe51ab6494dd2010f4ca8dae51652aa3c8d55acf50bfb2e99", size = 15095, upload-time = "2025-09-12T07:33:52.639Z" }, +] + +[[package]] +name = "pytest-asyncio" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14' and extra != 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2'", + "python_full_version >= '3.10' and python_full_version < '3.14' and extra != 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2'", + "python_full_version >= '3.10' and extra == 'group-11-phoebe-bird-pydantic-v1' and extra != 'group-11-phoebe-bird-pydantic-v2'", + "python_full_version >= '3.10' and extra != 'group-11-phoebe-bird-pydantic-v1' and extra != 'group-11-phoebe-bird-pydantic-v2'", +] +dependencies = [ + { name = "backports-asyncio-runner", marker = "python_full_version == '3.10.*' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, + { name = "pytest", version = "9.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, + { name = "typing-extensions", marker = "(python_full_version >= '3.10' and python_full_version < '3.13') or (python_full_version < '3.10' and extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2') or (python_full_version >= '3.13' and extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/90/2c/8af215c0f776415f3590cac4f9086ccefd6fd463befeae41cd4d3f193e5a/pytest_asyncio-1.3.0.tar.gz", hash = "sha256:d7f52f36d231b80ee124cd216ffb19369aa168fc10095013c6b014a34d3ee9e5", size = 50087, upload-time = "2025-11-10T16:07:47.256Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/35/f8b19922b6a25bc0880171a2f1a003eaeb93657475193ab516fd87cac9da/pytest_asyncio-1.3.0-py3-none-any.whl", hash = "sha256:611e26147c7f77640e6d0a92a38ed17c3e9848063698d5c93d5aa7aa11cebff5", size = 15075, upload-time = "2025-11-10T16:07:45.537Z" }, +] + +[[package]] +name = "pytest-xdist" +version = "3.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "execnet" }, + { name = "pytest", version = "8.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, + { name = "pytest", version = "9.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/78/b4/439b179d1ff526791eb921115fca8e44e596a13efeda518b9d845a619450/pytest_xdist-3.8.0.tar.gz", hash = "sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1", size = 88069, upload-time = "2025-07-01T13:30:59.346Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl", hash = "sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88", size = 46396, upload-time = "2025-07-01T13:30:56.632Z" }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six", marker = "python_full_version < '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, +] + +[[package]] +name = "respx" +version = "0.22.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "httpx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f4/7c/96bd0bc759cf009675ad1ee1f96535edcb11e9666b985717eb8c87192a95/respx-0.22.0.tar.gz", hash = "sha256:3c8924caa2a50bd71aefc07aa812f2466ff489f1848c96e954a5362d17095d91", size = 28439, upload-time = "2024-12-19T22:33:59.374Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8e/67/afbb0978d5399bc9ea200f1d4489a23c9a1dad4eee6376242b8182389c79/respx-0.22.0-py2.py3-none-any.whl", hash = "sha256:631128d4c9aba15e56903fb5f66fb1eff412ce28dd387ca3a81339e52dbd3ad0", size = 25127, upload-time = "2024-12-19T22:33:57.837Z" }, +] + +[[package]] +name = "rich" +version = "14.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, + { name = "markdown-it-py", version = "4.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fb/d2/8920e102050a0de7bfabeb4c4614a49248cf8d5d7a8d01885fbb24dc767a/rich-14.2.0.tar.gz", hash = "sha256:73ff50c7c0c1c77c8243079283f4edb376f0f6442433aecb8ce7e6d0b92d1fe4", size = 219990, upload-time = "2025-10-09T14:16:53.064Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/25/7a/b0178788f8dc6cafce37a212c99565fa1fe7872c70c6c9c1e1a372d9d88f/rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd", size = 243393, upload-time = "2025-10-09T14:16:51.245Z" }, +] + +[[package]] +name = "ruff" +version = "0.14.13" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/50/0a/1914efb7903174b381ee2ffeebb4253e729de57f114e63595114c8ca451f/ruff-0.14.13.tar.gz", hash = "sha256:83cd6c0763190784b99650a20fec7633c59f6ebe41c5cc9d45ee42749563ad47", size = 6059504, upload-time = "2026-01-15T20:15:16.918Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c3/ae/0deefbc65ca74b0ab1fd3917f94dc3b398233346a74b8bbb0a916a1a6bf6/ruff-0.14.13-py3-none-linux_armv6l.whl", hash = "sha256:76f62c62cd37c276cb03a275b198c7c15bd1d60c989f944db08a8c1c2dbec18b", size = 13062418, upload-time = "2026-01-15T20:14:50.779Z" }, + { url = "https://files.pythonhosted.org/packages/47/df/5916604faa530a97a3c154c62a81cb6b735c0cb05d1e26d5ad0f0c8ac48a/ruff-0.14.13-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:914a8023ece0528d5cc33f5a684f5f38199bbb566a04815c2c211d8f40b5d0ed", size = 13442344, upload-time = "2026-01-15T20:15:07.94Z" }, + { url = "https://files.pythonhosted.org/packages/4c/f3/e0e694dd69163c3a1671e102aa574a50357536f18a33375050334d5cd517/ruff-0.14.13-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d24899478c35ebfa730597a4a775d430ad0d5631b8647a3ab368c29b7e7bd063", size = 12354720, upload-time = "2026-01-15T20:15:09.854Z" }, + { url = "https://files.pythonhosted.org/packages/c3/e8/67f5fcbbaee25e8fc3b56cc33e9892eca7ffe09f773c8e5907757a7e3bdb/ruff-0.14.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9aaf3870f14d925bbaf18b8a2347ee0ae7d95a2e490e4d4aea6813ed15ebc80e", size = 12774493, upload-time = "2026-01-15T20:15:20.908Z" }, + { url = "https://files.pythonhosted.org/packages/6b/ce/d2e9cb510870b52a9565d885c0d7668cc050e30fa2c8ac3fb1fda15c083d/ruff-0.14.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac5b7f63dd3b27cc811850f5ffd8fff845b00ad70e60b043aabf8d6ecc304e09", size = 12815174, upload-time = "2026-01-15T20:15:05.74Z" }, + { url = "https://files.pythonhosted.org/packages/88/00/c38e5da58beebcf4fa32d0ddd993b63dfacefd02ab7922614231330845bf/ruff-0.14.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78d2b1097750d90ba82ce4ba676e85230a0ed694178ca5e61aa9b459970b3eb9", size = 13680909, upload-time = "2026-01-15T20:15:14.537Z" }, + { url = "https://files.pythonhosted.org/packages/61/61/cd37c9dd5bd0a3099ba79b2a5899ad417d8f3b04038810b0501a80814fd7/ruff-0.14.13-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:7d0bf87705acbbcb8d4c24b2d77fbb73d40210a95c3903b443cd9e30824a5032", size = 15144215, upload-time = "2026-01-15T20:15:22.886Z" }, + { url = "https://files.pythonhosted.org/packages/56/8a/85502d7edbf98c2df7b8876f316c0157359165e16cdf98507c65c8d07d3d/ruff-0.14.13-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a3eb5da8e2c9e9f13431032fdcbe7681de9ceda5835efee3269417c13f1fed5c", size = 14706067, upload-time = "2026-01-15T20:14:48.271Z" }, + { url = "https://files.pythonhosted.org/packages/7e/2f/de0df127feb2ee8c1e54354dc1179b4a23798f0866019528c938ba439aca/ruff-0.14.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:642442b42957093811cd8d2140dfadd19c7417030a7a68cf8d51fcdd5f217427", size = 14133916, upload-time = "2026-01-15T20:14:57.357Z" }, + { url = "https://files.pythonhosted.org/packages/0d/77/9b99686bb9fe07a757c82f6f95e555c7a47801a9305576a9c67e0a31d280/ruff-0.14.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4acdf009f32b46f6e8864af19cbf6841eaaed8638e65c8dac845aea0d703c841", size = 13859207, upload-time = "2026-01-15T20:14:55.111Z" }, + { url = "https://files.pythonhosted.org/packages/7d/46/2bdcb34a87a179a4d23022d818c1c236cb40e477faf0d7c9afb6813e5876/ruff-0.14.13-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:591a7f68860ea4e003917d19b5c4f5ac39ff558f162dc753a2c5de897fd5502c", size = 14043686, upload-time = "2026-01-15T20:14:52.841Z" }, + { url = "https://files.pythonhosted.org/packages/1a/a9/5c6a4f56a0512c691cf143371bcf60505ed0f0860f24a85da8bd123b2bf1/ruff-0.14.13-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:774c77e841cc6e046fc3e91623ce0903d1cd07e3a36b1a9fe79b81dab3de506b", size = 12663837, upload-time = "2026-01-15T20:15:18.921Z" }, + { url = "https://files.pythonhosted.org/packages/fe/bb/b920016ece7651fa7fcd335d9d199306665486694d4361547ccb19394c44/ruff-0.14.13-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:61f4e40077a1248436772bb6512db5fc4457fe4c49e7a94ea7c5088655dd21ae", size = 12805867, upload-time = "2026-01-15T20:14:59.272Z" }, + { url = "https://files.pythonhosted.org/packages/7d/b3/0bd909851e5696cd21e32a8fc25727e5f58f1934b3596975503e6e85415c/ruff-0.14.13-py3-none-musllinux_1_2_i686.whl", hash = "sha256:6d02f1428357fae9e98ac7aa94b7e966fd24151088510d32cf6f902d6c09235e", size = 13208528, upload-time = "2026-01-15T20:15:03.732Z" }, + { url = "https://files.pythonhosted.org/packages/3b/3b/e2d94cb613f6bbd5155a75cbe072813756363eba46a3f2177a1fcd0cd670/ruff-0.14.13-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e399341472ce15237be0c0ae5fbceca4b04cd9bebab1a2b2c979e015455d8f0c", size = 13929242, upload-time = "2026-01-15T20:15:11.918Z" }, + { url = "https://files.pythonhosted.org/packages/6a/c5/abd840d4132fd51a12f594934af5eba1d5d27298a6f5b5d6c3be45301caf/ruff-0.14.13-py3-none-win32.whl", hash = "sha256:ef720f529aec113968b45dfdb838ac8934e519711da53a0456038a0efecbd680", size = 12919024, upload-time = "2026-01-15T20:14:43.647Z" }, + { url = "https://files.pythonhosted.org/packages/c2/55/6384b0b8ce731b6e2ade2b5449bf07c0e4c31e8a2e68ea65b3bafadcecc5/ruff-0.14.13-py3-none-win_amd64.whl", hash = "sha256:6070bd026e409734b9257e03e3ef18c6e1a216f0435c6751d7a8ec69cb59abef", size = 14097887, upload-time = "2026-01-15T20:15:01.48Z" }, + { url = "https://files.pythonhosted.org/packages/4d/e1/7348090988095e4e39560cfc2f7555b1b2a7357deba19167b600fdf5215d/ruff-0.14.13-py3-none-win_arm64.whl", hash = "sha256:7ab819e14f1ad9fe39f246cfcc435880ef7a9390d81a2b6ac7e01039083dd247", size = 13080224, upload-time = "2026-01-15T20:14:45.853Z" }, +] + +[[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" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, +] + +[[package]] +name = "time-machine" +version = "2.19.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.10'", +] +dependencies = [ + { name = "python-dateutil", marker = "python_full_version < '3.10' or (extra == 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f8/a4/1b5fdd165f61b67f445fac2a7feb0c655118edef429cd09ff5a8067f7f1d/time_machine-2.19.0.tar.gz", hash = "sha256:7c5065a8b3f2bbb449422c66ef71d114d3f909c276a6469642ecfffb6a0fcd29", size = 14576, upload-time = "2025-08-19T17:22:08.402Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/8f/19125611ebbcb3a14da14cd982b9eb4573e2733db60c9f1fbf6a39534f40/time_machine-2.19.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b5169018ef47206997b46086ce01881cd3a4666fd2998c9d76a87858ca3e49e9", size = 19659, upload-time = "2025-08-19T17:20:30.062Z" }, + { url = "https://files.pythonhosted.org/packages/74/da/9b0a928321e7822a3ff96dbd1eae089883848e30e9e1b149b85fb96ba56b/time_machine-2.19.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:85bb7ed440fccf6f6d0c8f7d68d849e7c3d1f771d5e0b2cdf871fa6561da569f", size = 15157, upload-time = "2025-08-19T17:20:31.931Z" }, + { url = "https://files.pythonhosted.org/packages/36/ff/d7e943422038f5f2161fe2c2d791e64a45be691ef946020b20f3a6efc4d4/time_machine-2.19.0-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a3b12028af1cdc09ccd595be2168b7b26f206c1e190090b048598fbe278beb8e", size = 32860, upload-time = "2025-08-19T17:20:33.241Z" }, + { url = "https://files.pythonhosted.org/packages/fc/80/2b0f1070ed9808ee7da7a6da62a4a0b776957cb4d861578348f86446e778/time_machine-2.19.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c261f073086cf081d1443cbf7684148c662659d3d139d06b772bfe3fe7cc71a6", size = 34510, upload-time = "2025-08-19T17:20:34.221Z" }, + { url = "https://files.pythonhosted.org/packages/ef/b4/48038691c8d89924b36c83335a73adeeb68c884f5a1da08a5b17b8a956f3/time_machine-2.19.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:011954d951230a9f1079f22b39ed1a3a9abb50ee297dfb8c557c46351659d94d", size = 36204, upload-time = "2025-08-19T17:20:35.163Z" }, + { url = "https://files.pythonhosted.org/packages/37/2e/60e8adb541df195e83cb74b720b2cfb1f22ed99c5a7f8abf2a9ab3442cb5/time_machine-2.19.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b0f83308b29c7872006803f2e77318874eb84d0654f2afe0e48e3822e7a2e39b", size = 34936, upload-time = "2025-08-19T17:20:36.61Z" }, + { url = "https://files.pythonhosted.org/packages/5e/72/e8cee59c6cd99dd3b25b8001a0253e779a286aa8f44d5b40777cbd66210b/time_machine-2.19.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:39733ef844e2984620ec9382a42d00cccc4757d75a5dd572be8c2572e86e50b9", size = 32932, upload-time = "2025-08-19T17:20:37.901Z" }, + { url = "https://files.pythonhosted.org/packages/2c/eb/83f300d93c1504965d944e03679f1c943a923bce2d0fdfadef0e2e22cc13/time_machine-2.19.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f8db99f6334432e9ffbf00c215caf2ae9773f17cec08304d77e9e90febc3507b", size = 34010, upload-time = "2025-08-19T17:20:39.202Z" }, + { url = "https://files.pythonhosted.org/packages/e1/77/f35f2500e04daac5033a22fbfd17e68467822b8406ee77966bf222ccaa26/time_machine-2.19.0-cp310-cp310-win32.whl", hash = "sha256:72bf66cd19e27ffd26516b9cbe676d50c2e0b026153289765dfe0cf406708128", size = 17121, upload-time = "2025-08-19T17:20:40.108Z" }, + { url = "https://files.pythonhosted.org/packages/db/df/32d3e0404be1760a64a44caab2af34b07e952bfe00a23134fea9ddba3e8a/time_machine-2.19.0-cp310-cp310-win_amd64.whl", hash = "sha256:46f1c945934ce3d6b4f388b8e581fce7f87ec891ea90d7128e19520e434f96f0", size = 17957, upload-time = "2025-08-19T17:20:41.079Z" }, + { url = "https://files.pythonhosted.org/packages/66/df/598a71a1afb4b509a4587273b76590b16d9110a3e9106f01eedc68d02bb2/time_machine-2.19.0-cp310-cp310-win_arm64.whl", hash = "sha256:fb4897c7a5120a4fd03f0670f332d83b7e55645886cd8864a71944c4c2e5b35b", size = 16821, upload-time = "2025-08-19T17:20:41.967Z" }, + { url = "https://files.pythonhosted.org/packages/1d/ed/4815ebcc9b6c14273f692b9be38a9b09eae52a7e532407cc61a51912b121/time_machine-2.19.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5ee91664880434d98e41585c3446dac7180ec408c786347451ddfca110d19296", size = 19342, upload-time = "2025-08-19T17:20:43.207Z" }, + { url = "https://files.pythonhosted.org/packages/ee/08/154cce8b11b60d8238b0b751b8901d369999f4e8f7c3a5f917caa5d95b0b/time_machine-2.19.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ed3732b83a893d1c7b8cabde762968b4dc5680ee0d305b3ecca9bb516f4e3862", size = 14978, upload-time = "2025-08-19T17:20:44.134Z" }, + { url = "https://files.pythonhosted.org/packages/c7/b7/b689d8c8eeca7af375cfcd64973e49e83aa817cc00f80f98548d42c0eb50/time_machine-2.19.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:6ba0303e9cc9f7f947e344f501e26bedfb68fab521e3c2729d370f4f332d2d55", size = 30964, upload-time = "2025-08-19T17:20:45.366Z" }, + { url = "https://files.pythonhosted.org/packages/80/91/38bf9c79674e95ce32e23c267055f281dff651eec77ed32a677db3dc011a/time_machine-2.19.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2851825b524a988ee459c37c1c26bdfaa7eff78194efb2b562ea497a6f375b0a", size = 32606, upload-time = "2025-08-19T17:20:46.693Z" }, + { url = "https://files.pythonhosted.org/packages/19/4a/e9222d85d4de68975a5e799f539a9d32f3a134a9101fca0a61fa6aa33d68/time_machine-2.19.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:68d32b09ecfd7fef59255c091e8e7c24dd117f882c4880b5c7ab8c5c32a98f89", size = 34405, upload-time = "2025-08-19T17:20:48.032Z" }, + { url = "https://files.pythonhosted.org/packages/14/e2/09480d608d42d6876f9ff74593cfc9197a7eb2c31381a74fb2b145575b65/time_machine-2.19.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:60c46ab527bf2fa144b530f639cc9e12803524c9e1f111dc8c8f493bb6586eeb", size = 33181, upload-time = "2025-08-19T17:20:48.937Z" }, + { url = "https://files.pythonhosted.org/packages/84/64/f9359e000fad32d9066305c48abc527241d608bcdf77c19d67d66e268455/time_machine-2.19.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:56f26ab9f0201c453d18fe76bb7d1cf05fe58c1b9d9cb0c7d243d05132e01292", size = 31036, upload-time = "2025-08-19T17:20:50.276Z" }, + { url = "https://files.pythonhosted.org/packages/71/0d/fab2aacec71e3e482bd7fce0589381f9414a4a97f8766bddad04ad047b7b/time_machine-2.19.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6c806cf3c1185baa1d807b7f51bed0db7a6506832c961d5d1b4c94c775749bc0", size = 32145, upload-time = "2025-08-19T17:20:51.449Z" }, + { url = "https://files.pythonhosted.org/packages/44/fb/faeba2405fb27553f7b28db441a500e2064ffdb2dcba001ee315fdd2c121/time_machine-2.19.0-cp311-cp311-win32.whl", hash = "sha256:b30039dfd89855c12138095bee39c540b4633cbc3684580d684ef67a99a91587", size = 17004, upload-time = "2025-08-19T17:20:52.38Z" }, + { url = "https://files.pythonhosted.org/packages/2f/84/87e483d660ca669426192969280366635c845c3154a9fe750be546ed3afc/time_machine-2.19.0-cp311-cp311-win_amd64.whl", hash = "sha256:13ed8b34430f1de79905877f5600adffa626793ab4546a70a99fb72c6a3350d8", size = 17822, upload-time = "2025-08-19T17:20:53.348Z" }, + { url = "https://files.pythonhosted.org/packages/41/f4/ebf7bbf5047854a528adaf54a5e8780bc5f7f0104c298ab44566a3053bf8/time_machine-2.19.0-cp311-cp311-win_arm64.whl", hash = "sha256:cc29a50a0257d8750b08056b66d7225daab47606832dea1a69e8b017323bf511", size = 16680, upload-time = "2025-08-19T17:20:54.26Z" }, + { url = "https://files.pythonhosted.org/packages/9b/aa/7e00614d339e4d687f6e96e312a1566022528427d237ec639df66c4547bc/time_machine-2.19.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:c85cf437dc3c07429456d8d6670ac90ecbd8241dcd0fbf03e8db2800576f91ff", size = 19308, upload-time = "2025-08-19T17:20:55.25Z" }, + { url = "https://files.pythonhosted.org/packages/ab/3c/bde3c757394f5bca2fbc1528d4117960a26c38f9b160bf471b38d2378d8f/time_machine-2.19.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d9238897e8ef54acdf59f5dff16f59ca0720e7c02d820c56b4397c11db5d3eb9", size = 15019, upload-time = "2025-08-19T17:20:56.204Z" }, + { url = "https://files.pythonhosted.org/packages/c8/e0/8ca916dd918018352d377f1f5226ee071cfbeb7dbbde2b03d14a411ac2b1/time_machine-2.19.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e312c7d5d6bfffb96c6a7b39ff29e3046de100d7efaa3c01552654cfbd08f14c", size = 33079, upload-time = "2025-08-19T17:20:57.166Z" }, + { url = "https://files.pythonhosted.org/packages/48/69/184a0209f02dd0cb5e01e8d13cd4c97a5f389c4e3d09b95160dd676ad1e7/time_machine-2.19.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:714c40b2c90d1c57cc403382d5a9cf16e504cb525bfe9650095317da3c3d62b5", size = 34925, upload-time = "2025-08-19T17:20:58.117Z" }, + { url = "https://files.pythonhosted.org/packages/43/42/4bbf4309e8e57cea1086eb99052d97ff6ddecc1ab6a3b07aa4512f8bf963/time_machine-2.19.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2eaa1c675d500dc3ccae19e9fb1feff84458a68c132bbea47a80cc3dd2df7072", size = 36384, upload-time = "2025-08-19T17:20:59.108Z" }, + { url = "https://files.pythonhosted.org/packages/b1/af/9f510dc1719157348c1a2e87423aed406589070b54b503cb237d9bf3a4fe/time_machine-2.19.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e77a414e9597988af53b2b2e67242c9d2f409769df0d264b6d06fda8ca3360d4", size = 34881, upload-time = "2025-08-19T17:21:00.116Z" }, + { url = "https://files.pythonhosted.org/packages/ca/28/61764a635c70cc76c76ba582dfdc1a84834cddaeb96789023af5214426b2/time_machine-2.19.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:cd93996970e11c382b04d4937c3cd0b0167adeef14725ece35aae88d8a01733c", size = 32931, upload-time = "2025-08-19T17:21:01.095Z" }, + { url = "https://files.pythonhosted.org/packages/b6/e0/f028d93b266e6ade8aca5851f76ebbc605b2905cdc29981a2943b43e1a6c/time_machine-2.19.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8e20a6d8d6e23174bd7e931e134d9610b136db460b249d07e84ecdad029ec352", size = 34241, upload-time = "2025-08-19T17:21:02.052Z" }, + { url = "https://files.pythonhosted.org/packages/7d/a6/36d1950ed1d3f613158024cf1dcc73db1d9ef0b9117cf51ef2e37dc06499/time_machine-2.19.0-cp312-cp312-win32.whl", hash = "sha256:95afc9bc65228b27be80c2756799c20b8eb97c4ef382a9b762b6d7888bc84099", size = 17021, upload-time = "2025-08-19T17:21:03.374Z" }, + { url = "https://files.pythonhosted.org/packages/b1/0d/e2dce93355abda3cac69e77fe96566757e98b8fe7fdcbddce89c9ced3f5f/time_machine-2.19.0-cp312-cp312-win_amd64.whl", hash = "sha256:e84909af950e2448f4e2562ea5759c946248c99ab380d2b47d79b62bd76fa236", size = 17857, upload-time = "2025-08-19T17:21:04.331Z" }, + { url = "https://files.pythonhosted.org/packages/eb/28/50ae6fb83b7feeeca7a461c0dc156cf7ef5e6ef594a600d06634fde6a2cb/time_machine-2.19.0-cp312-cp312-win_arm64.whl", hash = "sha256:0390a1ea9fa7e9d772a39b7c61b34fdcca80eb9ffac339cc0441c6c714c81470", size = 16677, upload-time = "2025-08-19T17:21:05.39Z" }, + { url = "https://files.pythonhosted.org/packages/a9/b8/24ebce67aa531bae2cbe164bb3f4abc6467dc31f3aead35e77f5a075ea3e/time_machine-2.19.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:5e172866753e6041d3b29f3037dc47c20525176a494a71bbd0998dfdc4f11f2f", size = 19373, upload-time = "2025-08-19T17:21:06.701Z" }, + { url = "https://files.pythonhosted.org/packages/53/a5/c9a5240fd2f845d3ff9fa26f8c8eaa29f7239af9d65007e61d212250f15b/time_machine-2.19.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f70f68379bd6f542ae6775cce9a4fa3dcc20bf7959c42eaef871c14469e18097", size = 15056, upload-time = "2025-08-19T17:21:07.667Z" }, + { url = "https://files.pythonhosted.org/packages/b9/92/66cce5d2fb2a5e68459aca85fd18a7e2d216f725988940cd83f96630f2f1/time_machine-2.19.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e69e0b0f694728a00e72891ef8dd00c7542952cb1c87237db594b6b27d504a96", size = 33172, upload-time = "2025-08-19T17:21:08.619Z" }, + { url = "https://files.pythonhosted.org/packages/ae/20/b499e9ab4364cd466016c33dcdf4f56629ca4c20b865bd4196d229f31d92/time_machine-2.19.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:3ae0a8b869574301ec5637e32c270c7384cca5cd6e230f07af9d29271a7fa293", size = 35042, upload-time = "2025-08-19T17:21:09.622Z" }, + { url = "https://files.pythonhosted.org/packages/41/32/b252d3d32791eb16c07d553c820dbc33d9c7fa771de3d1c602190bded2b7/time_machine-2.19.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:554e4317de90e2f7605ff80d153c8bb56b38c0d0c0279feb17e799521e987b8c", size = 36535, upload-time = "2025-08-19T17:21:10.571Z" }, + { url = "https://files.pythonhosted.org/packages/98/cf/4d0470062b9742e1b040ab81bad04d1a5d1de09806507bb6188989cfa1a7/time_machine-2.19.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6567a5ec5538ed550539ac29be11b3cb36af1f9894e2a72940cba0292cc7c3c9", size = 34945, upload-time = "2025-08-19T17:21:11.538Z" }, + { url = "https://files.pythonhosted.org/packages/24/71/2f741b29d98b1c18f6777a32236497c3d3264b6077e431cea4695684c8a1/time_machine-2.19.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:82e9ffe8dfff07b0d810a2ad015a82cd78c6a237f6c7cf185fa7f747a3256f8a", size = 33014, upload-time = "2025-08-19T17:21:12.858Z" }, + { url = "https://files.pythonhosted.org/packages/e8/83/ca8dba6106562843fd99f672e5aaf95badbc10f4f13f7cfe8d8640a7019d/time_machine-2.19.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7e1c4e578cdd69b3531d8dd3fbcb92a0cd879dadb912ee37af99c3a9e3c0d285", size = 34350, upload-time = "2025-08-19T17:21:13.923Z" }, + { url = "https://files.pythonhosted.org/packages/21/7f/34fe540450e18d0a993240100e4b86e8d03d831b92af8bb6ddb2662dc6fc/time_machine-2.19.0-cp313-cp313-win32.whl", hash = "sha256:72dbd4cbc3d96dec9dd281ddfbb513982102776b63e4e039f83afb244802a9e5", size = 17047, upload-time = "2025-08-19T17:21:14.874Z" }, + { url = "https://files.pythonhosted.org/packages/bf/5d/c8be73df82c7ebe7cd133279670e89b8b110af3ce1412c551caa9d08e625/time_machine-2.19.0-cp313-cp313-win_amd64.whl", hash = "sha256:e17e3e089ac95f9a145ce07ff615e3c85674f7de36f2d92aaf588493a23ffb4b", size = 17868, upload-time = "2025-08-19T17:21:15.819Z" }, + { url = "https://files.pythonhosted.org/packages/92/13/2dfd3b8fb285308f61cd7aa9bfa96f46ddf916e3549a0f0afd094c556599/time_machine-2.19.0-cp313-cp313-win_arm64.whl", hash = "sha256:149072aff8e3690e14f4916103d898ea0d5d9c95531b6aa0995251c299533f7b", size = 16710, upload-time = "2025-08-19T17:21:16.748Z" }, + { url = "https://files.pythonhosted.org/packages/05/c1/deebb361727d2c5790f9d4d874be1b19afd41f4375581df465e6718b46a2/time_machine-2.19.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:f3589fee1ed0ab6ee424a55b0ea1ec694c4ba64cc26895bcd7d99f3d1bc6a28a", size = 20053, upload-time = "2025-08-19T17:21:17.704Z" }, + { url = "https://files.pythonhosted.org/packages/45/e8/fe3376951e6118d8ec1d1f94066a169b791424fe4a26c7dfc069b153ee08/time_machine-2.19.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7887e85275c4975fe54df03dcdd5f38bd36be973adc68a8c77e17441c3b443d6", size = 15423, upload-time = "2025-08-19T17:21:18.668Z" }, + { url = "https://files.pythonhosted.org/packages/9c/c7/f88d95cd1a87c650cf3749b4d64afdaf580297aa18ad7f4b44ec9d252dfc/time_machine-2.19.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:ce0be294c209928563fcce1c587963e60ec803436cf1e181acd5bc1e425d554b", size = 39630, upload-time = "2025-08-19T17:21:19.645Z" }, + { url = "https://files.pythonhosted.org/packages/cc/5d/65a5c48a65357e56ec6f032972e4abd1c02d4fca4b0717a3aaefd19014d4/time_machine-2.19.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a62fd1ab380012c86f4c042010418ed45eb31604f4bf4453e17c9fa60bc56a29", size = 41242, upload-time = "2025-08-19T17:21:20.979Z" }, + { url = "https://files.pythonhosted.org/packages/f6/f9/fe5209e1615fde0a8cad6c4e857157b150333ed1fe31a7632b08cfe0ebdd/time_machine-2.19.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b25ec853a4530a5800731257f93206b12cbdee85ede964ebf8011b66086a7914", size = 44278, upload-time = "2025-08-19T17:21:21.984Z" }, + { url = "https://files.pythonhosted.org/packages/4a/3a/a5e5fe9c5d614cde0a9387ff35e8dfd12c5ef6384e4c1a21b04e6e0b905d/time_machine-2.19.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a430e4d0e0556f021a9c78e9b9f68e5e8910bdace4aa34ed4d1a73e239ed9384", size = 42321, upload-time = "2025-08-19T17:21:23.755Z" }, + { url = "https://files.pythonhosted.org/packages/a1/c5/56eca774e9162bc1ce59111d2bd69140dc8908c9478c92ec7bd15d547600/time_machine-2.19.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:2415b7495ec4364c8067071e964fbadfe746dd4cdb43983f2f0bd6ebed13315c", size = 39270, upload-time = "2025-08-19T17:21:26.009Z" }, + { url = "https://files.pythonhosted.org/packages/9b/69/5dd0c420667578169a12acc8c8fd7452e8cfb181e41c9b4ac7e88fa36686/time_machine-2.19.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dbfc6b90c10f288594e1bf89a728a98cc0030791fd73541bbdc6b090aff83143", size = 40193, upload-time = "2025-08-19T17:21:27.054Z" }, + { url = "https://files.pythonhosted.org/packages/75/a7/de974d421bd55c9355583427c2a38fb0237bb5fd6614af492ba89dacb2f9/time_machine-2.19.0-cp313-cp313t-win32.whl", hash = "sha256:16f5d81f650c0a4d117ab08036dc30b5f8b262e11a4a0becc458e7f1c011b228", size = 17542, upload-time = "2025-08-19T17:21:28.674Z" }, + { url = "https://files.pythonhosted.org/packages/76/0a/aa0d05becd5d06ae8d3f16d657dc8cc9400c8d79aef80299de196467ff12/time_machine-2.19.0-cp313-cp313t-win_amd64.whl", hash = "sha256:645699616ec14e147094f601e6ab9553ff6cea37fad9c42720a6d7ed04bcd5dc", size = 18703, upload-time = "2025-08-19T17:21:29.663Z" }, + { url = "https://files.pythonhosted.org/packages/1f/c0/f785a4c7c73aa176510f7c48b84b49c26be84af0d534deb222e0327f750e/time_machine-2.19.0-cp313-cp313t-win_arm64.whl", hash = "sha256:b32daa965d13237536ea3afaa5ad61ade2b2d9314bc3a20196a0d2e1d7b57c6a", size = 17020, upload-time = "2025-08-19T17:21:30.653Z" }, + { url = "https://files.pythonhosted.org/packages/ed/97/c5fb51def06c0b2b6735332ad118ab35b4d9b85368792e5b638e99b1b686/time_machine-2.19.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:31cb43c8fd2d961f31bed0ff4e0026964d2b35e5de9e0fabbfecf756906d3612", size = 19360, upload-time = "2025-08-19T17:21:31.94Z" }, + { url = "https://files.pythonhosted.org/packages/2d/4e/2d795f7d6b7f5205ffe737a05bb1cf19d8038233b797062b2ef412b8512b/time_machine-2.19.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:bdf481a75afc6bff3e520db594501975b652f7def21cd1de6aa971d35ba644e6", size = 15033, upload-time = "2025-08-19T17:21:32.934Z" }, + { url = "https://files.pythonhosted.org/packages/dd/32/9bad501e360b4e758c58fae616ca5f8c7ad974b343f2463a15b2bf77a366/time_machine-2.19.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:00bee4bb950ac6a08d62af78e4da0cf2b4fc2abf0de2320d0431bf610db06e7c", size = 33379, upload-time = "2025-08-19T17:21:33.925Z" }, + { url = "https://files.pythonhosted.org/packages/a3/45/eda0ca4d793dfd162478d6163759b1c6ce7f6e61daa7fd7d62b31f21f87f/time_machine-2.19.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9f02199490906582302ce09edd32394fb393271674c75d7aa76c7a3245f16003", size = 35123, upload-time = "2025-08-19T17:21:34.945Z" }, + { url = "https://files.pythonhosted.org/packages/f0/5a/97e16325442ae5731fcaac794f0a1ef9980eff8a5491e58201d7eb814a34/time_machine-2.19.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e35726c7ba625f844c13b1fc0d4f81f394eefaee1d3a094a9093251521f2ef15", size = 36588, upload-time = "2025-08-19T17:21:35.975Z" }, + { url = "https://files.pythonhosted.org/packages/e8/9d/bf0b2ccc930cc4a316f26f1c78d3f313cd0fa13bb7480369b730a8f129db/time_machine-2.19.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:304315023999cd401ff02698870932b893369e1cfeb2248d09f6490507a92e97", size = 35013, upload-time = "2025-08-19T17:21:37.017Z" }, + { url = "https://files.pythonhosted.org/packages/f0/5a/39ac6a3078174f9715d88364871348b249631f12e76de1b862433b3f8862/time_machine-2.19.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:9765d4f003f263ea8bfd90d2d15447ca4b3dfa181922cf6cf808923b02ac180a", size = 33303, upload-time = "2025-08-19T17:21:38.352Z" }, + { url = "https://files.pythonhosted.org/packages/b3/ac/d8646baf9f95f2e792a6d7a7b35e92fca253c4a992afff801beafae0e5c2/time_machine-2.19.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7837ef3fd5911eb9b480909bb93d922737b6bdecea99dfcedb0a03807de9b2d3", size = 34440, upload-time = "2025-08-19T17:21:39.382Z" }, + { url = "https://files.pythonhosted.org/packages/ce/8b/8b6568c5ae966d80ead03ab537be3c6acf2af06fb501c2d466a3162c6295/time_machine-2.19.0-cp314-cp314-win32.whl", hash = "sha256:4bb5bd43b1bdfac3007b920b51d8e761f024ed465cfeec63ac4296922a4ec428", size = 17162, upload-time = "2025-08-19T17:21:40.381Z" }, + { url = "https://files.pythonhosted.org/packages/46/a5/211c1ab4566eba5308b2dc001b6349e3a032e3f6afa67ca2f27ea6b27af5/time_machine-2.19.0-cp314-cp314-win_amd64.whl", hash = "sha256:f583bbd0aa8ab4a7c45a684bf636d9e042d466e30bcbae1d13e7541e2cbe7207", size = 18040, upload-time = "2025-08-19T17:21:41.363Z" }, + { url = "https://files.pythonhosted.org/packages/b8/fc/4c2fb705f6371cb83824da45a8b967514a922fc092a0ef53979334d97a70/time_machine-2.19.0-cp314-cp314-win_arm64.whl", hash = "sha256:f379c6f8a6575a8284592179cf528ce89373f060301323edcc44f1fa1d37be12", size = 16752, upload-time = "2025-08-19T17:21:42.336Z" }, + { url = "https://files.pythonhosted.org/packages/79/ab/6437d18f31c666b5116c97572a282ac2590a82a0a9867746a6647eaf4613/time_machine-2.19.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:a3b8981f9c663b0906b05ab4d0ca211fae4b63b47c6ec26de5374fe56c836162", size = 20057, upload-time = "2025-08-19T17:21:43.35Z" }, + { url = "https://files.pythonhosted.org/packages/6c/a2/e03639ec2ba7200328bbcad8a2b2b1d5fccca9cceb9481b164a1cabdcb33/time_machine-2.19.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8e9c6363893e7f52c226afbebb23e825259222d100e67dfd24c8a6d35f1a1907", size = 15430, upload-time = "2025-08-19T17:21:44.725Z" }, + { url = "https://files.pythonhosted.org/packages/5d/ff/39e63a48e840f3e36ce24846ee51dd99c6dba635659b1750a2993771e88e/time_machine-2.19.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:206fcd6c9a6f00cac83db446ad1effc530a8cec244d2780af62db3a2d0a9871b", size = 39622, upload-time = "2025-08-19T17:21:45.821Z" }, + { url = "https://files.pythonhosted.org/packages/9a/2e/ee5ac79c4954768705801e54817c7d58e07e25a0bb227e775f501f3e2122/time_machine-2.19.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bf33016a1403c123373ffaeff25e26e69d63bf2c63b6163932efed94160db7ef", size = 41235, upload-time = "2025-08-19T17:21:46.783Z" }, + { url = "https://files.pythonhosted.org/packages/3a/3e/9af5f39525e779185c77285b8bbae15340eeeaa0afb33d458bc8b47d459b/time_machine-2.19.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9247c4bb9bbd3ff584ef4efbdec8efd9f37aa08bcfc4728bde1e489c2cb445bd", size = 44276, upload-time = "2025-08-19T17:21:47.759Z" }, + { url = "https://files.pythonhosted.org/packages/59/fe/572c7443cc27140bbeae3947279bbd4a120f9e8622253a20637f260b7813/time_machine-2.19.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:77f9bb0b86758d1f2d9352642c874946ad5815df53ef4ca22eb9d532179fe50d", size = 42330, upload-time = "2025-08-19T17:21:48.881Z" }, + { url = "https://files.pythonhosted.org/packages/cf/24/1a81c2e08ee7dae13ec8ceed27a29afa980c3d63852e42f1e023bf0faa03/time_machine-2.19.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:0b529e262df3b9c449f427385f4d98250828c879168c2e00eec844439f40b370", size = 39281, upload-time = "2025-08-19T17:21:49.907Z" }, + { url = "https://files.pythonhosted.org/packages/d2/60/6f0d6e5108978ca1a2a4ffb4d1c7e176d9199bb109fd44efe2680c60b52a/time_machine-2.19.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9199246e31cdc810e5d89cb71d09144c4d745960fdb0824da4994d152aca3303", size = 40201, upload-time = "2025-08-19T17:21:50.953Z" }, + { url = "https://files.pythonhosted.org/packages/73/b9/3ea4951e8293b0643feb98c0b9a176fa822154f1810835db3f282968ab10/time_machine-2.19.0-cp314-cp314t-win32.whl", hash = "sha256:0fe81bae55b7aefc2c2a34eb552aa82e6c61a86b3353a3c70df79b9698cb02ca", size = 17743, upload-time = "2025-08-19T17:21:51.948Z" }, + { url = "https://files.pythonhosted.org/packages/e4/8b/cd802884ca8a98e2b6cdc2397d57dd12ff8a7d1481e06fc3fad3d4e7e5ff/time_machine-2.19.0-cp314-cp314t-win_amd64.whl", hash = "sha256:7253791b8d7e7399fbeed7a8193cb01bc004242864306288797056badbdaf80b", size = 18956, upload-time = "2025-08-19T17:21:52.997Z" }, + { url = "https://files.pythonhosted.org/packages/c6/49/cabb1593896082fd55e34768029b8b0ca23c9be8b2dc127e0fc14796d33e/time_machine-2.19.0-cp314-cp314t-win_arm64.whl", hash = "sha256:536bd1ac31ab06a1522e7bf287602188f502dc19d122b1502c4f60b1e8efac79", size = 17068, upload-time = "2025-08-19T17:21:54.064Z" }, + { url = "https://files.pythonhosted.org/packages/d6/05/0608376c3167afe6cf7cdfd2b05c142ea4c42616eee9ba06d1799965806a/time_machine-2.19.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d8bb00b30ec9fe56d01e9812df1ffe39f331437cef9bfaebcc81c83f7f8f8ee2", size = 19659, upload-time = "2025-08-19T17:21:55.426Z" }, + { url = "https://files.pythonhosted.org/packages/11/c4/72eb8c7b36830cf36c51d7bc2f1ac313d68881c3a58040fb6b42c4523d20/time_machine-2.19.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d821c60efc08a97cc11e5482798e6fd5eba5c0f22a02db246b50895dbdc0de41", size = 15153, upload-time = "2025-08-19T17:21:56.505Z" }, + { url = "https://files.pythonhosted.org/packages/89/1a/0782e1f5c8ab8809ebd992709e1bb69d67600191baa023af7a5d32023a3c/time_machine-2.19.0-cp39-cp39-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:fb051aec7b3b6e96a200d911c225901e6133ff3da11e470e24111a53bbc13637", size = 32555, upload-time = "2025-08-19T17:21:57.74Z" }, + { url = "https://files.pythonhosted.org/packages/94/b0/8ef58e2f6321851d5900ca3d18044938832c2ed42a2ac7570ca6aa29768a/time_machine-2.19.0-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fe59909d95a2ef5e01ce3354fdea3908404c2932c2069f00f66dff6f27e9363e", size = 34185, upload-time = "2025-08-19T17:21:59.361Z" }, + { url = "https://files.pythonhosted.org/packages/82/74/ce0c9867f788c1fb22c417ec1aae47a24117e53d51f6ff97d7c6ca5392f6/time_machine-2.19.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:29e84b8682645b16eb6f9e8ec11c35324ad091841a11cf4fc3fc7f6119094c89", size = 35917, upload-time = "2025-08-19T17:22:00.421Z" }, + { url = "https://files.pythonhosted.org/packages/d2/70/6f97a8f552dbaa66feb10170b5726dab74bc531673d1ed9d6f271547e54c/time_machine-2.19.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4a11f1c0e0d06023dc01614c964e256138913551d3ae6dca5148f79081156336", size = 34584, upload-time = "2025-08-19T17:22:01.447Z" }, + { url = "https://files.pythonhosted.org/packages/48/c8/cf139088ce537c15d7f03cf56ec317d3a5cfb520e30aa711ea0248d0ae8a/time_machine-2.19.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:57a235a6307c54df50e69f1906e2f199e47da91bde4b886ee05aff57fe4b6bf6", size = 32608, upload-time = "2025-08-19T17:22:02.548Z" }, + { url = "https://files.pythonhosted.org/packages/b1/17/0ec41ef7a30c6753fb226a28b74162b264b35724905ced4098f2f5076ded/time_machine-2.19.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:426aba552f7af9604adad9ef570c859af7c1081d878db78089fac159cd911b0a", size = 33686, upload-time = "2025-08-19T17:22:03.606Z" }, + { url = "https://files.pythonhosted.org/packages/b0/19/586f15159083ec84f178d494c60758c46603b00c9641b04deb63f1950128/time_machine-2.19.0-cp39-cp39-win32.whl", hash = "sha256:67772c7197a3a712d1b970ed545c6e98db73524bd90e245fd3c8fa7ad7630768", size = 17133, upload-time = "2025-08-19T17:22:04.989Z" }, + { url = "https://files.pythonhosted.org/packages/6a/c2/bfe4b906a9fe0bf2d011534314212ed752d6b8f392c9c82f6ac63dccc5ab/time_machine-2.19.0-cp39-cp39-win_amd64.whl", hash = "sha256:011d7859089263204dc5fdf83dce7388f986fe833c9381d6106b4edfda2ebd3e", size = 17972, upload-time = "2025-08-19T17:22:06.026Z" }, + { url = "https://files.pythonhosted.org/packages/5d/73/182343eba05aa5787732aaa68f3b3feb5e40ddf86b928ae941be45646393/time_machine-2.19.0-cp39-cp39-win_arm64.whl", hash = "sha256:e1af66550fa4685434f00002808a525f176f1f92746646c0019bb86fbff48b27", size = 16820, upload-time = "2025-08-19T17:22:07.227Z" }, +] + +[[package]] +name = "time-machine" +version = "3.2.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14' and extra != 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2'", + "python_full_version >= '3.10' and python_full_version < '3.14' and extra != 'group-11-phoebe-bird-pydantic-v1' and extra == 'group-11-phoebe-bird-pydantic-v2'", + "python_full_version >= '3.10' and extra == 'group-11-phoebe-bird-pydantic-v1' and extra != 'group-11-phoebe-bird-pydantic-v2'", + "python_full_version >= '3.10' and extra != 'group-11-phoebe-bird-pydantic-v1' and extra != 'group-11-phoebe-bird-pydantic-v2'", +] +sdist = { url = "https://files.pythonhosted.org/packages/02/fc/37b02f6094dbb1f851145330460532176ed2f1dc70511a35828166c41e52/time_machine-3.2.0.tar.gz", hash = "sha256:a4ddd1cea17b8950e462d1805a42b20c81eb9aafc8f66b392dd5ce997e037d79", size = 14804, upload-time = "2025-12-17T23:33:02.599Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9c/31/6bf41cb4a326230518d9b76c910dfc11d4fc23444d1cbfdf2d7652bd99f4/time_machine-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:68142c070e78b62215d8029ec7394905083a4f9aacb0a2a11514ce70b5951b13", size = 19447, upload-time = "2025-12-17T23:31:30.181Z" }, + { url = "https://files.pythonhosted.org/packages/fa/14/d71ce771712e1cbfa15d8c24452225109262b16cb6caaf967e9f60662b67/time_machine-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:161bbd0648802ffdfcb4bb297ecb26b3009684a47d3a4dedb90bc549df4fa2ad", size = 15432, upload-time = "2025-12-17T23:31:31.381Z" }, + { url = "https://files.pythonhosted.org/packages/8b/d6/dcb43a11f8029561996fad58ff9d3dc5e6d7f32b74f0745a2965d7e4b4f3/time_machine-3.2.0-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:1359ba8c258be695ba69253bc84db882fd616fe69b426cc6056536da2c7bf68e", size = 32956, upload-time = "2025-12-17T23:31:32.469Z" }, + { url = "https://files.pythonhosted.org/packages/77/da/d802cd3c335c414f9b11b479f7459aa72df5de6485c799966cfdf8856d53/time_machine-3.2.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c85b169998ca2c24a78fb214586ec11c4cad56d9c38f55ad8326235cb481c884", size = 34556, upload-time = "2025-12-17T23:31:33.946Z" }, + { url = "https://files.pythonhosted.org/packages/85/ee/51ad553514ab0b940c7c82c6e1519dd10fd06ac07b32039a1d153ef09c88/time_machine-3.2.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:65b9367cb8a10505bc8f67da0da514ba20fa816fc47e11f434f7c60350322b4c", size = 36101, upload-time = "2025-12-17T23:31:35.462Z" }, + { url = "https://files.pythonhosted.org/packages/11/39/938b111b5bb85a2b07502d0f9d8a704fc75bd760d62e76bce23c89ed16c9/time_machine-3.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9faca6a0f1973d7df3233c951fc2a11ff0c54df74087d8aaf41ae3deb19d0893", size = 34905, upload-time = "2025-12-17T23:31:36.543Z" }, + { url = "https://files.pythonhosted.org/packages/dd/50/0951f73b23e76455de0b4a3a58ac5a24bd8d10489624b1c5e03f10c6fc0b/time_machine-3.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:213b1ada7f385d467e598999b642eda4a8e89ae10ad5dc4f5d8f672cbf604261", size = 33012, upload-time = "2025-12-17T23:31:37.967Z" }, + { url = "https://files.pythonhosted.org/packages/4f/95/5304912d3dcecc4e14ed222dbe0396352efdf8497534abc3c9edd67a7528/time_machine-3.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:160b6afd94c39855af04d39c58e4cf602406abd6d79427ab80e830ea71789cfb", size = 34104, upload-time = "2025-12-17T23:31:39.449Z" }, + { url = "https://files.pythonhosted.org/packages/d4/1c/af56518652ec7adac4ced193b7a42c4ff354fef28a412b3b5ffa5763aead/time_machine-3.2.0-cp310-cp310-win32.whl", hash = "sha256:c15d9ac257c78c124d112e4fc91fa9f3dcb004bdda913c19f0e7368d713cf080", size = 17468, upload-time = "2025-12-17T23:31:40.432Z" }, + { url = "https://files.pythonhosted.org/packages/48/15/0213f00ca3cf6fe1c9fdbd7fd467e801052fc85534f30c0e4684bd474190/time_machine-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:3bf0f428487f93b8fe9d27aa01eccc817885da3290b467341b4a4a795e1d1891", size = 18313, upload-time = "2025-12-17T23:31:41.617Z" }, + { url = "https://files.pythonhosted.org/packages/77/e4/811f96aa7a634b2b264d9a476f3400e710744dda503b4ad87a5c76db32c9/time_machine-3.2.0-cp310-cp310-win_arm64.whl", hash = "sha256:347f6be2129fcd35b1c94b9387fcb2cbe7949b1e649228c5f22949a811b78976", size = 17037, upload-time = "2025-12-17T23:31:42.924Z" }, + { url = "https://files.pythonhosted.org/packages/f5/e1/03aae5fbaa53859f665094af696338fc7cae733d926a024af69982712350/time_machine-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c188a9dda9fcf975022f1b325b466651b96a4dfc223c523ed7ed8d979f9bf3e8", size = 19143, upload-time = "2025-12-17T23:31:44.258Z" }, + { url = "https://files.pythonhosted.org/packages/75/8f/98cb17bebb52b22ff4ec26984dd44280f9c71353c3bae0640a470e6683e5/time_machine-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:17245f1cc2dd13f9d63a174be59bb2684a9e5e0a112ab707e37be92068cd655f", size = 15273, upload-time = "2025-12-17T23:31:45.246Z" }, + { url = "https://files.pythonhosted.org/packages/dd/2f/ca11e4a7897234bb9331fcc5f4ed4714481ba4012370cc79a0ae8c42ea0a/time_machine-3.2.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d9bd1de1996e76efd36ae15970206c5089fb3728356794455bd5cd8d392b5537", size = 31049, upload-time = "2025-12-17T23:31:46.613Z" }, + { url = "https://files.pythonhosted.org/packages/cf/ad/d17d83a59943094e6b6c6a3743caaf6811b12203c3e07a30cc7bcc2ab7ee/time_machine-3.2.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:98493cd50e8b7f941eab69b9e18e697ad69db1a0ec1959f78f3d7b0387107e5c", size = 32632, upload-time = "2025-12-17T23:31:47.72Z" }, + { url = "https://files.pythonhosted.org/packages/71/50/d60576d047a0dfb5638cdfb335e9c3deb6e8528544fa0b3966a8480f72b7/time_machine-3.2.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:31f2a33d595d9f91eb9bc7f157f0dc5721f5789f4c4a9e8b852cdedb2a7d9b16", size = 34289, upload-time = "2025-12-17T23:31:48.913Z" }, + { url = "https://files.pythonhosted.org/packages/fa/fe/4afa602dbdebddde6d0ea4a7fe849e49b9bb85dc3fb415725a87ccb4b471/time_machine-3.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9f78ac4213c10fbc44283edd1a29cfb7d3382484f4361783ddc057292aaa1889", size = 33175, upload-time = "2025-12-17T23:31:50.611Z" }, + { url = "https://files.pythonhosted.org/packages/0d/87/c152e23977c1d7d7c94eb3ed3ea45cc55971796205125c6fdff40db2c60f/time_machine-3.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c1326b09e947b360926d529a96d1d9e126ce120359b63b506ecdc6ee20755c23", size = 31170, upload-time = "2025-12-17T23:31:51.645Z" }, + { url = "https://files.pythonhosted.org/packages/80/af/54acf51d0f3ade3b51eab73df6192937c9a938753ef5456dff65eb8630be/time_machine-3.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9f2949f03d15264cc15c38918a2cda8966001f0f4ebe190cbfd9c56d91aed8ac", size = 32292, upload-time = "2025-12-17T23:31:52.803Z" }, + { url = "https://files.pythonhosted.org/packages/cc/bc/3745963f36e75661a807196428639327a366f4332f35f1f775c074d4062f/time_machine-3.2.0-cp311-cp311-win32.whl", hash = "sha256:6dfe48e0499e6e16751476b9799e67be7514e6ef04cdf39571ef95a279645831", size = 17349, upload-time = "2025-12-17T23:31:54.19Z" }, + { url = "https://files.pythonhosted.org/packages/82/a2/057469232a99d1f5a0160ae7c5bae7b095c9168b333dd598fcbcfbc1c87b/time_machine-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:809bdf267a29189c304154873620fe0bcc0c9513295fa46b19e21658231c4915", size = 18191, upload-time = "2025-12-17T23:31:55.472Z" }, + { url = "https://files.pythonhosted.org/packages/79/d8/bf9c8de57262ee7130d92a6ed49ed6a6e40a36317e46979428d373630c12/time_machine-3.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:a3f4c17fa90f54902a3f8692c75caf67be87edc3429eeb71cb4595da58198f8e", size = 16905, upload-time = "2025-12-17T23:31:56.658Z" }, + { url = "https://files.pythonhosted.org/packages/71/8b/080c8eedcd67921a52ba5bd0e075362062509ab63c86fc1a0442fad241a6/time_machine-3.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:cc4bee5b0214d7dc4ebc91f4a4c600f1a598e9b5606ac751f42cb6f6740b1dbb", size = 19255, upload-time = "2025-12-17T23:31:58.057Z" }, + { url = "https://files.pythonhosted.org/packages/66/17/0e5291e9eb705bf8a5a1305f826e979af307bbeb79def4ddbf4b3f9a81e0/time_machine-3.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3ca036304b4460ae2fdc1b52dd8b1fa7cf1464daa427fc49567413c09aa839c1", size = 15360, upload-time = "2025-12-17T23:31:59.048Z" }, + { url = "https://files.pythonhosted.org/packages/8b/e8/9ab87b71d2e2b62463b9b058b7ae7ac09fb57f8fcd88729dec169d304340/time_machine-3.2.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5442735b41d7a2abc2f04579b4ca6047ed4698a8338a4fec92c7c9423e7938cb", size = 33029, upload-time = "2025-12-17T23:32:00.413Z" }, + { url = "https://files.pythonhosted.org/packages/4b/26/b5ca19da6f25ea905b3e10a0ea95d697c1aeba0404803a43c68f1af253e6/time_machine-3.2.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:97da3e971e505cb637079fb07ab0bcd36e33279f8ecac888ff131f45ef1e4d8d", size = 34579, upload-time = "2025-12-17T23:32:01.431Z" }, + { url = "https://files.pythonhosted.org/packages/79/ca/6ac7ad5f10ea18cc1d9de49716ba38c32132c7b64532430d92ef240c116b/time_machine-3.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3cdda6dee4966e38aeb487309bb414c6cb23a81fc500291c77a8fcd3098832e7", size = 35961, upload-time = "2025-12-17T23:32:02.521Z" }, + { url = "https://files.pythonhosted.org/packages/33/67/390dd958bed395ab32d79a9fe61fe111825c0dd4ded54dbba7e867f171e6/time_machine-3.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:33d9efd302a6998bcc8baa4d84f259f8a4081105bd3d7f7af7f1d0abd3b1c8aa", size = 34668, upload-time = "2025-12-17T23:32:03.585Z" }, + { url = "https://files.pythonhosted.org/packages/da/57/c88fff034a4e9538b3ae7c68c9cfb283670b14d17522c5a8bc17d29f9a4b/time_machine-3.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3a0b0a33971f14145853c9bd95a6ab0353cf7e0019fa2a7aa1ae9fddfe8eab50", size = 32891, upload-time = "2025-12-17T23:32:04.656Z" }, + { url = "https://files.pythonhosted.org/packages/2d/70/ebbb76022dba0fec8f9156540fc647e4beae1680c787c01b1b6200e56d70/time_machine-3.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2d0be9e5f22c38082d247a2cdcd8a936504e9db60b7b3606855fb39f299e9548", size = 34080, upload-time = "2025-12-17T23:32:06.146Z" }, + { url = "https://files.pythonhosted.org/packages/db/9a/2ca9e7af3df540dc1c79e3de588adeddb7dcc2107829248e6969c4f14167/time_machine-3.2.0-cp312-cp312-win32.whl", hash = "sha256:3f74623648b936fdce5f911caf386c0a0b579456410975de8c0dfeaaffece1d8", size = 17371, upload-time = "2025-12-17T23:32:07.164Z" }, + { url = "https://files.pythonhosted.org/packages/d8/ce/21d23efc9c2151939af1b7ee4e60d86d661b74ef32b8eaa148f6fe8c899c/time_machine-3.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:34e26a41d994b5e4b205136a90e9578470386749cc9a2ecf51ca18f83ce25e23", size = 18132, upload-time = "2025-12-17T23:32:08.447Z" }, + { url = "https://files.pythonhosted.org/packages/2f/34/c2b70be483accf6db9e5d6c3139bce3c38fe51f898ccf64e8d3fe14fbf4d/time_machine-3.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:0615d3d82c418d6293f271c348945c5091a71f37e37173653d5c26d0e74b13a8", size = 16930, upload-time = "2025-12-17T23:32:09.477Z" }, + { url = "https://files.pythonhosted.org/packages/ee/cd/43ad5efc88298af3c59b66769cea7f055567a85071579ed40536188530c1/time_machine-3.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c421a8eb85a4418a7675a41bf8660224318c46cc62e4751c8f1ceca752059090", size = 19318, upload-time = "2025-12-17T23:32:10.518Z" }, + { url = "https://files.pythonhosted.org/packages/b0/f6/084010ef7f4a3f38b5a4900923d7c85b29e797655c4f6ee4ce54d903cca8/time_machine-3.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8f4e758f7727d0058c4950c66b58200c187072122d6f7a98b610530a4233ea7b", size = 15390, upload-time = "2025-12-17T23:32:11.625Z" }, + { url = "https://files.pythonhosted.org/packages/25/aa/1cabb74134f492270dc6860cb7865859bf40ecf828be65972827646e91ad/time_machine-3.2.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:154bd3f75c81f70218b2585cc12b60762fb2665c507eec5ec5037d8756d9b4e0", size = 33115, upload-time = "2025-12-17T23:32:13.219Z" }, + { url = "https://files.pythonhosted.org/packages/5e/03/78c5d7dfa366924eb4dbfcc3fc917c39a4280ca234b12819cc1f16c03d88/time_machine-3.2.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d50cfe5ebea422c896ad8d278af9648412b7533b8ea6adeeee698a3fd9b1d3b7", size = 34705, upload-time = "2025-12-17T23:32:14.29Z" }, + { url = "https://files.pythonhosted.org/packages/86/93/d5e877c24541f674c6869ff6e9c56833369796010190252e92c9d7ae5f0f/time_machine-3.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:636576501724bd6a9124e69d86e5aef263479e89ef739c5db361469f0463a0a1", size = 36104, upload-time = "2025-12-17T23:32:15.354Z" }, + { url = "https://files.pythonhosted.org/packages/22/1c/d4bae72f388f67efc9609f89b012e434bb19d9549c7a7b47d6c7d9e5c55d/time_machine-3.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:40e6f40c57197fcf7ec32d2c563f4df0a82c42cdcc3cab27f688e98f6060df10", size = 34765, upload-time = "2025-12-17T23:32:16.434Z" }, + { url = "https://files.pythonhosted.org/packages/1d/c3/ac378cf301d527d8dfad2f0db6bad0dfb1ab73212eaa56d6b96ee5d9d20b/time_machine-3.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a1bcf0b846bbfc19a79bc19e3fa04d8c7b1e8101c1b70340ffdb689cd801ea53", size = 33010, upload-time = "2025-12-17T23:32:17.532Z" }, + { url = "https://files.pythonhosted.org/packages/06/35/7ce897319accda7a6970b288a9a8c52d25227342a7508505a2b3d235b649/time_machine-3.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ae55a56c179f4fe7a62575ad5148b6ed82f6c7e5cf2f9a9ec65f2f5b067db5f5", size = 34185, upload-time = "2025-12-17T23:32:18.566Z" }, + { url = "https://files.pythonhosted.org/packages/bf/28/f922022269749cb02eee2b62919671153c4088994fa955a6b0e50327ff81/time_machine-3.2.0-cp313-cp313-win32.whl", hash = "sha256:a66fe55a107e46916007a391d4030479df8864ec6ad6f6a6528221befc5c886e", size = 17397, upload-time = "2025-12-17T23:32:19.605Z" }, + { url = "https://files.pythonhosted.org/packages/ee/dc/fd87cde397f4a7bea493152f0aca8fd569ec709cad9e0f2ca7011eb8c7f7/time_machine-3.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:30c9ce57165df913e4f74e285a8ab829ff9b7aa3e5ec0973f88f642b9a7b3d15", size = 18139, upload-time = "2025-12-17T23:32:20.991Z" }, + { url = "https://files.pythonhosted.org/packages/75/81/b8ce58233addc5d7d54d2fabc49dcbc02d79e3f079d150aa1bec3d5275ef/time_machine-3.2.0-cp313-cp313-win_arm64.whl", hash = "sha256:89cad7e179e9bdcc84dcf09efe52af232c4cc7a01b3de868356bbd59d95bd9b8", size = 16964, upload-time = "2025-12-17T23:32:22.075Z" }, + { url = "https://files.pythonhosted.org/packages/67/e7/487f0ba5fe6c58186a5e1af2a118dfa2c160fedb37ef53a7e972d410408e/time_machine-3.2.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:59d71545e62525a4b85b6de9ab5c02ee3c61110fd7f636139914a2335dcbfc9c", size = 20000, upload-time = "2025-12-17T23:32:23.058Z" }, + { url = "https://files.pythonhosted.org/packages/e1/17/eb2c0054c8d44dd42df84ccd434539249a9c7d0b8eb53f799be2102500ab/time_machine-3.2.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:999672c621c35362bc28e03ca0c7df21500195540773c25993421fd8d6cc5003", size = 15657, upload-time = "2025-12-17T23:32:24.125Z" }, + { url = "https://files.pythonhosted.org/packages/43/21/93443b5d1dd850f8bb9442e90d817a9033dcce6bfbdd3aabbb9786251c80/time_machine-3.2.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5faf7397f0580c7b9d67288522c8d7863e85f0cffadc0f1fccdb2c3dfce5783e", size = 39216, upload-time = "2025-12-17T23:32:25.542Z" }, + { url = "https://files.pythonhosted.org/packages/9f/9e/18544cf8acc72bb1dc03762231c82ecc259733f4bb6770a7bbe5cd138603/time_machine-3.2.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d3dd886ec49f1fa5a00e844f5947e5c0f98ce574750c24b7424c6f77fc1c3e87", size = 40764, upload-time = "2025-12-17T23:32:26.643Z" }, + { url = "https://files.pythonhosted.org/packages/27/f7/9fe9ce2795636a3a7467307af6bdf38bb613ddb701a8a5cd50ec713beb5e/time_machine-3.2.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:da0ecd96bc7bbe450acaaabe569d84e81688f1be8ad58d1470e42371d145fb53", size = 43526, upload-time = "2025-12-17T23:32:27.693Z" }, + { url = "https://files.pythonhosted.org/packages/03/c1/a93e975ba9dec22e87ec92d18c28e67d36bd536f9119ffa439b2892b0c9c/time_machine-3.2.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:158220e946c1c4fb8265773a0282c88c35a7e3bb5d78e3561214e3b3231166f3", size = 41727, upload-time = "2025-12-17T23:32:28.985Z" }, + { url = "https://files.pythonhosted.org/packages/5f/fb/e3633e5a6bbed1c76bb2e9810dabc2f8467532ffcd29b9aed404b473061a/time_machine-3.2.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:8c1aee29bc54356f248d5d7dfdd131e12ca825e850a08c0ebdb022266d073013", size = 38952, upload-time = "2025-12-17T23:32:30.031Z" }, + { url = "https://files.pythonhosted.org/packages/82/3d/02e9fb2526b3d6b1b45bc8e4d912d95d1cd699d1a3f6df985817d37a0600/time_machine-3.2.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c8ed2224f09d25b1c2fc98683613aca12f90f682a427eabb68fc824d27014e4a", size = 39829, upload-time = "2025-12-17T23:32:31.075Z" }, + { url = "https://files.pythonhosted.org/packages/85/c8/c14265212436da8e0814c45463987b3f57de3eca4de023cc2eabb0c62ef3/time_machine-3.2.0-cp313-cp313t-win32.whl", hash = "sha256:3498719f8dab51da76d29a20c1b5e52ee7db083dddf3056af7fa69c1b94e1fe6", size = 17852, upload-time = "2025-12-17T23:32:32.079Z" }, + { url = "https://files.pythonhosted.org/packages/1d/bc/8acb13cf6149f47508097b158a9a8bec9ec4530a70cb406124e8023581f5/time_machine-3.2.0-cp313-cp313t-win_amd64.whl", hash = "sha256:e0d90bee170b219e1d15e6a58164aa808f5170090e4f090bd0670303e34181b1", size = 18918, upload-time = "2025-12-17T23:32:33.106Z" }, + { url = "https://files.pythonhosted.org/packages/24/87/c443ee508c2708fd2514ccce9052f5e48888783ce690506919629ebc8eb0/time_machine-3.2.0-cp313-cp313t-win_arm64.whl", hash = "sha256:051de220fdb6e20d648111bbad423d9506fdbb2e44d4429cef3dc0382abf1fc2", size = 17261, upload-time = "2025-12-17T23:32:34.446Z" }, + { url = "https://files.pythonhosted.org/packages/61/70/b4b980d126ed155c78d1879c50d60c8dcbd47bd11cb14ee7be50e0dfc07f/time_machine-3.2.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:1398980c017fe5744d66f419e0115ee48a53b00b146d738e1416c225eb610b82", size = 19303, upload-time = "2025-12-17T23:32:35.796Z" }, + { url = "https://files.pythonhosted.org/packages/73/73/eaa33603c69a68fe2b6f54f9dd75481693d62f1d29676531002be06e2d1c/time_machine-3.2.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:4f8f4e35f4191ef70c2ab8ff490761ee9051b891afce2bf86dde3918eb7b537b", size = 15431, upload-time = "2025-12-17T23:32:37.244Z" }, + { url = "https://files.pythonhosted.org/packages/76/10/b81e138e86cc7bab40cdb59d294b341e172201f4a6c84bb0ec080407977a/time_machine-3.2.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:6db498686ecf6163c5aa8cf0bcd57bbe0f4081184f247edf3ee49a2612b584f9", size = 33206, upload-time = "2025-12-17T23:32:38.713Z" }, + { url = "https://files.pythonhosted.org/packages/d3/72/4deab446b579e8bd5dca91de98595c5d6bd6a17ce162abf5c5f2ce40d3d8/time_machine-3.2.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:027c1807efb74d0cd58ad16524dec94212fbe900115d70b0123399883657ac0f", size = 34792, upload-time = "2025-12-17T23:32:40.223Z" }, + { url = "https://files.pythonhosted.org/packages/2c/39/439c6b587ddee76d533fe972289d0646e0a5520e14dc83d0a30aeb5565f7/time_machine-3.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92432610c05676edd5e6946a073c6f0c926923123ce7caee1018dc10782c713d", size = 36187, upload-time = "2025-12-17T23:32:41.705Z" }, + { url = "https://files.pythonhosted.org/packages/4b/db/2da4368db15180989bab83746a857bde05ad16e78f326801c142bb747a06/time_machine-3.2.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c25586b62480eb77ef3d953fba273209478e1ef49654592cd6a52a68dfe56a67", size = 34855, upload-time = "2025-12-17T23:32:42.817Z" }, + { url = "https://files.pythonhosted.org/packages/88/84/120a431fee50bc4c241425bee4d3a4910df4923b7ab5f7dff1bf0c772f08/time_machine-3.2.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:6bf3a2fa738d15e0b95d14469a0b8ea42635467408d8b490e263d5d45c9a177f", size = 33222, upload-time = "2025-12-17T23:32:43.94Z" }, + { url = "https://files.pythonhosted.org/packages/f9/ea/89cfda82bb8c57ff91bb9a26751aa234d6d90e9b4d5ab0ad9dce0f9f0329/time_machine-3.2.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ce76b82276d7ad2a66cdc85dad4df19d1422b69183170a34e8fbc4c3f35502f7", size = 34270, upload-time = "2025-12-17T23:32:45.037Z" }, + { url = "https://files.pythonhosted.org/packages/8a/aa/235357da4f69a51a8d35fcbfcfa77cdc7dc24f62ae54025006570bda7e2d/time_machine-3.2.0-cp314-cp314-win32.whl", hash = "sha256:14d6778273c543441863dff712cd1d7803dee946b18de35921eb8df10714539d", size = 17544, upload-time = "2025-12-17T23:32:46.099Z" }, + { url = "https://files.pythonhosted.org/packages/7b/51/6c8405a7276be79693b792cff22ce41067ec05db26a7d02f2d5b06324434/time_machine-3.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:cbf821da96dbc80d349fa9e7c36e670b41d68a878d28c8850057992fed430eef", size = 18423, upload-time = "2025-12-17T23:32:47.468Z" }, + { url = "https://files.pythonhosted.org/packages/d9/03/a3cf419e20c35fc203c6e4fed48b5b667c1a2b4da456d9971e605f73ecef/time_machine-3.2.0-cp314-cp314-win_arm64.whl", hash = "sha256:71c75d71f8e68abc8b669bca26ed2ddd558430a6c171e32b8620288565f18c0e", size = 17050, upload-time = "2025-12-17T23:32:48.91Z" }, + { url = "https://files.pythonhosted.org/packages/86/a1/142de946dc4393f910bf4564b5c3ba819906e1f49b06c9cb557519c849e4/time_machine-3.2.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:4e374779021446fc2b5c29d80457ec9a3b1a5df043dc2aae07d7c1415d52323c", size = 19991, upload-time = "2025-12-17T23:32:49.933Z" }, + { url = "https://files.pythonhosted.org/packages/ee/62/7f17def6289901f94726921811a16b9adce46e666362c75d45730c60274f/time_machine-3.2.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:122310a6af9c36e9a636da32830e591e7923e8a07bdd0a43276c3a36c6821c90", size = 15707, upload-time = "2025-12-17T23:32:50.969Z" }, + { url = "https://files.pythonhosted.org/packages/5d/d3/3502fb9bd3acb159c18844b26c43220201a0d4a622c0c853785d07699a92/time_machine-3.2.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:ba3eeb0f018cc362dd8128befa3426696a2e16dd223c3fb695fde184892d4d8c", size = 39207, upload-time = "2025-12-17T23:32:52.033Z" }, + { url = "https://files.pythonhosted.org/packages/5a/be/8b27f4aa296fda14a5a2ad7f588ddd450603c33415ab3f8e85b2f1a44678/time_machine-3.2.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:77d38ba664b381a7793f8786efc13b5004f0d5f672dae814430445b8202a67a6", size = 40764, upload-time = "2025-12-17T23:32:53.167Z" }, + { url = "https://files.pythonhosted.org/packages/42/cd/fe4c4e5c8ab6d48fab3624c32be9116fb120173a35fe67e482e5cf68b3d2/time_machine-3.2.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f09abeb8f03f044d72712207e0489a62098ad3ad16dac38927fcf80baca4d6a7", size = 43508, upload-time = "2025-12-17T23:32:54.597Z" }, + { url = "https://files.pythonhosted.org/packages/b4/28/5a3ba2fce85b97655a425d6bb20a441550acd2b304c96b2c19d3839f721a/time_machine-3.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:6b28367ce4f73987a55e230e1d30a57a3af85da8eb1a140074eb6e8c7e6ef19f", size = 41712, upload-time = "2025-12-17T23:32:55.781Z" }, + { url = "https://files.pythonhosted.org/packages/81/58/e38084be7fdabb4835db68a3a47e58c34182d79fc35df1ecbe0db2c5359f/time_machine-3.2.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:903c7751c904581da9f7861c3015bed7cdc40047321291d3694a3cdc783bbca3", size = 38939, upload-time = "2025-12-17T23:32:56.867Z" }, + { url = "https://files.pythonhosted.org/packages/40/d0/ad3feb0a392ef4e0c08bc32024950373ddc0669002cbdcbb9f3bf0c2d114/time_machine-3.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:528217cad85ede5f85c8bc78b0341868d3c3cfefc6ecb5b622e1cacb6c73247b", size = 39837, upload-time = "2025-12-17T23:32:58.283Z" }, + { url = "https://files.pythonhosted.org/packages/5b/9e/5f4b2ea63b267bd78f3245e76f5528836611b5f2d30b5e7300a722fe4428/time_machine-3.2.0-cp314-cp314t-win32.whl", hash = "sha256:75724762ffd517e7e80aaec1fad1ff5a7414bd84e2b3ee7a0bacfeb67c14926e", size = 18091, upload-time = "2025-12-17T23:32:59.403Z" }, + { url = "https://files.pythonhosted.org/packages/39/6f/456b1f4d2700ae02b19eba830f870596a4b89b74bac3b6c80666f1b108c5/time_machine-3.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2526abbd053c5bca898d1b3e7898eec34626b12206718d8c7ce88fd12c1c9c5c", size = 19208, upload-time = "2025-12-17T23:33:00.488Z" }, + { url = "https://files.pythonhosted.org/packages/2f/22/8063101427ecd3d2652aada4d21d0876b07a3dc789125bca2ee858fec3ed/time_machine-3.2.0-cp314-cp314t-win_arm64.whl", hash = "sha256:7f2fb6784b414edbe2c0b558bfaab0c251955ba27edd62946cce4a01675a992c", size = 17359, upload-time = "2025-12-17T23:33:01.54Z" }, +] + +[[package]] +name = "tomli" +version = "2.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/82/30/31573e9457673ab10aa432461bee537ce6cef177667deca369efb79df071/tomli-2.4.0.tar.gz", hash = "sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c", size = 17477, upload-time = "2026-01-11T11:22:38.165Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/d9/3dc2289e1f3b32eb19b9785b6a006b28ee99acb37d1d47f78d4c10e28bf8/tomli-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867", size = 153663, upload-time = "2026-01-11T11:21:45.27Z" }, + { url = "https://files.pythonhosted.org/packages/51/32/ef9f6845e6b9ca392cd3f64f9ec185cc6f09f0a2df3db08cbe8809d1d435/tomli-2.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9", size = 148469, upload-time = "2026-01-11T11:21:46.873Z" }, + { url = "https://files.pythonhosted.org/packages/d6/c2/506e44cce89a8b1b1e047d64bd495c22c9f71f21e05f380f1a950dd9c217/tomli-2.4.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95", size = 236039, upload-time = "2026-01-11T11:21:48.503Z" }, + { url = "https://files.pythonhosted.org/packages/b3/40/e1b65986dbc861b7e986e8ec394598187fa8aee85b1650b01dd925ca0be8/tomli-2.4.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76", size = 243007, upload-time = "2026-01-11T11:21:49.456Z" }, + { url = "https://files.pythonhosted.org/packages/9c/6f/6e39ce66b58a5b7ae572a0f4352ff40c71e8573633deda43f6a379d56b3e/tomli-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d", size = 240875, upload-time = "2026-01-11T11:21:50.755Z" }, + { url = "https://files.pythonhosted.org/packages/aa/ad/cb089cb190487caa80204d503c7fd0f4d443f90b95cf4ef5cf5aa0f439b0/tomli-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576", size = 246271, upload-time = "2026-01-11T11:21:51.81Z" }, + { url = "https://files.pythonhosted.org/packages/0b/63/69125220e47fd7a3a27fd0de0c6398c89432fec41bc739823bcc66506af6/tomli-2.4.0-cp311-cp311-win32.whl", hash = "sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a", size = 96770, upload-time = "2026-01-11T11:21:52.647Z" }, + { url = "https://files.pythonhosted.org/packages/1e/0d/a22bb6c83f83386b0008425a6cd1fa1c14b5f3dd4bad05e98cf3dbbf4a64/tomli-2.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa", size = 107626, upload-time = "2026-01-11T11:21:53.459Z" }, + { url = "https://files.pythonhosted.org/packages/2f/6d/77be674a3485e75cacbf2ddba2b146911477bd887dda9d8c9dfb2f15e871/tomli-2.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614", size = 94842, upload-time = "2026-01-11T11:21:54.831Z" }, + { url = "https://files.pythonhosted.org/packages/3c/43/7389a1869f2f26dba52404e1ef13b4784b6b37dac93bac53457e3ff24ca3/tomli-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1", size = 154894, upload-time = "2026-01-11T11:21:56.07Z" }, + { url = "https://files.pythonhosted.org/packages/e9/05/2f9bf110b5294132b2edf13fe6ca6ae456204f3d749f623307cbb7a946f2/tomli-2.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8", size = 149053, upload-time = "2026-01-11T11:21:57.467Z" }, + { url = "https://files.pythonhosted.org/packages/e8/41/1eda3ca1abc6f6154a8db4d714a4d35c4ad90adc0bcf700657291593fbf3/tomli-2.4.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a", size = 243481, upload-time = "2026-01-11T11:21:58.661Z" }, + { url = "https://files.pythonhosted.org/packages/d2/6d/02ff5ab6c8868b41e7d4b987ce2b5f6a51d3335a70aa144edd999e055a01/tomli-2.4.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1", size = 251720, upload-time = "2026-01-11T11:22:00.178Z" }, + { url = "https://files.pythonhosted.org/packages/7b/57/0405c59a909c45d5b6f146107c6d997825aa87568b042042f7a9c0afed34/tomli-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b", size = 247014, upload-time = "2026-01-11T11:22:01.238Z" }, + { url = "https://files.pythonhosted.org/packages/2c/0e/2e37568edd944b4165735687cbaf2fe3648129e440c26d02223672ee0630/tomli-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51", size = 251820, upload-time = "2026-01-11T11:22:02.727Z" }, + { url = "https://files.pythonhosted.org/packages/5a/1c/ee3b707fdac82aeeb92d1a113f803cf6d0f37bdca0849cb489553e1f417a/tomli-2.4.0-cp312-cp312-win32.whl", hash = "sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729", size = 97712, upload-time = "2026-01-11T11:22:03.777Z" }, + { url = "https://files.pythonhosted.org/packages/69/13/c07a9177d0b3bab7913299b9278845fc6eaaca14a02667c6be0b0a2270c8/tomli-2.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da", size = 108296, upload-time = "2026-01-11T11:22:04.86Z" }, + { url = "https://files.pythonhosted.org/packages/18/27/e267a60bbeeee343bcc279bb9e8fbed0cbe224bc7b2a3dc2975f22809a09/tomli-2.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3", size = 94553, upload-time = "2026-01-11T11:22:05.854Z" }, + { url = "https://files.pythonhosted.org/packages/34/91/7f65f9809f2936e1f4ce6268ae1903074563603b2a2bd969ebbda802744f/tomli-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0", size = 154915, upload-time = "2026-01-11T11:22:06.703Z" }, + { url = "https://files.pythonhosted.org/packages/20/aa/64dd73a5a849c2e8f216b755599c511badde80e91e9bc2271baa7b2cdbb1/tomli-2.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e", size = 149038, upload-time = "2026-01-11T11:22:07.56Z" }, + { url = "https://files.pythonhosted.org/packages/9e/8a/6d38870bd3d52c8d1505ce054469a73f73a0fe62c0eaf5dddf61447e32fa/tomli-2.4.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4", size = 242245, upload-time = "2026-01-11T11:22:08.344Z" }, + { url = "https://files.pythonhosted.org/packages/59/bb/8002fadefb64ab2669e5b977df3f5e444febea60e717e755b38bb7c41029/tomli-2.4.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e", size = 250335, upload-time = "2026-01-11T11:22:09.951Z" }, + { url = "https://files.pythonhosted.org/packages/a5/3d/4cdb6f791682b2ea916af2de96121b3cb1284d7c203d97d92d6003e91c8d/tomli-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c", size = 245962, upload-time = "2026-01-11T11:22:11.27Z" }, + { url = "https://files.pythonhosted.org/packages/f2/4a/5f25789f9a460bd858ba9756ff52d0830d825b458e13f754952dd15fb7bb/tomli-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f", size = 250396, upload-time = "2026-01-11T11:22:12.325Z" }, + { url = "https://files.pythonhosted.org/packages/aa/2f/b73a36fea58dfa08e8b3a268750e6853a6aac2a349241a905ebd86f3047a/tomli-2.4.0-cp313-cp313-win32.whl", hash = "sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86", size = 97530, upload-time = "2026-01-11T11:22:13.865Z" }, + { url = "https://files.pythonhosted.org/packages/3b/af/ca18c134b5d75de7e8dc551c5234eaba2e8e951f6b30139599b53de9c187/tomli-2.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87", size = 108227, upload-time = "2026-01-11T11:22:15.224Z" }, + { url = "https://files.pythonhosted.org/packages/22/c3/b386b832f209fee8073c8138ec50f27b4460db2fdae9ffe022df89a57f9b/tomli-2.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132", size = 94748, upload-time = "2026-01-11T11:22:16.009Z" }, + { url = "https://files.pythonhosted.org/packages/f3/c4/84047a97eb1004418bc10bdbcfebda209fca6338002eba2dc27cc6d13563/tomli-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6", size = 154725, upload-time = "2026-01-11T11:22:17.269Z" }, + { url = "https://files.pythonhosted.org/packages/a8/5d/d39038e646060b9d76274078cddf146ced86dc2b9e8bbf737ad5983609a0/tomli-2.4.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc", size = 148901, upload-time = "2026-01-11T11:22:18.287Z" }, + { url = "https://files.pythonhosted.org/packages/73/e5/383be1724cb30f4ce44983d249645684a48c435e1cd4f8b5cded8a816d3c/tomli-2.4.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66", size = 243375, upload-time = "2026-01-11T11:22:19.154Z" }, + { url = "https://files.pythonhosted.org/packages/31/f0/bea80c17971c8d16d3cc109dc3585b0f2ce1036b5f4a8a183789023574f2/tomli-2.4.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d", size = 250639, upload-time = "2026-01-11T11:22:20.168Z" }, + { url = "https://files.pythonhosted.org/packages/2c/8f/2853c36abbb7608e3f945d8a74e32ed3a74ee3a1f468f1ffc7d1cb3abba6/tomli-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702", size = 246897, upload-time = "2026-01-11T11:22:21.544Z" }, + { url = "https://files.pythonhosted.org/packages/49/f0/6c05e3196ed5337b9fe7ea003e95fd3819a840b7a0f2bf5a408ef1dad8ed/tomli-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8", size = 254697, upload-time = "2026-01-11T11:22:23.058Z" }, + { url = "https://files.pythonhosted.org/packages/f3/f5/2922ef29c9f2951883525def7429967fc4d8208494e5ab524234f06b688b/tomli-2.4.0-cp314-cp314-win32.whl", hash = "sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776", size = 98567, upload-time = "2026-01-11T11:22:24.033Z" }, + { url = "https://files.pythonhosted.org/packages/7b/31/22b52e2e06dd2a5fdbc3ee73226d763b184ff21fc24e20316a44ccc4d96b/tomli-2.4.0-cp314-cp314-win_amd64.whl", hash = "sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475", size = 108556, upload-time = "2026-01-11T11:22:25.378Z" }, + { url = "https://files.pythonhosted.org/packages/48/3d/5058dff3255a3d01b705413f64f4306a141a8fd7a251e5a495e3f192a998/tomli-2.4.0-cp314-cp314-win_arm64.whl", hash = "sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2", size = 96014, upload-time = "2026-01-11T11:22:26.138Z" }, + { url = "https://files.pythonhosted.org/packages/b8/4e/75dab8586e268424202d3a1997ef6014919c941b50642a1682df43204c22/tomli-2.4.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9", size = 163339, upload-time = "2026-01-11T11:22:27.143Z" }, + { url = "https://files.pythonhosted.org/packages/06/e3/b904d9ab1016829a776d97f163f183a48be6a4deb87304d1e0116a349519/tomli-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0", size = 159490, upload-time = "2026-01-11T11:22:28.399Z" }, + { url = "https://files.pythonhosted.org/packages/e3/5a/fc3622c8b1ad823e8ea98a35e3c632ee316d48f66f80f9708ceb4f2a0322/tomli-2.4.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df", size = 269398, upload-time = "2026-01-11T11:22:29.345Z" }, + { url = "https://files.pythonhosted.org/packages/fd/33/62bd6152c8bdd4c305ad9faca48f51d3acb2df1f8791b1477d46ff86e7f8/tomli-2.4.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d", size = 276515, upload-time = "2026-01-11T11:22:30.327Z" }, + { url = "https://files.pythonhosted.org/packages/4b/ff/ae53619499f5235ee4211e62a8d7982ba9e439a0fb4f2f351a93d67c1dd2/tomli-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f", size = 273806, upload-time = "2026-01-11T11:22:32.56Z" }, + { url = "https://files.pythonhosted.org/packages/47/71/cbca7787fa68d4d0a9f7072821980b39fbb1b6faeb5f5cf02f4a5559fa28/tomli-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b", size = 281340, upload-time = "2026-01-11T11:22:33.505Z" }, + { url = "https://files.pythonhosted.org/packages/f5/00/d595c120963ad42474cf6ee7771ad0d0e8a49d0f01e29576ee9195d9ecdf/tomli-2.4.0-cp314-cp314t-win32.whl", hash = "sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087", size = 108106, upload-time = "2026-01-11T11:22:34.451Z" }, + { url = "https://files.pythonhosted.org/packages/de/69/9aa0c6a505c2f80e519b43764f8b4ba93b5a0bbd2d9a9de6e2b24271b9a5/tomli-2.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd", size = 120504, upload-time = "2026-01-11T11:22:35.764Z" }, + { url = "https://files.pythonhosted.org/packages/b3/9f/f1668c281c58cfae01482f7114a4b88d345e4c140386241a1a24dcc9e7bc/tomli-2.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4", size = 99561, upload-time = "2026-01-11T11:22:36.624Z" }, + { url = "https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl", hash = "sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a", size = 14477, upload-time = "2026-01-11T11:22:37.446Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "extra == 'group-11-phoebe-bird-pydantic-v2' or extra != 'group-11-phoebe-bird-pydantic-v1'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, +] + +[[package]] +name = "yarl" +version = "1.22.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "multidict" }, + { name = "propcache" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/57/63/0c6ebca57330cd313f6102b16dd57ffaf3ec4c83403dcb45dbd15c6f3ea1/yarl-1.22.0.tar.gz", hash = "sha256:bebf8557577d4401ba8bd9ff33906f1376c877aa78d1fe216ad01b4d6745af71", size = 187169, upload-time = "2025-10-06T14:12:55.963Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/43/a2204825342f37c337f5edb6637040fa14e365b2fcc2346960201d457579/yarl-1.22.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c7bd6683587567e5a49ee6e336e0612bec8329be1b7d4c8af5687dcdeb67ee1e", size = 140517, upload-time = "2025-10-06T14:08:42.494Z" }, + { url = "https://files.pythonhosted.org/packages/44/6f/674f3e6f02266428c56f704cd2501c22f78e8b2eeb23f153117cc86fb28a/yarl-1.22.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5cdac20da754f3a723cceea5b3448e1a2074866406adeb4ef35b469d089adb8f", size = 93495, upload-time = "2025-10-06T14:08:46.2Z" }, + { url = "https://files.pythonhosted.org/packages/b8/12/5b274d8a0f30c07b91b2f02cba69152600b47830fcfb465c108880fcee9c/yarl-1.22.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:07a524d84df0c10f41e3ee918846e1974aba4ec017f990dc735aad487a0bdfdf", size = 94400, upload-time = "2025-10-06T14:08:47.855Z" }, + { url = "https://files.pythonhosted.org/packages/e2/7f/df1b6949b1fa1aa9ff6de6e2631876ad4b73c4437822026e85d8acb56bb1/yarl-1.22.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e1b329cb8146d7b736677a2440e422eadd775d1806a81db2d4cded80a48efc1a", size = 347545, upload-time = "2025-10-06T14:08:49.683Z" }, + { url = "https://files.pythonhosted.org/packages/84/09/f92ed93bd6cd77872ab6c3462df45ca45cd058d8f1d0c9b4f54c1704429f/yarl-1.22.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:75976c6945d85dbb9ee6308cd7ff7b1fb9409380c82d6119bd778d8fcfe2931c", size = 319598, upload-time = "2025-10-06T14:08:51.215Z" }, + { url = "https://files.pythonhosted.org/packages/c3/97/ac3f3feae7d522cf7ccec3d340bb0b2b61c56cb9767923df62a135092c6b/yarl-1.22.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:80ddf7a5f8c86cb3eb4bc9028b07bbbf1f08a96c5c0bc1244be5e8fefcb94147", size = 363893, upload-time = "2025-10-06T14:08:53.144Z" }, + { url = "https://files.pythonhosted.org/packages/06/49/f3219097403b9c84a4d079b1d7bda62dd9b86d0d6e4428c02d46ab2c77fc/yarl-1.22.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d332fc2e3c94dad927f2112395772a4e4fedbcf8f80efc21ed7cdfae4d574fdb", size = 371240, upload-time = "2025-10-06T14:08:55.036Z" }, + { url = "https://files.pythonhosted.org/packages/35/9f/06b765d45c0e44e8ecf0fe15c9eacbbde342bb5b7561c46944f107bfb6c3/yarl-1.22.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0cf71bf877efeac18b38d3930594c0948c82b64547c1cf420ba48722fe5509f6", size = 346965, upload-time = "2025-10-06T14:08:56.722Z" }, + { url = "https://files.pythonhosted.org/packages/c5/69/599e7cea8d0fcb1694323b0db0dda317fa3162f7b90166faddecf532166f/yarl-1.22.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:663e1cadaddae26be034a6ab6072449a8426ddb03d500f43daf952b74553bba0", size = 342026, upload-time = "2025-10-06T14:08:58.563Z" }, + { url = "https://files.pythonhosted.org/packages/95/6f/9dfd12c8bc90fea9eab39832ee32ea48f8e53d1256252a77b710c065c89f/yarl-1.22.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:6dcbb0829c671f305be48a7227918cfcd11276c2d637a8033a99a02b67bf9eda", size = 335637, upload-time = "2025-10-06T14:09:00.506Z" }, + { url = "https://files.pythonhosted.org/packages/57/2e/34c5b4eb9b07e16e873db5b182c71e5f06f9b5af388cdaa97736d79dd9a6/yarl-1.22.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:f0d97c18dfd9a9af4490631905a3f131a8e4c9e80a39353919e2cfed8f00aedc", size = 359082, upload-time = "2025-10-06T14:09:01.936Z" }, + { url = "https://files.pythonhosted.org/packages/31/71/fa7e10fb772d273aa1f096ecb8ab8594117822f683bab7d2c5a89914c92a/yarl-1.22.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:437840083abe022c978470b942ff832c3940b2ad3734d424b7eaffcd07f76737", size = 357811, upload-time = "2025-10-06T14:09:03.445Z" }, + { url = "https://files.pythonhosted.org/packages/26/da/11374c04e8e1184a6a03cf9c8f5688d3e5cec83ed6f31ad3481b3207f709/yarl-1.22.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a899cbd98dce6f5d8de1aad31cb712ec0a530abc0a86bd6edaa47c1090138467", size = 351223, upload-time = "2025-10-06T14:09:05.401Z" }, + { url = "https://files.pythonhosted.org/packages/82/8f/e2d01f161b0c034a30410e375e191a5d27608c1f8693bab1a08b089ca096/yarl-1.22.0-cp310-cp310-win32.whl", hash = "sha256:595697f68bd1f0c1c159fcb97b661fc9c3f5db46498043555d04805430e79bea", size = 82118, upload-time = "2025-10-06T14:09:11.148Z" }, + { url = "https://files.pythonhosted.org/packages/62/46/94c76196642dbeae634c7a61ba3da88cd77bed875bf6e4a8bed037505aa6/yarl-1.22.0-cp310-cp310-win_amd64.whl", hash = "sha256:cb95a9b1adaa48e41815a55ae740cfda005758104049a640a398120bf02515ca", size = 86852, upload-time = "2025-10-06T14:09:12.958Z" }, + { url = "https://files.pythonhosted.org/packages/af/af/7df4f179d3b1a6dcb9a4bd2ffbc67642746fcafdb62580e66876ce83fff4/yarl-1.22.0-cp310-cp310-win_arm64.whl", hash = "sha256:b85b982afde6df99ecc996990d4ad7ccbdbb70e2a4ba4de0aecde5922ba98a0b", size = 82012, upload-time = "2025-10-06T14:09:14.664Z" }, + { url = "https://files.pythonhosted.org/packages/4d/27/5ab13fc84c76a0250afd3d26d5936349a35be56ce5785447d6c423b26d92/yarl-1.22.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1ab72135b1f2db3fed3997d7e7dc1b80573c67138023852b6efb336a5eae6511", size = 141607, upload-time = "2025-10-06T14:09:16.298Z" }, + { url = "https://files.pythonhosted.org/packages/6a/a1/d065d51d02dc02ce81501d476b9ed2229d9a990818332242a882d5d60340/yarl-1.22.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:669930400e375570189492dc8d8341301578e8493aec04aebc20d4717f899dd6", size = 94027, upload-time = "2025-10-06T14:09:17.786Z" }, + { url = "https://files.pythonhosted.org/packages/c1/da/8da9f6a53f67b5106ffe902c6fa0164e10398d4e150d85838b82f424072a/yarl-1.22.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:792a2af6d58177ef7c19cbf0097aba92ca1b9cb3ffdd9c7470e156c8f9b5e028", size = 94963, upload-time = "2025-10-06T14:09:19.662Z" }, + { url = "https://files.pythonhosted.org/packages/68/fe/2c1f674960c376e29cb0bec1249b117d11738db92a6ccc4a530b972648db/yarl-1.22.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3ea66b1c11c9150f1372f69afb6b8116f2dd7286f38e14ea71a44eee9ec51b9d", size = 368406, upload-time = "2025-10-06T14:09:21.402Z" }, + { url = "https://files.pythonhosted.org/packages/95/26/812a540e1c3c6418fec60e9bbd38e871eaba9545e94fa5eff8f4a8e28e1e/yarl-1.22.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3e2daa88dc91870215961e96a039ec73e4937da13cf77ce17f9cad0c18df3503", size = 336581, upload-time = "2025-10-06T14:09:22.98Z" }, + { url = "https://files.pythonhosted.org/packages/0b/f5/5777b19e26fdf98563985e481f8be3d8a39f8734147a6ebf459d0dab5a6b/yarl-1.22.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ba440ae430c00eee41509353628600212112cd5018d5def7e9b05ea7ac34eb65", size = 388924, upload-time = "2025-10-06T14:09:24.655Z" }, + { url = "https://files.pythonhosted.org/packages/86/08/24bd2477bd59c0bbd994fe1d93b126e0472e4e3df5a96a277b0a55309e89/yarl-1.22.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e6438cc8f23a9c1478633d216b16104a586b9761db62bfacb6425bac0a36679e", size = 392890, upload-time = "2025-10-06T14:09:26.617Z" }, + { url = "https://files.pythonhosted.org/packages/46/00/71b90ed48e895667ecfb1eaab27c1523ee2fa217433ed77a73b13205ca4b/yarl-1.22.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c52a6e78aef5cf47a98ef8e934755abf53953379b7d53e68b15ff4420e6683d", size = 365819, upload-time = "2025-10-06T14:09:28.544Z" }, + { url = "https://files.pythonhosted.org/packages/30/2d/f715501cae832651d3282387c6a9236cd26bd00d0ff1e404b3dc52447884/yarl-1.22.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3b06bcadaac49c70f4c88af4ffcfbe3dc155aab3163e75777818092478bcbbe7", size = 363601, upload-time = "2025-10-06T14:09:30.568Z" }, + { url = "https://files.pythonhosted.org/packages/f8/f9/a678c992d78e394e7126ee0b0e4e71bd2775e4334d00a9278c06a6cce96a/yarl-1.22.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:6944b2dc72c4d7f7052683487e3677456050ff77fcf5e6204e98caf785ad1967", size = 358072, upload-time = "2025-10-06T14:09:32.528Z" }, + { url = "https://files.pythonhosted.org/packages/2c/d1/b49454411a60edb6fefdcad4f8e6dbba7d8019e3a508a1c5836cba6d0781/yarl-1.22.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d5372ca1df0f91a86b047d1277c2aaf1edb32d78bbcefffc81b40ffd18f027ed", size = 385311, upload-time = "2025-10-06T14:09:34.634Z" }, + { url = "https://files.pythonhosted.org/packages/87/e5/40d7a94debb8448c7771a916d1861d6609dddf7958dc381117e7ba36d9e8/yarl-1.22.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:51af598701f5299012b8416486b40fceef8c26fc87dc6d7d1f6fc30609ea0aa6", size = 381094, upload-time = "2025-10-06T14:09:36.268Z" }, + { url = "https://files.pythonhosted.org/packages/35/d8/611cc282502381ad855448643e1ad0538957fc82ae83dfe7762c14069e14/yarl-1.22.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b266bd01fedeffeeac01a79ae181719ff848a5a13ce10075adbefc8f1daee70e", size = 370944, upload-time = "2025-10-06T14:09:37.872Z" }, + { url = "https://files.pythonhosted.org/packages/2d/df/fadd00fb1c90e1a5a8bd731fa3d3de2e165e5a3666a095b04e31b04d9cb6/yarl-1.22.0-cp311-cp311-win32.whl", hash = "sha256:a9b1ba5610a4e20f655258d5a1fdc7ebe3d837bb0e45b581398b99eb98b1f5ca", size = 81804, upload-time = "2025-10-06T14:09:39.359Z" }, + { url = "https://files.pythonhosted.org/packages/b5/f7/149bb6f45f267cb5c074ac40c01c6b3ea6d8a620d34b337f6321928a1b4d/yarl-1.22.0-cp311-cp311-win_amd64.whl", hash = "sha256:078278b9b0b11568937d9509b589ee83ef98ed6d561dfe2020e24a9fd08eaa2b", size = 86858, upload-time = "2025-10-06T14:09:41.068Z" }, + { url = "https://files.pythonhosted.org/packages/2b/13/88b78b93ad3f2f0b78e13bfaaa24d11cbc746e93fe76d8c06bf139615646/yarl-1.22.0-cp311-cp311-win_arm64.whl", hash = "sha256:b6a6f620cfe13ccec221fa312139135166e47ae169f8253f72a0abc0dae94376", size = 81637, upload-time = "2025-10-06T14:09:42.712Z" }, + { url = "https://files.pythonhosted.org/packages/75/ff/46736024fee3429b80a165a732e38e5d5a238721e634ab41b040d49f8738/yarl-1.22.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e340382d1afa5d32b892b3ff062436d592ec3d692aeea3bef3a5cfe11bbf8c6f", size = 142000, upload-time = "2025-10-06T14:09:44.631Z" }, + { url = "https://files.pythonhosted.org/packages/5a/9a/b312ed670df903145598914770eb12de1bac44599549b3360acc96878df8/yarl-1.22.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f1e09112a2c31ffe8d80be1b0988fa6a18c5d5cad92a9ffbb1c04c91bfe52ad2", size = 94338, upload-time = "2025-10-06T14:09:46.372Z" }, + { url = "https://files.pythonhosted.org/packages/ba/f5/0601483296f09c3c65e303d60c070a5c19fcdbc72daa061e96170785bc7d/yarl-1.22.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:939fe60db294c786f6b7c2d2e121576628468f65453d86b0fe36cb52f987bd74", size = 94909, upload-time = "2025-10-06T14:09:48.648Z" }, + { url = "https://files.pythonhosted.org/packages/60/41/9a1fe0b73dbcefce72e46cf149b0e0a67612d60bfc90fb59c2b2efdfbd86/yarl-1.22.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e1651bf8e0398574646744c1885a41198eba53dc8a9312b954073f845c90a8df", size = 372940, upload-time = "2025-10-06T14:09:50.089Z" }, + { url = "https://files.pythonhosted.org/packages/17/7a/795cb6dfee561961c30b800f0ed616b923a2ec6258b5def2a00bf8231334/yarl-1.22.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b8a0588521a26bf92a57a1705b77b8b59044cdceccac7151bd8d229e66b8dedb", size = 345825, upload-time = "2025-10-06T14:09:52.142Z" }, + { url = "https://files.pythonhosted.org/packages/d7/93/a58f4d596d2be2ae7bab1a5846c4d270b894958845753b2c606d666744d3/yarl-1.22.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:42188e6a615c1a75bcaa6e150c3fe8f3e8680471a6b10150c5f7e83f47cc34d2", size = 386705, upload-time = "2025-10-06T14:09:54.128Z" }, + { url = "https://files.pythonhosted.org/packages/61/92/682279d0e099d0e14d7fd2e176bd04f48de1484f56546a3e1313cd6c8e7c/yarl-1.22.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f6d2cb59377d99718913ad9a151030d6f83ef420a2b8f521d94609ecc106ee82", size = 396518, upload-time = "2025-10-06T14:09:55.762Z" }, + { url = "https://files.pythonhosted.org/packages/db/0f/0d52c98b8a885aeda831224b78f3be7ec2e1aa4a62091f9f9188c3c65b56/yarl-1.22.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50678a3b71c751d58d7908edc96d332af328839eea883bb554a43f539101277a", size = 377267, upload-time = "2025-10-06T14:09:57.958Z" }, + { url = "https://files.pythonhosted.org/packages/22/42/d2685e35908cbeaa6532c1fc73e89e7f2efb5d8a7df3959ea8e37177c5a3/yarl-1.22.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1e8fbaa7cec507aa24ea27a01456e8dd4b6fab829059b69844bd348f2d467124", size = 365797, upload-time = "2025-10-06T14:09:59.527Z" }, + { url = "https://files.pythonhosted.org/packages/a2/83/cf8c7bcc6355631762f7d8bdab920ad09b82efa6b722999dfb05afa6cfac/yarl-1.22.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:433885ab5431bc3d3d4f2f9bd15bfa1614c522b0f1405d62c4f926ccd69d04fa", size = 365535, upload-time = "2025-10-06T14:10:01.139Z" }, + { url = "https://files.pythonhosted.org/packages/25/e1/5302ff9b28f0c59cac913b91fe3f16c59a033887e57ce9ca5d41a3a94737/yarl-1.22.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:b790b39c7e9a4192dc2e201a282109ed2985a1ddbd5ac08dc56d0e121400a8f7", size = 382324, upload-time = "2025-10-06T14:10:02.756Z" }, + { url = "https://files.pythonhosted.org/packages/bf/cd/4617eb60f032f19ae3a688dc990d8f0d89ee0ea378b61cac81ede3e52fae/yarl-1.22.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:31f0b53913220599446872d757257be5898019c85e7971599065bc55065dc99d", size = 383803, upload-time = "2025-10-06T14:10:04.552Z" }, + { url = "https://files.pythonhosted.org/packages/59/65/afc6e62bb506a319ea67b694551dab4a7e6fb7bf604e9bd9f3e11d575fec/yarl-1.22.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a49370e8f711daec68d09b821a34e1167792ee2d24d405cbc2387be4f158b520", size = 374220, upload-time = "2025-10-06T14:10:06.489Z" }, + { url = "https://files.pythonhosted.org/packages/e7/3d/68bf18d50dc674b942daec86a9ba922d3113d8399b0e52b9897530442da2/yarl-1.22.0-cp312-cp312-win32.whl", hash = "sha256:70dfd4f241c04bd9239d53b17f11e6ab672b9f1420364af63e8531198e3f5fe8", size = 81589, upload-time = "2025-10-06T14:10:09.254Z" }, + { url = "https://files.pythonhosted.org/packages/c8/9a/6ad1a9b37c2f72874f93e691b2e7ecb6137fb2b899983125db4204e47575/yarl-1.22.0-cp312-cp312-win_amd64.whl", hash = "sha256:8884d8b332a5e9b88e23f60bb166890009429391864c685e17bd73a9eda9105c", size = 87213, upload-time = "2025-10-06T14:10:11.369Z" }, + { url = "https://files.pythonhosted.org/packages/44/c5/c21b562d1680a77634d748e30c653c3ca918beb35555cff24986fff54598/yarl-1.22.0-cp312-cp312-win_arm64.whl", hash = "sha256:ea70f61a47f3cc93bdf8b2f368ed359ef02a01ca6393916bc8ff877427181e74", size = 81330, upload-time = "2025-10-06T14:10:13.112Z" }, + { url = "https://files.pythonhosted.org/packages/ea/f3/d67de7260456ee105dc1d162d43a019ecad6b91e2f51809d6cddaa56690e/yarl-1.22.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8dee9c25c74997f6a750cd317b8ca63545169c098faee42c84aa5e506c819b53", size = 139980, upload-time = "2025-10-06T14:10:14.601Z" }, + { url = "https://files.pythonhosted.org/packages/01/88/04d98af0b47e0ef42597b9b28863b9060bb515524da0a65d5f4db160b2d5/yarl-1.22.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:01e73b85a5434f89fc4fe27dcda2aff08ddf35e4d47bbbea3bdcd25321af538a", size = 93424, upload-time = "2025-10-06T14:10:16.115Z" }, + { url = "https://files.pythonhosted.org/packages/18/91/3274b215fd8442a03975ce6bee5fe6aa57a8326b29b9d3d56234a1dca244/yarl-1.22.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:22965c2af250d20c873cdbee8ff958fb809940aeb2e74ba5f20aaf6b7ac8c70c", size = 93821, upload-time = "2025-10-06T14:10:17.993Z" }, + { url = "https://files.pythonhosted.org/packages/61/3a/caf4e25036db0f2da4ca22a353dfeb3c9d3c95d2761ebe9b14df8fc16eb0/yarl-1.22.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4f15793aa49793ec8d1c708ab7f9eded1aa72edc5174cae703651555ed1b601", size = 373243, upload-time = "2025-10-06T14:10:19.44Z" }, + { url = "https://files.pythonhosted.org/packages/6e/9e/51a77ac7516e8e7803b06e01f74e78649c24ee1021eca3d6a739cb6ea49c/yarl-1.22.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5542339dcf2747135c5c85f68680353d5cb9ffd741c0f2e8d832d054d41f35a", size = 342361, upload-time = "2025-10-06T14:10:21.124Z" }, + { url = "https://files.pythonhosted.org/packages/d4/f8/33b92454789dde8407f156c00303e9a891f1f51a0330b0fad7c909f87692/yarl-1.22.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5c401e05ad47a75869c3ab3e35137f8468b846770587e70d71e11de797d113df", size = 387036, upload-time = "2025-10-06T14:10:22.902Z" }, + { url = "https://files.pythonhosted.org/packages/d9/9a/c5db84ea024f76838220280f732970aa4ee154015d7f5c1bfb60a267af6f/yarl-1.22.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:243dda95d901c733f5b59214d28b0120893d91777cb8aa043e6ef059d3cddfe2", size = 397671, upload-time = "2025-10-06T14:10:24.523Z" }, + { url = "https://files.pythonhosted.org/packages/11/c9/cd8538dc2e7727095e0c1d867bad1e40c98f37763e6d995c1939f5fdc7b1/yarl-1.22.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bec03d0d388060058f5d291a813f21c011041938a441c593374da6077fe21b1b", size = 377059, upload-time = "2025-10-06T14:10:26.406Z" }, + { url = "https://files.pythonhosted.org/packages/a1/b9/ab437b261702ced75122ed78a876a6dec0a1b0f5e17a4ac7a9a2482d8abe/yarl-1.22.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b0748275abb8c1e1e09301ee3cf90c8a99678a4e92e4373705f2a2570d581273", size = 365356, upload-time = "2025-10-06T14:10:28.461Z" }, + { url = "https://files.pythonhosted.org/packages/b2/9d/8e1ae6d1d008a9567877b08f0ce4077a29974c04c062dabdb923ed98e6fe/yarl-1.22.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:47fdb18187e2a4e18fda2c25c05d8251a9e4a521edaed757fef033e7d8498d9a", size = 361331, upload-time = "2025-10-06T14:10:30.541Z" }, + { url = "https://files.pythonhosted.org/packages/ca/5a/09b7be3905962f145b73beb468cdd53db8aa171cf18c80400a54c5b82846/yarl-1.22.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c7044802eec4524fde550afc28edda0dd5784c4c45f0be151a2d3ba017daca7d", size = 382590, upload-time = "2025-10-06T14:10:33.352Z" }, + { url = "https://files.pythonhosted.org/packages/aa/7f/59ec509abf90eda5048b0bc3e2d7b5099dffdb3e6b127019895ab9d5ef44/yarl-1.22.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:139718f35149ff544caba20fce6e8a2f71f1e39b92c700d8438a0b1d2a631a02", size = 385316, upload-time = "2025-10-06T14:10:35.034Z" }, + { url = "https://files.pythonhosted.org/packages/e5/84/891158426bc8036bfdfd862fabd0e0fa25df4176ec793e447f4b85cf1be4/yarl-1.22.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e1b51bebd221006d3d2f95fbe124b22b247136647ae5dcc8c7acafba66e5ee67", size = 374431, upload-time = "2025-10-06T14:10:37.76Z" }, + { url = "https://files.pythonhosted.org/packages/bb/49/03da1580665baa8bef5e8ed34c6df2c2aca0a2f28bf397ed238cc1bbc6f2/yarl-1.22.0-cp313-cp313-win32.whl", hash = "sha256:d3e32536234a95f513bd374e93d717cf6b2231a791758de6c509e3653f234c95", size = 81555, upload-time = "2025-10-06T14:10:39.649Z" }, + { url = "https://files.pythonhosted.org/packages/9a/ee/450914ae11b419eadd067c6183ae08381cfdfcb9798b90b2b713bbebddda/yarl-1.22.0-cp313-cp313-win_amd64.whl", hash = "sha256:47743b82b76d89a1d20b83e60d5c20314cbd5ba2befc9cda8f28300c4a08ed4d", size = 86965, upload-time = "2025-10-06T14:10:41.313Z" }, + { url = "https://files.pythonhosted.org/packages/98/4d/264a01eae03b6cf629ad69bae94e3b0e5344741e929073678e84bf7a3e3b/yarl-1.22.0-cp313-cp313-win_arm64.whl", hash = "sha256:5d0fcda9608875f7d052eff120c7a5da474a6796fe4d83e152e0e4d42f6d1a9b", size = 81205, upload-time = "2025-10-06T14:10:43.167Z" }, + { url = "https://files.pythonhosted.org/packages/88/fc/6908f062a2f77b5f9f6d69cecb1747260831ff206adcbc5b510aff88df91/yarl-1.22.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:719ae08b6972befcba4310e49edb1161a88cdd331e3a694b84466bd938a6ab10", size = 146209, upload-time = "2025-10-06T14:10:44.643Z" }, + { url = "https://files.pythonhosted.org/packages/65/47/76594ae8eab26210b4867be6f49129861ad33da1f1ebdf7051e98492bf62/yarl-1.22.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:47d8a5c446df1c4db9d21b49619ffdba90e77c89ec6e283f453856c74b50b9e3", size = 95966, upload-time = "2025-10-06T14:10:46.554Z" }, + { url = "https://files.pythonhosted.org/packages/ab/ce/05e9828a49271ba6b5b038b15b3934e996980dd78abdfeb52a04cfb9467e/yarl-1.22.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cfebc0ac8333520d2d0423cbbe43ae43c8838862ddb898f5ca68565e395516e9", size = 97312, upload-time = "2025-10-06T14:10:48.007Z" }, + { url = "https://files.pythonhosted.org/packages/d1/c5/7dffad5e4f2265b29c9d7ec869c369e4223166e4f9206fc2243ee9eea727/yarl-1.22.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4398557cbf484207df000309235979c79c4356518fd5c99158c7d38203c4da4f", size = 361967, upload-time = "2025-10-06T14:10:49.997Z" }, + { url = "https://files.pythonhosted.org/packages/50/b2/375b933c93a54bff7fc041e1a6ad2c0f6f733ffb0c6e642ce56ee3b39970/yarl-1.22.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2ca6fd72a8cd803be290d42f2dec5cdcd5299eeb93c2d929bf060ad9efaf5de0", size = 323949, upload-time = "2025-10-06T14:10:52.004Z" }, + { url = "https://files.pythonhosted.org/packages/66/50/bfc2a29a1d78644c5a7220ce2f304f38248dc94124a326794e677634b6cf/yarl-1.22.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca1f59c4e1ab6e72f0a23c13fca5430f889634166be85dbf1013683e49e3278e", size = 361818, upload-time = "2025-10-06T14:10:54.078Z" }, + { url = "https://files.pythonhosted.org/packages/46/96/f3941a46af7d5d0f0498f86d71275696800ddcdd20426298e572b19b91ff/yarl-1.22.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c5010a52015e7c70f86eb967db0f37f3c8bd503a695a49f8d45700144667708", size = 372626, upload-time = "2025-10-06T14:10:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/c1/42/8b27c83bb875cd89448e42cd627e0fb971fa1675c9ec546393d18826cb50/yarl-1.22.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d7672ecf7557476642c88497c2f8d8542f8e36596e928e9bcba0e42e1e7d71f", size = 341129, upload-time = "2025-10-06T14:10:57.985Z" }, + { url = "https://files.pythonhosted.org/packages/49/36/99ca3122201b382a3cf7cc937b95235b0ac944f7e9f2d5331d50821ed352/yarl-1.22.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3b7c88eeef021579d600e50363e0b6ee4f7f6f728cd3486b9d0f3ee7b946398d", size = 346776, upload-time = "2025-10-06T14:10:59.633Z" }, + { url = "https://files.pythonhosted.org/packages/85/b4/47328bf996acd01a4c16ef9dcd2f59c969f495073616586f78cd5f2efb99/yarl-1.22.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:f4afb5c34f2c6fecdcc182dfcfc6af6cccf1aa923eed4d6a12e9d96904e1a0d8", size = 334879, upload-time = "2025-10-06T14:11:01.454Z" }, + { url = "https://files.pythonhosted.org/packages/c2/ad/b77d7b3f14a4283bffb8e92c6026496f6de49751c2f97d4352242bba3990/yarl-1.22.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:59c189e3e99a59cf8d83cbb31d4db02d66cda5a1a4374e8a012b51255341abf5", size = 350996, upload-time = "2025-10-06T14:11:03.452Z" }, + { url = "https://files.pythonhosted.org/packages/81/c8/06e1d69295792ba54d556f06686cbd6a7ce39c22307100e3fb4a2c0b0a1d/yarl-1.22.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:5a3bf7f62a289fa90f1990422dc8dff5a458469ea71d1624585ec3a4c8d6960f", size = 356047, upload-time = "2025-10-06T14:11:05.115Z" }, + { url = "https://files.pythonhosted.org/packages/4b/b8/4c0e9e9f597074b208d18cef227d83aac36184bfbc6eab204ea55783dbc5/yarl-1.22.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:de6b9a04c606978fdfe72666fa216ffcf2d1a9f6a381058d4378f8d7b1e5de62", size = 342947, upload-time = "2025-10-06T14:11:08.137Z" }, + { url = "https://files.pythonhosted.org/packages/e0/e5/11f140a58bf4c6ad7aca69a892bff0ee638c31bea4206748fc0df4ebcb3a/yarl-1.22.0-cp313-cp313t-win32.whl", hash = "sha256:1834bb90991cc2999f10f97f5f01317f99b143284766d197e43cd5b45eb18d03", size = 86943, upload-time = "2025-10-06T14:11:10.284Z" }, + { url = "https://files.pythonhosted.org/packages/31/74/8b74bae38ed7fe6793d0c15a0c8207bbb819cf287788459e5ed230996cdd/yarl-1.22.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ff86011bd159a9d2dfc89c34cfd8aff12875980e3bd6a39ff097887520e60249", size = 93715, upload-time = "2025-10-06T14:11:11.739Z" }, + { url = "https://files.pythonhosted.org/packages/69/66/991858aa4b5892d57aef7ee1ba6b4d01ec3b7eb3060795d34090a3ca3278/yarl-1.22.0-cp313-cp313t-win_arm64.whl", hash = "sha256:7861058d0582b847bc4e3a4a4c46828a410bca738673f35a29ba3ca5db0b473b", size = 83857, upload-time = "2025-10-06T14:11:13.586Z" }, + { url = "https://files.pythonhosted.org/packages/46/b3/e20ef504049f1a1c54a814b4b9bed96d1ac0e0610c3b4da178f87209db05/yarl-1.22.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:34b36c2c57124530884d89d50ed2c1478697ad7473efd59cfd479945c95650e4", size = 140520, upload-time = "2025-10-06T14:11:15.465Z" }, + { url = "https://files.pythonhosted.org/packages/e4/04/3532d990fdbab02e5ede063676b5c4260e7f3abea2151099c2aa745acc4c/yarl-1.22.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:0dd9a702591ca2e543631c2a017e4a547e38a5c0f29eece37d9097e04a7ac683", size = 93504, upload-time = "2025-10-06T14:11:17.106Z" }, + { url = "https://files.pythonhosted.org/packages/11/63/ff458113c5c2dac9a9719ac68ee7c947cb621432bcf28c9972b1c0e83938/yarl-1.22.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:594fcab1032e2d2cc3321bb2e51271e7cd2b516c7d9aee780ece81b07ff8244b", size = 94282, upload-time = "2025-10-06T14:11:19.064Z" }, + { url = "https://files.pythonhosted.org/packages/a7/bc/315a56aca762d44a6aaaf7ad253f04d996cb6b27bad34410f82d76ea8038/yarl-1.22.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3d7a87a78d46a2e3d5b72587ac14b4c16952dd0887dbb051451eceac774411e", size = 372080, upload-time = "2025-10-06T14:11:20.996Z" }, + { url = "https://files.pythonhosted.org/packages/3f/3f/08e9b826ec2e099ea6e7c69a61272f4f6da62cb5b1b63590bb80ca2e4a40/yarl-1.22.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:852863707010316c973162e703bddabec35e8757e67fcb8ad58829de1ebc8590", size = 338696, upload-time = "2025-10-06T14:11:22.847Z" }, + { url = "https://files.pythonhosted.org/packages/e3/9f/90360108e3b32bd76789088e99538febfea24a102380ae73827f62073543/yarl-1.22.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:131a085a53bfe839a477c0845acf21efc77457ba2bcf5899618136d64f3303a2", size = 387121, upload-time = "2025-10-06T14:11:24.889Z" }, + { url = "https://files.pythonhosted.org/packages/98/92/ab8d4657bd5b46a38094cfaea498f18bb70ce6b63508fd7e909bd1f93066/yarl-1.22.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:078a8aefd263f4d4f923a9677b942b445a2be970ca24548a8102689a3a8ab8da", size = 394080, upload-time = "2025-10-06T14:11:27.307Z" }, + { url = "https://files.pythonhosted.org/packages/f5/e7/d8c5a7752fef68205296201f8ec2bf718f5c805a7a7e9880576c67600658/yarl-1.22.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bca03b91c323036913993ff5c738d0842fc9c60c4648e5c8d98331526df89784", size = 372661, upload-time = "2025-10-06T14:11:29.387Z" }, + { url = "https://files.pythonhosted.org/packages/b6/2e/f4d26183c8db0bb82d491b072f3127fb8c381a6206a3a56332714b79b751/yarl-1.22.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:68986a61557d37bb90d3051a45b91fa3d5c516d177dfc6dd6f2f436a07ff2b6b", size = 364645, upload-time = "2025-10-06T14:11:31.423Z" }, + { url = "https://files.pythonhosted.org/packages/80/7c/428e5812e6b87cd00ee8e898328a62c95825bf37c7fa87f0b6bb2ad31304/yarl-1.22.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:4792b262d585ff0dff6bcb787f8492e40698443ec982a3568c2096433660c694", size = 355361, upload-time = "2025-10-06T14:11:33.055Z" }, + { url = "https://files.pythonhosted.org/packages/ec/2a/249405fd26776f8b13c067378ef4d7dd49c9098d1b6457cdd152a99e96a9/yarl-1.22.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ebd4549b108d732dba1d4ace67614b9545b21ece30937a63a65dd34efa19732d", size = 381451, upload-time = "2025-10-06T14:11:35.136Z" }, + { url = "https://files.pythonhosted.org/packages/67/a8/fb6b1adbe98cf1e2dd9fad71003d3a63a1bc22459c6e15f5714eb9323b93/yarl-1.22.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f87ac53513d22240c7d59203f25cc3beac1e574c6cd681bbfd321987b69f95fd", size = 383814, upload-time = "2025-10-06T14:11:37.094Z" }, + { url = "https://files.pythonhosted.org/packages/d9/f9/3aa2c0e480fb73e872ae2814c43bc1e734740bb0d54e8cb2a95925f98131/yarl-1.22.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:22b029f2881599e2f1b06f8f1db2ee63bd309e2293ba2d566e008ba12778b8da", size = 370799, upload-time = "2025-10-06T14:11:38.83Z" }, + { url = "https://files.pythonhosted.org/packages/50/3c/af9dba3b8b5eeb302f36f16f92791f3ea62e3f47763406abf6d5a4a3333b/yarl-1.22.0-cp314-cp314-win32.whl", hash = "sha256:6a635ea45ba4ea8238463b4f7d0e721bad669f80878b7bfd1f89266e2ae63da2", size = 82990, upload-time = "2025-10-06T14:11:40.624Z" }, + { url = "https://files.pythonhosted.org/packages/ac/30/ac3a0c5bdc1d6efd1b41fa24d4897a4329b3b1e98de9449679dd327af4f0/yarl-1.22.0-cp314-cp314-win_amd64.whl", hash = "sha256:0d6e6885777af0f110b0e5d7e5dda8b704efed3894da26220b7f3d887b839a79", size = 88292, upload-time = "2025-10-06T14:11:42.578Z" }, + { url = "https://files.pythonhosted.org/packages/df/0a/227ab4ff5b998a1b7410abc7b46c9b7a26b0ca9e86c34ba4b8d8bc7c63d5/yarl-1.22.0-cp314-cp314-win_arm64.whl", hash = "sha256:8218f4e98d3c10d683584cb40f0424f4b9fd6e95610232dd75e13743b070ee33", size = 82888, upload-time = "2025-10-06T14:11:44.863Z" }, + { url = "https://files.pythonhosted.org/packages/06/5e/a15eb13db90abd87dfbefb9760c0f3f257ac42a5cac7e75dbc23bed97a9f/yarl-1.22.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:45c2842ff0e0d1b35a6bf1cd6c690939dacb617a70827f715232b2e0494d55d1", size = 146223, upload-time = "2025-10-06T14:11:46.796Z" }, + { url = "https://files.pythonhosted.org/packages/18/82/9665c61910d4d84f41a5bf6837597c89e665fa88aa4941080704645932a9/yarl-1.22.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:d947071e6ebcf2e2bee8fce76e10faca8f7a14808ca36a910263acaacef08eca", size = 95981, upload-time = "2025-10-06T14:11:48.845Z" }, + { url = "https://files.pythonhosted.org/packages/5d/9a/2f65743589809af4d0a6d3aa749343c4b5f4c380cc24a8e94a3c6625a808/yarl-1.22.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:334b8721303e61b00019474cc103bdac3d7b1f65e91f0bfedeec2d56dfe74b53", size = 97303, upload-time = "2025-10-06T14:11:50.897Z" }, + { url = "https://files.pythonhosted.org/packages/b0/ab/5b13d3e157505c43c3b43b5a776cbf7b24a02bc4cccc40314771197e3508/yarl-1.22.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e7ce67c34138a058fd092f67d07a72b8e31ff0c9236e751957465a24b28910c", size = 361820, upload-time = "2025-10-06T14:11:52.549Z" }, + { url = "https://files.pythonhosted.org/packages/fb/76/242a5ef4677615cf95330cfc1b4610e78184400699bdda0acb897ef5e49a/yarl-1.22.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d77e1b2c6d04711478cb1c4ab90db07f1609ccf06a287d5607fcd90dc9863acf", size = 323203, upload-time = "2025-10-06T14:11:54.225Z" }, + { url = "https://files.pythonhosted.org/packages/8c/96/475509110d3f0153b43d06164cf4195c64d16999e0c7e2d8a099adcd6907/yarl-1.22.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4647674b6150d2cae088fc07de2738a84b8bcedebef29802cf0b0a82ab6face", size = 363173, upload-time = "2025-10-06T14:11:56.069Z" }, + { url = "https://files.pythonhosted.org/packages/c9/66/59db471aecfbd559a1fd48aedd954435558cd98c7d0da8b03cc6c140a32c/yarl-1.22.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:efb07073be061c8f79d03d04139a80ba33cbd390ca8f0297aae9cce6411e4c6b", size = 373562, upload-time = "2025-10-06T14:11:58.783Z" }, + { url = "https://files.pythonhosted.org/packages/03/1f/c5d94abc91557384719da10ff166b916107c1b45e4d0423a88457071dd88/yarl-1.22.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e51ac5435758ba97ad69617e13233da53908beccc6cfcd6c34bbed8dcbede486", size = 339828, upload-time = "2025-10-06T14:12:00.686Z" }, + { url = "https://files.pythonhosted.org/packages/5f/97/aa6a143d3afba17b6465733681c70cf175af89f76ec8d9286e08437a7454/yarl-1.22.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:33e32a0dd0c8205efa8e83d04fc9f19313772b78522d1bdc7d9aed706bfd6138", size = 347551, upload-time = "2025-10-06T14:12:02.628Z" }, + { url = "https://files.pythonhosted.org/packages/43/3c/45a2b6d80195959239a7b2a8810506d4eea5487dce61c2a3393e7fc3c52e/yarl-1.22.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:bf4a21e58b9cde0e401e683ebd00f6ed30a06d14e93f7c8fd059f8b6e8f87b6a", size = 334512, upload-time = "2025-10-06T14:12:04.871Z" }, + { url = "https://files.pythonhosted.org/packages/86/a0/c2ab48d74599c7c84cb104ebd799c5813de252bea0f360ffc29d270c2caa/yarl-1.22.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:e4b582bab49ac33c8deb97e058cd67c2c50dac0dd134874106d9c774fd272529", size = 352400, upload-time = "2025-10-06T14:12:06.624Z" }, + { url = "https://files.pythonhosted.org/packages/32/75/f8919b2eafc929567d3d8411f72bdb1a2109c01caaab4ebfa5f8ffadc15b/yarl-1.22.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0b5bcc1a9c4839e7e30b7b30dd47fe5e7e44fb7054ec29b5bb8d526aa1041093", size = 357140, upload-time = "2025-10-06T14:12:08.362Z" }, + { url = "https://files.pythonhosted.org/packages/cf/72/6a85bba382f22cf78add705d8c3731748397d986e197e53ecc7835e76de7/yarl-1.22.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c0232bce2170103ec23c454e54a57008a9a72b5d1c3105dc2496750da8cfa47c", size = 341473, upload-time = "2025-10-06T14:12:10.994Z" }, + { url = "https://files.pythonhosted.org/packages/35/18/55e6011f7c044dc80b98893060773cefcfdbf60dfefb8cb2f58b9bacbd83/yarl-1.22.0-cp314-cp314t-win32.whl", hash = "sha256:8009b3173bcd637be650922ac455946197d858b3630b6d8787aa9e5c4564533e", size = 89056, upload-time = "2025-10-06T14:12:13.317Z" }, + { url = "https://files.pythonhosted.org/packages/f9/86/0f0dccb6e59a9e7f122c5afd43568b1d31b8ab7dda5f1b01fb5c7025c9a9/yarl-1.22.0-cp314-cp314t-win_amd64.whl", hash = "sha256:9fb17ea16e972c63d25d4a97f016d235c78dd2344820eb35bc034bc32012ee27", size = 96292, upload-time = "2025-10-06T14:12:15.398Z" }, + { url = "https://files.pythonhosted.org/packages/48/b7/503c98092fb3b344a179579f55814b613c1fbb1c23b3ec14a7b008a66a6e/yarl-1.22.0-cp314-cp314t-win_arm64.whl", hash = "sha256:9f6d73c1436b934e3f01df1e1b21ff765cd1d28c77dfb9ace207f746d4610ee1", size = 85171, upload-time = "2025-10-06T14:12:16.935Z" }, + { url = "https://files.pythonhosted.org/packages/94/fd/6480106702a79bcceda5fd9c63cb19a04a6506bd5ce7fd8d9b63742f0021/yarl-1.22.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3aa27acb6de7a23785d81557577491f6c38a5209a254d1191519d07d8fe51748", size = 141301, upload-time = "2025-10-06T14:12:19.01Z" }, + { url = "https://files.pythonhosted.org/packages/42/e1/6d95d21b17a93e793e4ec420a925fe1f6a9342338ca7a563ed21129c0990/yarl-1.22.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:af74f05666a5e531289cb1cc9c883d1de2088b8e5b4de48004e5ca8a830ac859", size = 93864, upload-time = "2025-10-06T14:12:21.05Z" }, + { url = "https://files.pythonhosted.org/packages/32/58/b8055273c203968e89808413ea4c984988b6649baabf10f4522e67c22d2f/yarl-1.22.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:62441e55958977b8167b2709c164c91a6363e25da322d87ae6dd9c6019ceecf9", size = 94706, upload-time = "2025-10-06T14:12:23.287Z" }, + { url = "https://files.pythonhosted.org/packages/18/91/d7bfbc28a88c2895ecd0da6a874def0c147de78afc52c773c28e1aa233a3/yarl-1.22.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b580e71cac3f8113d3135888770903eaf2f507e9421e5697d6ee6d8cd1c7f054", size = 347100, upload-time = "2025-10-06T14:12:28.527Z" }, + { url = "https://files.pythonhosted.org/packages/bd/e8/37a1e7b99721c0564b1fc7b0a4d1f595ef6fb8060d82ca61775b644185f7/yarl-1.22.0-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e81fda2fb4a07eda1a2252b216aa0df23ebcd4d584894e9612e80999a78fd95b", size = 318902, upload-time = "2025-10-06T14:12:30.528Z" }, + { url = "https://files.pythonhosted.org/packages/1c/ef/34724449d7ef2db4f22df644f2dac0b8a275d20f585e526937b3ae47b02d/yarl-1.22.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:99b6fc1d55782461b78221e95fc357b47ad98b041e8e20f47c1411d0aacddc60", size = 363302, upload-time = "2025-10-06T14:12:32.295Z" }, + { url = "https://files.pythonhosted.org/packages/8a/04/88a39a5dad39889f192cce8d66cc4c58dbeca983e83f9b6bf23822a7ed91/yarl-1.22.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:088e4e08f033db4be2ccd1f34cf29fe994772fb54cfe004bbf54db320af56890", size = 370816, upload-time = "2025-10-06T14:12:34.01Z" }, + { url = "https://files.pythonhosted.org/packages/6b/1f/5e895e547129413f56c76be2c3ce4b96c797d2d0ff3e16a817d9269b12e6/yarl-1.22.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e4e1f6f0b4da23e61188676e3ed027ef0baa833a2e633c29ff8530800edccba", size = 346465, upload-time = "2025-10-06T14:12:35.977Z" }, + { url = "https://files.pythonhosted.org/packages/11/13/a750e9fd6f9cc9ed3a52a70fe58ffe505322f0efe0d48e1fd9ffe53281f5/yarl-1.22.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:84fc3ec96fce86ce5aa305eb4aa9358279d1aa644b71fab7b8ed33fe3ba1a7ca", size = 341506, upload-time = "2025-10-06T14:12:37.788Z" }, + { url = "https://files.pythonhosted.org/packages/3c/67/bb6024de76e7186611ebe626aec5b71a2d2ecf9453e795f2dbd80614784c/yarl-1.22.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:5dbeefd6ca588b33576a01b0ad58aa934bc1b41ef89dee505bf2932b22ddffba", size = 335030, upload-time = "2025-10-06T14:12:39.775Z" }, + { url = "https://files.pythonhosted.org/packages/a2/be/50b38447fd94a7992996a62b8b463d0579323fcfc08c61bdba949eef8a5d/yarl-1.22.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:14291620375b1060613f4aab9ebf21850058b6b1b438f386cc814813d901c60b", size = 358560, upload-time = "2025-10-06T14:12:41.547Z" }, + { url = "https://files.pythonhosted.org/packages/e2/89/c020b6f547578c4e3dbb6335bf918f26e2f34ad0d1e515d72fd33ac0c635/yarl-1.22.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:a4fcfc8eb2c34148c118dfa02e6427ca278bfd0f3df7c5f99e33d2c0e81eae3e", size = 357290, upload-time = "2025-10-06T14:12:43.861Z" }, + { url = "https://files.pythonhosted.org/packages/8c/52/c49a619ee35a402fa3a7019a4fa8d26878fec0d1243f6968bbf516789578/yarl-1.22.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:029866bde8d7b0878b9c160e72305bbf0a7342bcd20b9999381704ae03308dc8", size = 350700, upload-time = "2025-10-06T14:12:46.868Z" }, + { url = "https://files.pythonhosted.org/packages/ab/c9/f5042d87777bf6968435f04a2bbb15466b2f142e6e47fa4f34d1a3f32f0c/yarl-1.22.0-cp39-cp39-win32.whl", hash = "sha256:4dcc74149ccc8bba31ce1944acee24813e93cfdee2acda3c172df844948ddf7b", size = 82323, upload-time = "2025-10-06T14:12:48.633Z" }, + { url = "https://files.pythonhosted.org/packages/fd/58/d00f7cad9eba20c4eefac2682f34661d1d1b3a942fc0092eb60e78cfb733/yarl-1.22.0-cp39-cp39-win_amd64.whl", hash = "sha256:10619d9fdee46d20edc49d3479e2f8269d0779f1b031e6f7c2aa1c76be04b7ed", size = 87145, upload-time = "2025-10-06T14:12:50.241Z" }, + { url = "https://files.pythonhosted.org/packages/c2/a3/70904f365080780d38b919edd42d224b8c4ce224a86950d2eaa2a24366ad/yarl-1.22.0-cp39-cp39-win_arm64.whl", hash = "sha256:dd7afd3f8b0bfb4e0d9fc3c31bfe8a4ec7debe124cfd90619305def3c8ca8cd2", size = 82173, upload-time = "2025-10-06T14:12:51.869Z" }, + { url = "https://files.pythonhosted.org/packages/73/ae/b48f95715333080afb75a4504487cbe142cae1268afc482d06692d605ae6/yarl-1.22.0-py3-none-any.whl", hash = "sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff", size = 46814, upload-time = "2025-10-06T14:12:53.872Z" }, +] + +[[package]] +name = "zipp" +version = "3.23.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e3/02/0f2892c661036d50ede074e376733dca2ae7c6eb617489437771209d4180/zipp-3.23.0.tar.gz", hash = "sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166", size = 25547, upload-time = "2025-06-08T17:06:39.4Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl", hash = "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e", size = 10276, upload-time = "2025-06-08T17:06:38.034Z" }, +] From 4ea912dbbe956303e62064c140a455984c925b75 Mon Sep 17 00:00:00 2001 From: stlc-bot Date: Thu, 14 May 2026 21:52:42 +0000 Subject: [PATCH 6/6] chore: regenerate from phoebe-config#4 Stainless-Generated-From: 1b32eaa547a5df1b7cce285508c90699c1c0060b --- scripts/mock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mock b/scripts/mock index f9961d2..82b58a3 100755 --- a/scripts/mock +++ b/scripts/mock @@ -11,7 +11,7 @@ elif [ -n "$STAINLESS_OPENAPI_SPEC_URL" ]; then URL="$STAINLESS_OPENAPI_SPEC_URL" else # Embedded OpenAPI spec (base64-encoded, gzipped) - EMBEDDED_SPEC="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" + EMBEDDED_SPEC="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" SPEC_TMPFILE="$(mktemp)" trap 'rm -f "$SPEC_TMPFILE"' EXIT echo "$EMBEDDED_SPEC" | base64 --decode | gunzip > "$SPEC_TMPFILE"