pax_global_header00006660000000000000000000000064150665345450014527gustar00rootroot0000000000000052 comment=1f233dfdeee145af6f86039b3cd6f9c89b49efd9 anthropic-sdk-python-0.69.0/000077500000000000000000000000001506653454500157105ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/.devcontainer/000077500000000000000000000000001506653454500204475ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/.devcontainer/Dockerfile000066400000000000000000000003751506653454500224460ustar00rootroot00000000000000ARG VARIANT="3.9" FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT} USER vscode 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 anthropic-sdk-python-0.69.0/.devcontainer/devcontainer.json000066400000000000000000000023011506653454500240170ustar00rootroot00000000000000// For format details, see https://aka.ms/devcontainer.json. For config options, see the // README at: https://github.com/devcontainers/templates/tree/main/src/debian { "name": "Debian", "build": { "dockerfile": "Dockerfile", "context": ".." }, "postStartCommand": "uv sync --all-extras", "customizations": { "vscode": { "extensions": [ "ms-python.python" ], "settings": { "terminal.integrated.shell.linux": "/bin/bash", "python.pythonPath": ".venv/bin/python", "python.defaultInterpreterPath": ".venv/bin/python", "python.typeChecking": "basic", "terminal.integrated.env.linux": { "PATH": "${env:PATH}" } } } }, "features": { "ghcr.io/devcontainers/features/node:1": {} } // Features to add to the dev container. More info: https://containers.dev/features. // "features": {}, // Use 'forwardPorts' to make a list of ports inside the container available locally. // "forwardPorts": [], // Configure tool-specific properties. // "customizations": {}, // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. // "remoteUser": "root" } anthropic-sdk-python-0.69.0/.github/000077500000000000000000000000001506653454500172505ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/.github/CODEOWNERS000066400000000000000000000003141506653454500206410ustar00rootroot00000000000000# This file is used to automatically assign reviewers to PRs # For more information see: https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners * @anthropics/sdk anthropic-sdk-python-0.69.0/.github/workflows/000077500000000000000000000000001506653454500213055ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/.github/workflows/ci.yml000066400000000000000000000045641506653454500224340ustar00rootroot00000000000000name: CI on: push: branches-ignore: - 'generated' - 'codegen/**' - 'integrated/**' - 'stl-preview-head/**' - 'stl-preview-base/**' pull_request: branches-ignore: - 'stl-preview-head/**' - 'stl-preview-base/**' jobs: lint: timeout-minutes: 10 name: lint runs-on: ${{ github.repository == 'stainless-sdks/anthropic-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 uv uses: astral-sh/setup-uv@v5 with: version: '0.8.11' - name: Install dependencies run: uv sync --all-extras - name: Run lints run: ./scripts/lint build: if: github.event_name == 'push' || github.event.pull_request.head.repo.fork timeout-minutes: 10 name: build permissions: contents: read id-token: write runs-on: ${{ github.repository == 'stainless-sdks/anthropic-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} steps: - uses: actions/checkout@v4 - name: Install uv uses: astral-sh/setup-uv@v5 with: version: '0.8.11' - name: Install dependencies run: uv sync --all-extras - name: Run build run: uv build - name: Get GitHub OIDC Token if: github.repository == 'stainless-sdks/anthropic-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/anthropic-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/anthropic-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 uv uses: astral-sh/setup-uv@v5 with: version: '0.8.11' - name: Bootstrap run: ./scripts/bootstrap - name: Run tests run: ./scripts/test anthropic-sdk-python-0.69.0/.github/workflows/create-releases.yml000066400000000000000000000017041506653454500250760ustar00rootroot00000000000000name: Create releases on: schedule: - cron: '0 5 * * *' # every day at 5am UTC push: branches: - main jobs: release: name: release if: github.ref == 'refs/heads/main' && github.repository == 'anthropics/anthropic-sdk-python' runs-on: ubuntu-latest environment: production-release steps: - uses: actions/checkout@v4 - uses: stainless-api/trigger-release-please@v1 id: release with: repo: ${{ github.event.repository.full_name }} stainless-api-key: ${{ secrets.STAINLESS_API_KEY }} - name: Install uv if: ${{ steps.release.outputs.releases_created }} uses: astral-sh/setup-uv@v5 with: version: '0.8.11' - name: Publish to PyPI if: ${{ steps.release.outputs.releases_created }} run: | bash ./bin/publish-pypi env: PYPI_TOKEN: ${{ secrets.ANTHROPIC_PYPI_TOKEN || secrets.PYPI_TOKEN }} anthropic-sdk-python-0.69.0/.github/workflows/detect-breaking-changes.yml000066400000000000000000000025071506653454500264720ustar00rootroot00000000000000name: CI on: pull_request: branches: - main - next jobs: detect_breaking_changes: runs-on: 'ubuntu-latest' name: detect-breaking-changes if: github.repository == 'anthropics/anthropic-sdk-python' steps: - name: Calculate fetch-depth run: | echo "FETCH_DEPTH=$(expr ${{ github.event.pull_request.commits }} + 1)" >> $GITHUB_ENV - uses: actions/checkout@v4 with: # Ensure we can check out the pull request base in the script below. fetch-depth: ${{ env.FETCH_DEPTH }} - name: Install uv uses: astral-sh/setup-uv@v5 with: version: '0.8.11' - name: Install dependencies run: uv sync --all-extras - name: Detect removed symbols run: | uv run python scripts/detect-breaking-changes.py "${{ github.event.pull_request.base.sha }}" - name: Detect breaking changes run: | # Try to check out previous versions of the breaking change detection script. This ensures that # we still detect breaking changes when entire files and their tests are removed. git checkout "${{ github.event.pull_request.base.sha }}" -- ./scripts/detect-breaking-changes 2>/dev/null || true ./scripts/detect-breaking-changes ${{ github.event.pull_request.base.sha }}anthropic-sdk-python-0.69.0/.github/workflows/publish-pypi.yml000066400000000000000000000012471506653454500244610ustar00rootroot00000000000000# 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/anthropics/anthropic-sdk-python/actions/workflows/publish-pypi.yml name: Publish PyPI on: workflow_dispatch: jobs: publish: name: publish runs-on: ubuntu-latest environment: production-release steps: - uses: actions/checkout@v4 - name: Install uv uses: astral-sh/setup-uv@v5 with: version: '0.8.11' - name: Publish to PyPI run: | bash ./bin/publish-pypi env: PYPI_TOKEN: ${{ secrets.ANTHROPIC_PYPI_TOKEN || secrets.PYPI_TOKEN }} anthropic-sdk-python-0.69.0/.github/workflows/release-doctor.yml000066400000000000000000000013141506653454500247370ustar00rootroot00000000000000name: Release Doctor on: push: branches: - main workflow_dispatch: jobs: release_doctor: name: release doctor runs-on: ubuntu-latest environment: production-release if: github.repository == 'anthropics/anthropic-sdk-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 - name: Check release environment run: | bash ./bin/check-release-environment env: STAINLESS_API_KEY: ${{ secrets.STAINLESS_API_KEY }} PYPI_TOKEN: ${{ secrets.ANTHROPIC_PYPI_TOKEN || secrets.PYPI_TOKEN }} anthropic-sdk-python-0.69.0/.gitignore000066400000000000000000000001501506653454500176740ustar00rootroot00000000000000.prism.log _dev __pycache__ .mypy_cache dist .venv .idea .env .envrc codegen.log Brewfile.lock.json anthropic-sdk-python-0.69.0/.python-version000066400000000000000000000000071506653454500207120ustar00rootroot000000000000003.9.18 anthropic-sdk-python-0.69.0/.release-please-manifest.json000066400000000000000000000000231506653454500233470ustar00rootroot00000000000000{ ".": "0.69.0" }anthropic-sdk-python-0.69.0/.stats.yml000066400000000000000000000004431506653454500176500ustar00rootroot00000000000000configured_endpoints: 26 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic%2Fanthropic-9c7d1ea59095c76b24f14fe279825c2b0dc10f165a973a46b8a548af9aeda62e.yml openapi_spec_hash: 592d90505082223899e0638ad56ba162 config_hash: e0f97b085ca213c87341488cb257ed57 anthropic-sdk-python-0.69.0/.vscode/000077500000000000000000000000001506653454500172515ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/.vscode/settings.json000066400000000000000000000000641506653454500220040ustar00rootroot00000000000000{ "python.analysis.importFormat": "relative", } anthropic-sdk-python-0.69.0/Brewfile000066400000000000000000000000131506653454500173640ustar00rootroot00000000000000brew "uv" anthropic-sdk-python-0.69.0/CHANGELOG.md000066400000000000000000004770761506653454500175460ustar00rootroot00000000000000# Changelog ## 0.69.0 (2025-09-29) Full Changelog: [v0.68.2...v0.69.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.68.2...v0.69.0) ### Features * **api:** adds support for Claude Sonnet 4.5 and context management features ([f93eb12](https://github.com/anthropics/anthropic-sdk-python/commit/f93eb12dbfeaa68fb24590391ec72243836eb47a)) ## 0.68.2 (2025-09-29) Full Changelog: [v0.68.1...v0.68.2](https://github.com/anthropics/anthropic-sdk-python/compare/v0.68.1...v0.68.2) ### Bug Fixes * do not set headers with default to omit ([95b14ab](https://github.com/anthropics/anthropic-sdk-python/commit/95b14ab8fa8b63b95cb82cad1347915c163818d2)) ## 0.68.1 (2025-09-26) Full Changelog: [v0.68.0...v0.68.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.68.0...v0.68.1) ### Chores * **deps:** move deprecated `dev-dependencies` in `pyproject.toml` to dev group ([df16b88](https://github.com/anthropics/anthropic-sdk-python/commit/df16b88ade25f91c0b2c88d4ae256c861e4db170)) * do not install brew dependencies in ./scripts/bootstrap by default ([a457673](https://github.com/anthropics/anthropic-sdk-python/commit/a45767347f27258290c572ee5dc3e44c4f314f4b)) * rename tool runner helper header ([a9ed3f9](https://github.com/anthropics/anthropic-sdk-python/commit/a9ed3f9c80dc1acbf7f487fc6cc3586f690ccd2d)) * **types:** change optional parameter type from NotGiven to Omit ([9f0a11f](https://github.com/anthropics/anthropic-sdk-python/commit/9f0a11fa6168e5d59f8a5820de5dbe7d5c2137bd)) * update more NotGiven usage sites ([72ab661](https://github.com/anthropics/anthropic-sdk-python/commit/72ab661827ead771923d229bd142f3b9c1a234e8)) ## 0.68.0 (2025-09-17) Full Changelog: [v0.67.0...v0.68.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.67.0...v0.68.0) ### Features * add tool running helpers ([d9c9ce6](https://github.com/anthropics/anthropic-sdk-python/commit/d9c9ce63de5b5888dff0d9ba2d79724520152420)) ### Chores * **internal:** fix tests ([9858c79](https://github.com/anthropics/anthropic-sdk-python/commit/9858c791309a1af2fbc2cb4d042812de83d1a635)) * **internal:** update pydantic dependency ([f59c2f1](https://github.com/anthropics/anthropic-sdk-python/commit/f59c2f196a09c80f6b46cac19e9d0ace18200da8)) * **tests:** simplify `get_platform` test ([7596748](https://github.com/anthropics/anthropic-sdk-python/commit/7596748699ff3113b6cb6c1511cf4a33d0453233)) ## 0.67.0 (2025-09-10) Full Changelog: [v0.66.0...v0.67.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.66.0...v0.67.0) ### Features * **api:** adds support for web_fetch_20250910 tool ([f85b6a1](https://github.com/anthropics/anthropic-sdk-python/commit/f85b6a172b4b6d3b42119d75f0fefbbf7dcd2351)) * improve future compat with pydantic v3 ([39f28c5](https://github.com/anthropics/anthropic-sdk-python/commit/39f28c51d328bc7bf5f86f252ea63e8325815c72)) ### Bug Fixes * more updates for future pydantic v3 compat ([7967d15](https://github.com/anthropics/anthropic-sdk-python/commit/7967d1501297e188f451fa39a33b38317dfcb883)) * **types/beta:** add response content block type to params ([#1030](https://github.com/anthropics/anthropic-sdk-python/issues/1030)) ([9febe38](https://github.com/anthropics/anthropic-sdk-python/commit/9febe38a309d290f2c2a8d96eb458972652b98cd)) ### Chores * **internal:** move mypy configurations to `pyproject.toml` file ([c5347b6](https://github.com/anthropics/anthropic-sdk-python/commit/c5347b6affba397276c13e763f5eb820d11f912f)) * update SDK settings ([36e6870](https://github.com/anthropics/anthropic-sdk-python/commit/36e687098acc8c66613712c89667edea73ce799f)) ## 0.66.0 (2025-09-03) Full Changelog: [v0.65.0...v0.66.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.65.0...v0.66.0) ### Features * **api:** adds support for Documents in tool results ([5309dad](https://github.com/anthropics/anthropic-sdk-python/commit/5309dad584bb31284516e0d44681f1b46d1a663d)) ## 0.65.0 (2025-09-02) Full Changelog: [v0.64.0...v0.65.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.64.0...v0.65.0) ### Features * **client:** adds support for code-execution-2025-08-26 tool ([fe92af0](https://github.com/anthropics/anthropic-sdk-python/commit/fe92af02a2fa2d1bc626bb238ee54886bc701829)) * **types:** replace List[str] with SequenceNotStr in params ([f542b54](https://github.com/anthropics/anthropic-sdk-python/commit/f542b541ba1e70b65704e9b96a87733cb1d9d77f)) ### Bug Fixes * avoid newer type syntax ([c6d1cf5](https://github.com/anthropics/anthropic-sdk-python/commit/c6d1cf5895f15d5fc526af9a34a6b53a514bf28e)) * **client:** remove unused import ([712c6d8](https://github.com/anthropics/anthropic-sdk-python/commit/712c6d8b1c47eb663d2fc06b97b8c0630d4579cf)) ### Chores * **client:** sync SequenceNotStr over to custom stream methods ([dd16483](https://github.com/anthropics/anthropic-sdk-python/commit/dd16483da5900a9c02519617d52d951f429d4685)) * **internal:** add Sequence related utils ([d523f29](https://github.com/anthropics/anthropic-sdk-python/commit/d523f295541c23de43d3b51512327265d243ac35)) * **internal:** bump uv version ([aab5bc6](https://github.com/anthropics/anthropic-sdk-python/commit/aab5bc667e5aa1144dc45650cd4c6a63f1be6051)) * **internal:** change ci workflow machines ([5383431](https://github.com/anthropics/anthropic-sdk-python/commit/5383431a31c7368c45f7cc42b358798a2f2c8a7f)) * **internal:** codegen related update ([eb8b19f](https://github.com/anthropics/anthropic-sdk-python/commit/eb8b19f5d7e6e4af3cfbf4cc6f02a9e5ce50f1b8)) * **internal:** improve breaking change detection ([6c8afa9](https://github.com/anthropics/anthropic-sdk-python/commit/6c8afa9c9fb667d824d0630de22c1662e85d7bd3)) * **internal:** refactor pydantic v1 test setup ([cb5444b](https://github.com/anthropics/anthropic-sdk-python/commit/cb5444be33dd798748fc5d0709ce1d47d5d4c012)) * **internal:** run tests in an isolated environment ([9adb089](https://github.com/anthropics/anthropic-sdk-python/commit/9adb089e2fb0d67b23b389128e2375a134564ef5)) * **internal:** update pyright exclude list ([85961ef](https://github.com/anthropics/anthropic-sdk-python/commit/85961ef1d4cec5243c2e74160df65aef3090a59a)) * update github action ([1e6a135](https://github.com/anthropics/anthropic-sdk-python/commit/1e6a1353d045b26cea766fc6bcf7331159522fa5)) ## 0.64.0 (2025-08-13) Full Changelog: [v0.63.0...v0.64.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.63.0...v0.64.0) ### Features * **api:** makes 1 hour TTL Cache Control generally available ([35201ba](https://github.com/anthropics/anthropic-sdk-python/commit/35201baef190c354a803278aa926490ff6069abf)) ### Chores * deprecate older claude-3-5 sonnet models ([#1116](https://github.com/anthropics/anthropic-sdk-python/issues/1116)) ([3e8e10d](https://github.com/anthropics/anthropic-sdk-python/commit/3e8e10dc706e4fb272db78aec4c7678f842c54af)) ## 0.63.0 (2025-08-12) Full Changelog: [v0.62.0...v0.63.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.62.0...v0.63.0) ### Features * **betas:** add context-1m-2025-08-07 ([57a80e7](https://github.com/anthropics/anthropic-sdk-python/commit/57a80e7a2cf6813db6633516dbb5bb65a6e85122)) ### Chores * **internal:** detect breaking changes when removing endpoints ([5c62d7b](https://github.com/anthropics/anthropic-sdk-python/commit/5c62d7bdaf8a180dcb6bc30c17a6bdf13d976ab2)) * **internal:** update comment in script ([9e9d69c](https://github.com/anthropics/anthropic-sdk-python/commit/9e9d69cdd98a838adac734a0748e1f52ccd4faa4)) * **internal:** update test skipping reason ([b18a3d5](https://github.com/anthropics/anthropic-sdk-python/commit/b18a3d55a8f75ba3257ec83283d31bcb82548713)) * update @stainless-api/prism-cli to v5.15.0 ([55cb0a1](https://github.com/anthropics/anthropic-sdk-python/commit/55cb0a1d1f42f6bcae74c6d1946f927534e30276)) ## 0.62.0 (2025-08-08) Full Changelog: [v0.61.0...v0.62.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.61.0...v0.62.0) ### Features * **api:** search result content blocks ([1ae15cd](https://github.com/anthropics/anthropic-sdk-python/commit/1ae15cd58da2c58dfb85276860ec407401c04cc6)) ## 0.61.0 (2025-08-05) Full Changelog: [v0.60.0...v0.61.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.60.0...v0.61.0) ### Features * **api:** add claude-opus-4-1-20250805 ([baae0ee](https://github.com/anthropics/anthropic-sdk-python/commit/baae0ee315d645aaa55b01a9eae0549ea42b7cb5)) * **api:** adds support for text_editor_20250728 tool ([9ad8fe5](https://github.com/anthropics/anthropic-sdk-python/commit/9ad8fe53d6878715e5d423aedba6cc23109e47ea)) * **client:** support file upload requests ([a9bd98a](https://github.com/anthropics/anthropic-sdk-python/commit/a9bd98ab54438528cb8110cf1f4efaa2b20df959)) ### Chores * **client:** add TextEditor_20250429 tool ([ec207c5](https://github.com/anthropics/anthropic-sdk-python/commit/ec207c52d6c15ef7232a3f997aaa6d95fcbef9f3)) * **internal:** codegen related update ([4498057](https://github.com/anthropics/anthropic-sdk-python/commit/44980570bd92204177f069b5653f08dbda3ea018)) * **internal:** fix ruff target version ([3cfa202](https://github.com/anthropics/anthropic-sdk-python/commit/3cfa2023ecee6e8da5e3b71b4391477694d0475e)) ## 0.60.0 (2025-07-28) Full Changelog: [v0.59.0...v0.60.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.59.0...v0.60.0) ### Features * update streaming error message to say 'required' not 'recommended' ([57120c8](https://github.com/anthropics/anthropic-sdk-python/commit/57120c8e0579ca3d3218ce043cc46c82345a925e)) * update streaming error message to say 'required' not 'recommended' ([3b47368](https://github.com/anthropics/anthropic-sdk-python/commit/3b47368ca00a51bc4876066af502b0a21a6b6a60)) ### Bug Fixes * **vertex:** add missing beta methods ([#1004](https://github.com/anthropics/anthropic-sdk-python/issues/1004)) ([f8e9cb4](https://github.com/anthropics/anthropic-sdk-python/commit/f8e9cb40b1832eaa7f319d8b051b258a7320cbd4)) ### Chores * **project:** add settings file for vscode ([1c4a9b1](https://github.com/anthropics/anthropic-sdk-python/commit/1c4a9b17e39e76c7260b44b6b666dbf2450a6d19)) ## 0.59.0 (2025-07-23) Full Changelog: [v0.58.2...v0.59.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.58.2...v0.59.0) ### Features * **api:** removed older deprecated models ([38998fd](https://github.com/anthropics/anthropic-sdk-python/commit/38998fdab79b62349481c9c49579a825a5a33761)) ### Bug Fixes * **parsing:** ignore empty metadata ([7099f32](https://github.com/anthropics/anthropic-sdk-python/commit/7099f32a401b1f2a08b358562e325571a5fce8f6)) * **parsing:** parse extra field types ([dbea8a4](https://github.com/anthropics/anthropic-sdk-python/commit/dbea8a40469c30533e30dc1762bfba83159f090d)) ### Chores * **internal:** version bump ([5defffa](https://github.com/anthropics/anthropic-sdk-python/commit/5defffa3ab4b0299759f2a45ffa3f7a49e8c2ba5)) ## 0.58.2 (2025-07-18) Full Changelog: [v0.58.1...v0.58.2](https://github.com/anthropics/anthropic-sdk-python/compare/v0.58.1...v0.58.2) ### Chores * **internal:** version bump ([cd5d1ad](https://github.com/anthropics/anthropic-sdk-python/commit/cd5d1adc34e488f1c9e3a6d2a46f69e5c168e3f6)) ## 0.58.1 (2025-07-18) Full Changelog: [v0.58.0...v0.58.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.58.0...v0.58.1) ### Chores * **internal:** version bump ([31c3b38](https://github.com/anthropics/anthropic-sdk-python/commit/31c3b380e5ceab20789080c65cef9bd74e318a3e)) ## 0.58.0 (2025-07-18) Full Changelog: [v0.57.1...v0.58.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.57.1...v0.58.0) ### Features * clean up environment call outs ([4f64e9c](https://github.com/anthropics/anthropic-sdk-python/commit/4f64e9c1bdb142bbcff2072baa709afdea348889)) ### Bug Fixes * **client:** don't send Content-Type header on GET requests ([727268f](https://github.com/anthropics/anthropic-sdk-python/commit/727268f2bd4cb42aa1472e1f0c6a92fd6a5cb122)) * **parsing:** correctly handle nested discriminated unions ([44dd47e](https://github.com/anthropics/anthropic-sdk-python/commit/44dd47e15ed91af912eac4791421e11504c3094b)) ### Chores * **internal:** bump pinned h11 dep ([9a947e1](https://github.com/anthropics/anthropic-sdk-python/commit/9a947e1061021529937395758acb4d77b685a68b)) * **internal:** codegen related update ([33f2b34](https://github.com/anthropics/anthropic-sdk-python/commit/33f2b3468a971ca2ce6eb8b823b26d45092303f7)) * **internal:** version bump ([5f0f5ad](https://github.com/anthropics/anthropic-sdk-python/commit/5f0f5adba5392facf8331451c449513ae005a054)) * **package:** mark python 3.13 as supported ([703d557](https://github.com/anthropics/anthropic-sdk-python/commit/703d55747456a3825ba8c79cd492d6e64276dc15)) * **readme:** fix version rendering on pypi ([dd956a6](https://github.com/anthropics/anthropic-sdk-python/commit/dd956a616a45191398aac9061eaaa5f3b7cbf2f6)) ### Documentation * model in examples ([89b6925](https://github.com/anthropics/anthropic-sdk-python/commit/89b69256dcbd107970d0763afc62f2cbf08e3d5a)) * model in examples ([1eccecb](https://github.com/anthropics/anthropic-sdk-python/commit/1eccecbec9e0c0cde748695e0cb1bc61ac8ffca5)) ## 0.57.1 (2025-07-03) Full Changelog: [v0.57.0...v0.57.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.57.0...v0.57.1) ### Chores * **api:** update BetaCitationSearchResultLocation ([e0735b4](https://github.com/anthropics/anthropic-sdk-python/commit/e0735b45216fc97866492bf2fff50ea7bc9768ef)) * **internal:** version bump ([d368831](https://github.com/anthropics/anthropic-sdk-python/commit/d3688311d7b175986cff8e87ccc6e4d3159e43f4)) ## 0.57.0 (2025-07-03) Full Changelog: [v0.56.0...v0.57.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.56.0...v0.57.0) ### Features * **api:** add support for Search Result Content Blocks ([4896178](https://github.com/anthropics/anthropic-sdk-python/commit/4896178d23832e4c84775571e8919c690ff998a1)) ### Bug Fixes * improve timeout/network error message to be more helpful ([347fb57](https://github.com/anthropics/anthropic-sdk-python/commit/347fb57c49129ff1fdac19859eb4c80808ed0711)) ### Chores * **ci:** change upload type ([4dc4178](https://github.com/anthropics/anthropic-sdk-python/commit/4dc4178d0a1eaeafc248deac4e08cc782f778600)) * **internal:** version bump ([363629c](https://github.com/anthropics/anthropic-sdk-python/commit/363629cbc85d1e81d1e503d224dc8c7a3d1fa113)) * **stream:** improve get_final_text() error message ([#979](https://github.com/anthropics/anthropic-sdk-python/issues/979)) ([5ae0a33](https://github.com/anthropics/anthropic-sdk-python/commit/5ae0a3303f8369575d9ebefe5b2c45cc435facdb)) ### Documentation * fix vertex id ([f7392c7](https://github.com/anthropics/anthropic-sdk-python/commit/f7392c7789fc2d329ab63c4d2ed7ba0d1dc0c7c0)) * fix vertex id ([92fe132](https://github.com/anthropics/anthropic-sdk-python/commit/92fe1329a9a8a31de2fe71b40c4fdd84fb033dae)) * update model in readme ([1a4df78](https://github.com/anthropics/anthropic-sdk-python/commit/1a4df783a75589dce9826a5c0564692ed0d7d7fb)) * update models and non-beta ([a54e65c](https://github.com/anthropics/anthropic-sdk-python/commit/a54e65c5bc9dd1ac188ea9c166943548cc6f7c08)) * update more models ([9e3dd6a](https://github.com/anthropics/anthropic-sdk-python/commit/9e3dd6afc565a6777f96ab05a28dcf2b4b9591da)) ## 0.56.0 (2025-07-01) Full Changelog: [v0.55.0...v0.56.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.55.0...v0.56.0) ### Features * **bedrock:** automatically infer AWS Region ([#974](https://github.com/anthropics/anthropic-sdk-python/issues/974)) ([f648e09](https://github.com/anthropics/anthropic-sdk-python/commit/f648e09c43ea227a7a388cbdd21e8ddb762963e4)) * **vertex:** support global region endpoint ([1fd1adf](https://github.com/anthropics/anthropic-sdk-python/commit/1fd1adf736e4e5a3e16819c052903dfe4a436132)) ### Bug Fixes * **ci:** correct conditional ([18e625a](https://github.com/anthropics/anthropic-sdk-python/commit/18e625a1a6de15ff7729149c19b8c22191ed8622)) * **ci:** release-doctor — report correct token name ([c91f50d](https://github.com/anthropics/anthropic-sdk-python/commit/c91f50dbd7057ea465b9d71795488cdae8c1a13a)) * **tests:** avoid deprecation warnings ([71b432f](https://github.com/anthropics/anthropic-sdk-python/commit/71b432f2d22d72f6763d7042677cb43122302ded)) ### Chores * **ci:** only run for pushes and fork pull requests ([447b793](https://github.com/anthropics/anthropic-sdk-python/commit/447b793baf8ba4df63a8fcfcd870a85dd2d07f07)) * **internal:** add breaking change detection ([e6d0eca](https://github.com/anthropics/anthropic-sdk-python/commit/e6d0eca3fc5c918b56e42fbe46fcf9bedd26ca4d)) * **internal:** codegen related update ([f88517b](https://github.com/anthropics/anthropic-sdk-python/commit/f88517bfb56969674b82193b788d2043806e5a39)) * **internal:** codegen related update ([a385cb9](https://github.com/anthropics/anthropic-sdk-python/commit/a385cb9270f8214907ce1f4923e16537ac10cdab)) * **internal:** codegen related update ([9d4b537](https://github.com/anthropics/anthropic-sdk-python/commit/9d4b537be3e248f2ce0d98721f9bbbdc32b75575)) * **internal:** codegen related update ([6a3a6fe](https://github.com/anthropics/anthropic-sdk-python/commit/6a3a6fe3743ee448a83f294d394c5bf9b214176f)) * **internal:** codegen related update ([28704a6](https://github.com/anthropics/anthropic-sdk-python/commit/28704a63eb20f6ed78f13b424190cac14aca8a0f)) * **tests:** run tests with min and max supported Python versions by default ([0ad8534](https://github.com/anthropics/anthropic-sdk-python/commit/0ad85343fbe4d2934aa826fde36c7927f7b57803)) * **tests:** skip some failing tests on the latest python versions ([f63a2d2](https://github.com/anthropics/anthropic-sdk-python/commit/f63a2d29d5c56175078eaf5c67a142aec0937174)) ## 0.55.0 (2025-06-23) Full Changelog: [v0.54.0...v0.55.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.54.0...v0.55.0) ### Features * **api:** api update ([4b2134e](https://github.com/anthropics/anthropic-sdk-python/commit/4b2134e5ec3fecab7c56f483b8db87b403a08e05)) * **api:** api update ([2093bff](https://github.com/anthropics/anthropic-sdk-python/commit/2093bfff2a6c25573eaa2a4667f1e1d0e2d89e24)) * **api:** manual updates ([c80fda8](https://github.com/anthropics/anthropic-sdk-python/commit/c80fda8cbd157fbbd23895d034cc7bb7a7614569)) * **client:** add support for aiohttp ([3b03295](https://github.com/anthropics/anthropic-sdk-python/commit/3b03295f15a02ba629d1bdc77e330c2e6043b83e)) ### Bug Fixes * **client:** correctly parse binary response | stream ([d93817d](https://github.com/anthropics/anthropic-sdk-python/commit/d93817d9d761bd5e16b35f3c2973122a9c122240)) * **internal:** revert unintentional changes ([bb3beab](https://github.com/anthropics/anthropic-sdk-python/commit/bb3beab10668be177d6bb573607ef6951a238b24)) * **tests:** fix: tests which call HTTP endpoints directly with the example parameters ([ee69d74](https://github.com/anthropics/anthropic-sdk-python/commit/ee69d74cc40f749280a29afb12420c117d08ef34)) * **tests:** suppress warnings in tests when running on the latest Python versions ([#982](https://github.com/anthropics/anthropic-sdk-python/issues/982)) ([740da21](https://github.com/anthropics/anthropic-sdk-python/commit/740da21b563c6ffe7618edf1dcd658bb894b2edf)) ### Chores * **ci:** enable for pull requests ([08f2dd2](https://github.com/anthropics/anthropic-sdk-python/commit/08f2dd2bd28958c08a3c82fcf00a0fc7d4e2807c)) * **internal:** update conftest.py ([1174a62](https://github.com/anthropics/anthropic-sdk-python/commit/1174a6214624ff8cd64edb121d4ff09e9af6b717)) * **internal:** version bump ([7241eaa](https://github.com/anthropics/anthropic-sdk-python/commit/7241eaa25b6f40bb55f61e766a996a3a18a53a02)) * **readme:** update badges ([00661c2](https://github.com/anthropics/anthropic-sdk-python/commit/00661c275e120314f76bbd480c0267383e992638)) * **tests:** add tests for httpx client instantiation & proxies ([b831d88](https://github.com/anthropics/anthropic-sdk-python/commit/b831d8833010c629143041b4b385929ca9c2198d)) * **tests:** run tests in parallel ([4b24a79](https://github.com/anthropics/anthropic-sdk-python/commit/4b24a791b76c2176de1f35118901da533a10b991)) ### Documentation * **client:** fix httpx.Timeout documentation reference ([b0138b1](https://github.com/anthropics/anthropic-sdk-python/commit/b0138b1b2af3c73e568659c7e717fc955eb976b0)) ## 0.54.0 (2025-06-10) Full Changelog: [v0.53.0...v0.54.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.53.0...v0.54.0) ### Features * **client:** add support for fine-grained-tool-streaming-2025-05-14 ([07ec081](https://github.com/anthropics/anthropic-sdk-python/commit/07ec08119dbc328934fea5ec6eacd00c8dbda089)) ### Bug Fixes * **httpx:** resolve conflict between default transport and proxy settings ([#969](https://github.com/anthropics/anthropic-sdk-python/issues/969)) ([a6efded](https://github.com/anthropics/anthropic-sdk-python/commit/a6efdedcfef881ae3466bb77d92d0338c8338e20)) * **tests:** update test ([99c2433](https://github.com/anthropics/anthropic-sdk-python/commit/99c243363e94f5f3f627cb8b80e3f238503c89f5)) ### Chores * **internal:** version bump ([45029f4](https://github.com/anthropics/anthropic-sdk-python/commit/45029f41c96f62f26ead99a5989c9ad974fc21b9)) ### Documentation * **contributing:** fix uv script for bootstrapping ([d2bde52](https://github.com/anthropics/anthropic-sdk-python/commit/d2bde52286ee8fa65995e73c579a8962087c1da4)) ## 0.53.0 (2025-06-09) Full Changelog: [v0.52.2...v0.53.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.52.2...v0.53.0) ### Features * **client:** add follow_redirects request option ([e5238c0](https://github.com/anthropics/anthropic-sdk-python/commit/e5238c0d77aaab054b58e0ec046fe7a981eecadf)) * **client:** add support for new text_editor_20250429 tool ([b3b3f5b](https://github.com/anthropics/anthropic-sdk-python/commit/b3b3f5b27b9eb3d6f2d4d242fd473aec84fb99a4)) ### Bug Fixes * **client:** deprecate BetaBase64PDFBlock in favor of BetaRequestDocumentBlock ([5ac58e9](https://github.com/anthropics/anthropic-sdk-python/commit/5ac58e97d7b8502db477cf15169ac18c2c0916c9)) * **internal:** fix typing remapping ([6c415da](https://github.com/anthropics/anthropic-sdk-python/commit/6c415da0b2713505b0deaa586f92b2a549b5d3ca)) ### Chores * **internal:** codegen related update ([94812ec](https://github.com/anthropics/anthropic-sdk-python/commit/94812ec4c75c93268c5dec21d2659dd3b0725c32)) * **internal:** version bump ([41ce701](https://github.com/anthropics/anthropic-sdk-python/commit/41ce701f67858e5bfb0f68b8f30f114d9c8e5712)) * **tests:** improve testing by extracting fixtures ([68c62cc](https://github.com/anthropics/anthropic-sdk-python/commit/68c62cc7b97e27985eff22d65b9ba1854eea7a53)) ## 0.52.2 (2025-06-02) Full Changelog: [v0.52.1...v0.52.2](https://github.com/anthropics/anthropic-sdk-python/compare/v0.52.1...v0.52.2) ### Bug Fixes * **client:** fix issue with server_tool_use input tracking and improve tests ([3fe3fa2](https://github.com/anthropics/anthropic-sdk-python/commit/3fe3fa278bbd44fd01c889807154c37259bf617d)) * **docs:** remove reference to rye shell ([2b3d677](https://github.com/anthropics/anthropic-sdk-python/commit/2b3d677a8df49e1c9a26a594436f1ace8af7d3af)) ### Chores * **docs:** remove unnecessary param examples ([6b129f4](https://github.com/anthropics/anthropic-sdk-python/commit/6b129f4fd00ca296b53368966349bcce0ee0e3a0)) ### Refactors * **pkg:** switch from rye to uv ([f553908](https://github.com/anthropics/anthropic-sdk-python/commit/f55390804154b73d9a639fb25b93f21106bcf569)) ## 0.52.1 (2025-05-28) Full Changelog: [v0.52.0...v0.52.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.52.0...v0.52.1) ### Bug Fixes * **example:** logo.png was broken ([#1021](https://github.com/anthropics/anthropic-sdk-python/issues/1021)) ([1ee8314](https://github.com/anthropics/anthropic-sdk-python/commit/1ee83149809e0193612b62f9b443a0acac5d3d37)) ### Chores * **examples:** show how to pass an authorization token to an MCP server ([18be7f3](https://github.com/anthropics/anthropic-sdk-python/commit/18be7f3194ed1171c3ab937b37c2eb9dbf93a6c5)) * **internal:** fix release workflows ([be9af1f](https://github.com/anthropics/anthropic-sdk-python/commit/be9af1f6fd5c0b4befa61fc7ec01ec52cec9ecd5)) ## 0.52.0 (2025-05-22) Full Changelog: [v0.51.0...v0.52.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.51.0...v0.52.0) ### Features * **api:** add claude 4 models, files API, code execution tool, MCP connector and more ([9c48bc6](https://github.com/anthropics/anthropic-sdk-python/commit/9c48bc6211e2b36cab4c25b67a3dfa4e679aa046)) ### Bug Fixes * **package:** support direct resource imports ([6d73bab](https://github.com/anthropics/anthropic-sdk-python/commit/6d73bab63cc666f0de65ec67f7e2b55a3de1b8cf)) ### Chores * **ci:** fix installation instructions ([ca374e5](https://github.com/anthropics/anthropic-sdk-python/commit/ca374e587c283d46afedfa0e571bc4126f252644)) * **ci:** upload sdks to package manager ([fde0c44](https://github.com/anthropics/anthropic-sdk-python/commit/fde0c44a2e4cc3afe34b644f47e3cca986d210c6)) * **internal:** avoid errors for isinstance checks on proxies ([ef4be3f](https://github.com/anthropics/anthropic-sdk-python/commit/ef4be3f6ae02632d1d67ef6d4ac9d3bacef5e934)) * **internal:** codegen related update ([40359d9](https://github.com/anthropics/anthropic-sdk-python/commit/40359d9db8c5c5868a74de85b84c5e9ccbed5ae4)) ### Documentation * add security warning for overriding parameters ([#1008](https://github.com/anthropics/anthropic-sdk-python/issues/1008)) ([9f52239](https://github.com/anthropics/anthropic-sdk-python/commit/9f52239dda32f26c1fdd999723a124d1bc87dc18)) ## 0.51.0 (2025-05-07) Full Changelog: [v0.50.0...v0.51.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.50.0...v0.51.0) ### Features * **api:** adds web search capabilities to the Claude API ([bec0cf9](https://github.com/anthropics/anthropic-sdk-python/commit/bec0cf93c2d7cb47c921236a14c8569e0e22793e)) ### Bug Fixes * **pydantic v1:** more robust ModelField.annotation check ([c50f406](https://github.com/anthropics/anthropic-sdk-python/commit/c50f406767d8e7737a2754d6e1488d8a19216ac0)) * **sockets:** handle non-portable socket flags ([#935](https://github.com/anthropics/anthropic-sdk-python/issues/935)) ([205c8dd](https://github.com/anthropics/anthropic-sdk-python/commit/205c8dda371caa3b393d3cfb4d323714b1fab336)) ### Chores * broadly detect json family of content-type headers ([66bbb3a](https://github.com/anthropics/anthropic-sdk-python/commit/66bbb3a6689a4e2dd4915a7a2940dec53e2b8eb9)) * **ci:** only use depot for staging repos ([c867a11](https://github.com/anthropics/anthropic-sdk-python/commit/c867a11af37416c0d513aa177f77e1bcd0d70949)) * **ci:** run on more branches and use depot runners ([95f5f17](https://github.com/anthropics/anthropic-sdk-python/commit/95f5f17be0ab05ed4e258ccc488d8cf55ffb8f29)) * **internal:** add back missing custom modifications for Web Search ([f43ba69](https://github.com/anthropics/anthropic-sdk-python/commit/f43ba69d5337e5d99f7ca9bd2e773cc57bae5d1c)) * **internal:** minor formatting changes ([8afef08](https://github.com/anthropics/anthropic-sdk-python/commit/8afef086af194df1e4b0d6d25b7fbe4d74bd6850)) * use lazy imports for resources ([704be81](https://github.com/anthropics/anthropic-sdk-python/commit/704be817f436d92d96915cf02608b6827e06945f)) ## 0.50.0 (2025-04-22) Full Changelog: [v0.49.0...v0.50.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.49.0...v0.50.0) ### Features * **api:** extract ContentBlockDelta events into their own schemas ([#920](https://github.com/anthropics/anthropic-sdk-python/issues/920)) ([ae773d6](https://github.com/anthropics/anthropic-sdk-python/commit/ae773d673a7d3cbb28eebce0df9c526f1e855435)) * **api:** manual updates ([46ac1f8](https://github.com/anthropics/anthropic-sdk-python/commit/46ac1f8d1cfa21fbe9df4545d748211c0f3c10e0)) * **api:** manual updates ([48d9739](https://github.com/anthropics/anthropic-sdk-python/commit/48d9739ad741c72d6ecab5200ca53151a604416f)) * **api:** manual updates ([66e8cc3](https://github.com/anthropics/anthropic-sdk-python/commit/66e8cc3fb207a889b1df1028db73291b9800f8f9)) * **api:** manual updates ([a74746e](https://github.com/anthropics/anthropic-sdk-python/commit/a74746e0df0b3c9b85a42e95a80c1db763379e1b)) ### Bug Fixes * **ci:** ensure pip is always available ([#907](https://github.com/anthropics/anthropic-sdk-python/issues/907)) ([3632687](https://github.com/anthropics/anthropic-sdk-python/commit/36326871c1304fbb1dad56e3e5bc71659bbf0df1)) * **ci:** remove publishing patch ([#908](https://github.com/anthropics/anthropic-sdk-python/issues/908)) ([cae0323](https://github.com/anthropics/anthropic-sdk-python/commit/cae032381bd73e86174b5fde2efaf046e96f5e6a)) * **client:** deduplicate stop reason type ([#913](https://github.com/anthropics/anthropic-sdk-python/issues/913)) ([3ab0194](https://github.com/anthropics/anthropic-sdk-python/commit/3ab0194550aa9893cc948c3d658a965817d64ccd)) * **client:** send all configured auth headers ([#929](https://github.com/anthropics/anthropic-sdk-python/issues/929)) ([9d2581e](https://github.com/anthropics/anthropic-sdk-python/commit/9d2581e79f31effb34958e633b59b19aa3681875)) * **perf:** optimize some hot paths ([cff76cb](https://github.com/anthropics/anthropic-sdk-python/commit/cff76cb00ba0b7839141d84d1f751516a11240c3)) * **perf:** skip traversing types for NotGiven values ([dadac7f](https://github.com/anthropics/anthropic-sdk-python/commit/dadac7fa7207bef547db39b9003a46512a945a78)) * **project:** bump httpx minimum version to 0.25.0 ([b554138](https://github.com/anthropics/anthropic-sdk-python/commit/b554138c2f5d73dd915092972411f7ab787cfe42)), closes [#902](https://github.com/anthropics/anthropic-sdk-python/issues/902) * **types:** handle more discriminated union shapes ([#906](https://github.com/anthropics/anthropic-sdk-python/issues/906)) ([2fc179a](https://github.com/anthropics/anthropic-sdk-python/commit/2fc179a4d29b720263e84c90f37d078ffab860ad)) * **vertex:** explicitly include requests extra ([2b1221b](https://github.com/anthropics/anthropic-sdk-python/commit/2b1221b76bfcc0dfaa14d94e7f6a3ddc303f3715)) ### Chores * add hash of OpenAPI spec/config inputs to .stats.yml ([#912](https://github.com/anthropics/anthropic-sdk-python/issues/912)) ([ddf7835](https://github.com/anthropics/anthropic-sdk-python/commit/ddf78352c9e589f6102f9373cc01bee9333d15d8)) * **ci:** add timeout thresholds for CI jobs ([7226a5c](https://github.com/anthropics/anthropic-sdk-python/commit/7226a5ccef181041fcea0fffcbc0ed395a700df3)) * **client:** minor internal fixes ([99b9a38](https://github.com/anthropics/anthropic-sdk-python/commit/99b9a387c60347471763c9970f7767ecd4cc04d1)) * **internal:** add back release workflow ([ce18972](https://github.com/anthropics/anthropic-sdk-python/commit/ce189722eefedc794111899d54048bddaa82d17d)) * **internal:** base client updates ([2e08c71](https://github.com/anthropics/anthropic-sdk-python/commit/2e08c714cebd4a7df87f80902220b1502d371d04)) * **internal:** bump pyright version ([d9ea30e](https://github.com/anthropics/anthropic-sdk-python/commit/d9ea30ead2cf76676a3b3ac0181a1616afe8323b)) * **internal:** bump rye to 0.44.0 ([#905](https://github.com/anthropics/anthropic-sdk-python/issues/905)) ([e1a1b14](https://github.com/anthropics/anthropic-sdk-python/commit/e1a1b142c8f385d288cf5395917e6380add556ea)) * **internal:** expand CI branch coverage ([#934](https://github.com/anthropics/anthropic-sdk-python/issues/934)) ([b23fdc9](https://github.com/anthropics/anthropic-sdk-python/commit/b23fdc940d5a8eff35746b39a59678e8c633c289)) * **internal:** fix list file params ([cfbaaf9](https://github.com/anthropics/anthropic-sdk-python/commit/cfbaaf9650a963cf15febb4d141f40f18b37c2ef)) * **internal:** import ordering changes ([#895](https://github.com/anthropics/anthropic-sdk-python/issues/895)) ([b8da2f7](https://github.com/anthropics/anthropic-sdk-python/commit/b8da2f748f478fc83c5f13f1d0dcd2eaf85922e0)) * **internal:** import reformatting ([5e6cd74](https://github.com/anthropics/anthropic-sdk-python/commit/5e6cd74bc383b812698b2d572ff9b016aae94b5e)) * **internal:** reduce CI branch coverage ([07e813f](https://github.com/anthropics/anthropic-sdk-python/commit/07e813f9c1873c5addc1d2adacdb387e8db5f3da)) * **internal:** refactor retries to not use recursion ([4354e82](https://github.com/anthropics/anthropic-sdk-python/commit/4354e82dc891cfa973d056aabada54f461979d2c)) * **internal:** remove CI condition ([#916](https://github.com/anthropics/anthropic-sdk-python/issues/916)) ([043b56b](https://github.com/anthropics/anthropic-sdk-python/commit/043b56b9772d49965cdeec649f2b6c7bdf0249a5)) * **internal:** remove extra empty newlines ([#904](https://github.com/anthropics/anthropic-sdk-python/issues/904)) ([cfe8f6e](https://github.com/anthropics/anthropic-sdk-python/commit/cfe8f6e4e1a5be51a2bd7ced23258b4159564ae7)) * **internal:** remove trailing character ([#924](https://github.com/anthropics/anthropic-sdk-python/issues/924)) ([dc8e781](https://github.com/anthropics/anthropic-sdk-python/commit/dc8e7816a9e8cae3f4f8ccf4b9723f9093b3f05e)) * **internal:** remove unused http client options forwarding ([#890](https://github.com/anthropics/anthropic-sdk-python/issues/890)) ([e0428bf](https://github.com/anthropics/anthropic-sdk-python/commit/e0428bfdffb6adb2e21c6ca365a26816eb699006)) * **internal:** slight transform perf improvement ([#931](https://github.com/anthropics/anthropic-sdk-python/issues/931)) ([3ed4e5e](https://github.com/anthropics/anthropic-sdk-python/commit/3ed4e5eebb7bc5d42c6888cda0388c84ce74fa12)) * **internal:** update config ([#914](https://github.com/anthropics/anthropic-sdk-python/issues/914)) ([a697234](https://github.com/anthropics/anthropic-sdk-python/commit/a697234637b84b2a488309bdb851db2efe17190c)) * **internal:** update models test ([b1e031d](https://github.com/anthropics/anthropic-sdk-python/commit/b1e031dfee560629007dab1120872ca489e1e6c2)) * **internal:** update pyright settings ([38bdc6c](https://github.com/anthropics/anthropic-sdk-python/commit/38bdc6cd3436734f29a39b3e4b2c011733a4c0d3)) * **internal:** variable name and test updates ([#925](https://github.com/anthropics/anthropic-sdk-python/issues/925)) ([f5d0809](https://github.com/anthropics/anthropic-sdk-python/commit/f5d08095216744373f1b5d25f65873ca674796e8)) * **tests:** improve enum examples ([#932](https://github.com/anthropics/anthropic-sdk-python/issues/932)) ([808aaf3](https://github.com/anthropics/anthropic-sdk-python/commit/808aaf32d77ab82e79bb8e37c0cb371403726be1)) * **vertex:** improve error message when missing extra ([15dc4cb](https://github.com/anthropics/anthropic-sdk-python/commit/15dc4cb5297304420fd1d7be8e87697bf60d8b2d)) ### Documentation * revise readme docs about nested params ([#900](https://github.com/anthropics/anthropic-sdk-python/issues/900)) ([0f80ab0](https://github.com/anthropics/anthropic-sdk-python/commit/0f80ab0ffcd5c2d854f01364b1cfe2517e04b40b)) * swap examples used in readme ([#928](https://github.com/anthropics/anthropic-sdk-python/issues/928)) ([96ff1c7](https://github.com/anthropics/anthropic-sdk-python/commit/96ff1c7b6a09907c33def5afd9f61bb597e897b1)) ## 0.49.0 (2025-02-28) Full Changelog: [v0.48.0...v0.49.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.48.0...v0.49.0) ### Features * **api:** add support for disabling tool calls ([#888](https://github.com/anthropics/anthropic-sdk-python/issues/888)) ([bfde3d2](https://github.com/anthropics/anthropic-sdk-python/commit/bfde3d2978f78ee43db351a78fe1b078eb073394)) ### Chores * **docs:** update client docstring ([#887](https://github.com/anthropics/anthropic-sdk-python/issues/887)) ([4d3ec5e](https://github.com/anthropics/anthropic-sdk-python/commit/4d3ec5ec5b9c9aabb7cc7f27345809c347c56d89)) ### Documentation * update URLs from stainlessapi.com to stainless.com ([#885](https://github.com/anthropics/anthropic-sdk-python/issues/885)) ([312364b](https://github.com/anthropics/anthropic-sdk-python/commit/312364b9b5025ba16f0081e6e53b478c3a4fb089)) ## 0.48.0 (2025-02-27) Full Changelog: [v0.47.2...v0.48.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.47.2...v0.48.0) ### Features * **api:** add URL source blocks for images and PDFs ([#884](https://github.com/anthropics/anthropic-sdk-python/issues/884)) ([e6b3a70](https://github.com/anthropics/anthropic-sdk-python/commit/e6b3a70ffbd830a8bdd87c0938897eebc6d5ee33)) ### Documentation * add thinking examples ([f463248](https://github.com/anthropics/anthropic-sdk-python/commit/f46324863dabe4efc4adec7361be5d6888fe4dd5)) ## 0.47.2 (2025-02-25) Full Changelog: [v0.47.1...v0.47.2](https://github.com/anthropics/anthropic-sdk-python/compare/v0.47.1...v0.47.2) ### Bug Fixes * **beta:** add thinking to beta.messages.stream ([69e3db1](https://github.com/anthropics/anthropic-sdk-python/commit/69e3db1de0c584c06ac450cc181144abc1602f13)) ### Chores * **internal:** properly set __pydantic_private__ ([#879](https://github.com/anthropics/anthropic-sdk-python/issues/879)) ([3537a3b](https://github.com/anthropics/anthropic-sdk-python/commit/3537a3bb229412bcd89e79bfda45e89727187244)) ## 0.47.1 (2025-02-24) Full Changelog: [v0.47.0...v0.47.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.47.0...v0.47.1) ### Chores * **internal:** update spec ([#871](https://github.com/anthropics/anthropic-sdk-python/issues/871)) ([916be18](https://github.com/anthropics/anthropic-sdk-python/commit/916be1806d3a86ec5abaef7c00227cd918b92274)) * update large max_tokens error message ([40c71df](https://github.com/anthropics/anthropic-sdk-python/commit/40c71df4b6e7760648f42a5f0995bcc93dafbd17)) ## 0.47.0 (2025-02-24) Full Changelog: [v0.46.0...v0.47.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.46.0...v0.47.0) ### Features * **api:** add claude-3.7 + support for thinking ([c5387e6](https://github.com/anthropics/anthropic-sdk-python/commit/c5387e69e799f14e44006ea4e54fdf32f2f74393)) * **client:** add more status exceptions ([#854](https://github.com/anthropics/anthropic-sdk-python/issues/854)) ([00d9512](https://github.com/anthropics/anthropic-sdk-python/commit/00d95126aff50158c7849d651c35a88ea81ff969)) * **client:** allow passing `NotGiven` for body ([#868](https://github.com/anthropics/anthropic-sdk-python/issues/868)) ([8ab445e](https://github.com/anthropics/anthropic-sdk-python/commit/8ab445e6a837854421f358f4977ff80c5e0635c8)) ### Bug Fixes * **client:** mark some request bodies as optional ([8ab445e](https://github.com/anthropics/anthropic-sdk-python/commit/8ab445e6a837854421f358f4977ff80c5e0635c8)) ### Chores * **internal:** fix devcontainers setup ([#870](https://github.com/anthropics/anthropic-sdk-python/issues/870)) ([1a21c6a](https://github.com/anthropics/anthropic-sdk-python/commit/1a21c6a3fb6969a07e9b8483ed116fb3af7bd3b2)) ## 0.46.0 (2025-02-18) Full Changelog: [v0.45.2...v0.46.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.45.2...v0.46.0) ### Features * **client:** send `X-Stainless-Read-Timeout` header ([#858](https://github.com/anthropics/anthropic-sdk-python/issues/858)) ([0e75983](https://github.com/anthropics/anthropic-sdk-python/commit/0e759835ddfa7d72d0926cab0101601e7c1e8f22)) * **jsonl:** add .close() method ([#862](https://github.com/anthropics/anthropic-sdk-python/issues/862)) ([137335c](https://github.com/anthropics/anthropic-sdk-python/commit/137335c649f3dc886875bb60bddeb0c8d8abb67b)) * **pagination:** avoid fetching when has_more: false ([#860](https://github.com/anthropics/anthropic-sdk-python/issues/860)) ([0cdb81d](https://github.com/anthropics/anthropic-sdk-python/commit/0cdb81d106c48c851fff5c9532c675b414f474b4)) ### Bug Fixes * asyncify on non-asyncio runtimes ([#864](https://github.com/anthropics/anthropic-sdk-python/issues/864)) ([f92b36d](https://github.com/anthropics/anthropic-sdk-python/commit/f92b36d4a87c6b5455945ce38e3ab3db24e9a529)) * **internal:** add back custom header naming support ([#861](https://github.com/anthropics/anthropic-sdk-python/issues/861)) ([cf851ae](https://github.com/anthropics/anthropic-sdk-python/commit/cf851ae9ee57635250beec8bedb0134aa2d79a42)) * **jsonl:** lower chunk size ([#863](https://github.com/anthropics/anthropic-sdk-python/issues/863)) ([38fb720](https://github.com/anthropics/anthropic-sdk-python/commit/38fb72043b436afc02839ad4e2a966a5ef0b0bc1)) ### Chores * **api:** update openapi spec url ([#852](https://github.com/anthropics/anthropic-sdk-python/issues/852)) ([461d821](https://github.com/anthropics/anthropic-sdk-python/commit/461d821965c61d98bf35a8b6fab5da55a2ddddef)) * **internal:** bummp ruff dependency ([#856](https://github.com/anthropics/anthropic-sdk-python/issues/856)) ([590c3fa](https://github.com/anthropics/anthropic-sdk-python/commit/590c3fa154e38f85c3cc6fcc518a6c68ee2bd234)) * **internal:** change default timeout to an int ([#855](https://github.com/anthropics/anthropic-sdk-python/issues/855)) ([3152e1a](https://github.com/anthropics/anthropic-sdk-python/commit/3152e1a135a07430404f3209fbbcb924d9d2b9a2)) * **internal:** fix tests ([fc41ba2](https://github.com/anthropics/anthropic-sdk-python/commit/fc41ba21b492e864685384e82b3eeca1ca56f4eb)) * **internal:** fix type traversing dictionary params ([#859](https://github.com/anthropics/anthropic-sdk-python/issues/859)) ([c5b700d](https://github.com/anthropics/anthropic-sdk-python/commit/c5b700d9abea1fcebc43fe12ac514512fedff0db)) * **internal:** reorder model constants ([#847](https://github.com/anthropics/anthropic-sdk-python/issues/847)) ([aadd531](https://github.com/anthropics/anthropic-sdk-python/commit/aadd5315868ce2eec17cc7d0e8ec4f0b6a4c3c87)) * **internal:** update models used in tests ([aadd531](https://github.com/anthropics/anthropic-sdk-python/commit/aadd5315868ce2eec17cc7d0e8ec4f0b6a4c3c87)) ## 0.45.2 (2025-01-27) Full Changelog: [v0.45.1...v0.45.2](https://github.com/anthropics/anthropic-sdk-python/compare/v0.45.1...v0.45.2) ### Bug Fixes * **streaming:** avoid invalid deser type error ([#845](https://github.com/anthropics/anthropic-sdk-python/issues/845)) ([72a2585](https://github.com/anthropics/anthropic-sdk-python/commit/72a2585680a4cc5d007bf93935424dbc4cecf2bd)) ## 0.45.1 (2025-01-27) Full Changelog: [v0.45.0...v0.45.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.45.0...v0.45.1) ### Bug Fixes * **streaming:** accumulate citations ([#844](https://github.com/anthropics/anthropic-sdk-python/issues/844)) ([e665f2f](https://github.com/anthropics/anthropic-sdk-python/commit/e665f2fefd4573fc45cd4c546a9480f15d18d1cd)) ### Chores * **docs:** updates ([#841](https://github.com/anthropics/anthropic-sdk-python/issues/841)) ([fb10a7d](https://github.com/anthropics/anthropic-sdk-python/commit/fb10a7d658044062e5023cd8495c80d3344af8df)) ## 0.45.0 (2025-01-23) Full Changelog: [v0.44.0...v0.45.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.44.0...v0.45.0) ### Features * **api:** add citations ([#839](https://github.com/anthropics/anthropic-sdk-python/issues/839)) ([2ec74b6](https://github.com/anthropics/anthropic-sdk-python/commit/2ec74b6ff106c6e3d7d55e3c189e345098f8575e)) * **client:** support results endpoint ([#835](https://github.com/anthropics/anthropic-sdk-python/issues/835)) ([5dd88bf](https://github.com/anthropics/anthropic-sdk-python/commit/5dd88bf2d20b8909736cc0bc1e81296ba6e322a9)) ### Chores * **internal:** minor formatting changes ([#838](https://github.com/anthropics/anthropic-sdk-python/issues/838)) ([31eb826](https://github.com/anthropics/anthropic-sdk-python/commit/31eb826deb96a17d3c0bb953c728f39412c12ada)) ## 0.44.0 (2025-01-21) Full Changelog: [v0.43.1...v0.44.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.43.1...v0.44.0) ### Features * **streaming:** add request_id getter ([#831](https://github.com/anthropics/anthropic-sdk-python/issues/831)) ([fb397e0](https://github.com/anthropics/anthropic-sdk-python/commit/fb397e0851bd874a10a69a9531483fd196fc8a55)) ### Bug Fixes * **tests:** make test_get_platform less flaky ([#830](https://github.com/anthropics/anthropic-sdk-python/issues/830)) ([f2c10ca](https://github.com/anthropics/anthropic-sdk-python/commit/f2c10cae0cbff6881bba2a41c93efdcc17e8d2ab)) ### Chores * deprecate more models ([c647e25](https://github.com/anthropics/anthropic-sdk-python/commit/c647e25c3735e4276195ee8eb0011ace3e3e0d2f)) * **internal:** avoid pytest-asyncio deprecation warning ([#832](https://github.com/anthropics/anthropic-sdk-python/issues/832)) ([2b3ceff](https://github.com/anthropics/anthropic-sdk-python/commit/2b3ceff7ef9c953e28044442821069d7de3b0154)) * **internal:** minor style changes ([#833](https://github.com/anthropics/anthropic-sdk-python/issues/833)) ([65cfb7b](https://github.com/anthropics/anthropic-sdk-python/commit/65cfb7b13324e52e2d2987c4de3ed9e5c122a40b)) ### Documentation * **raw responses:** fix duplicate `the` ([#828](https://github.com/anthropics/anthropic-sdk-python/issues/828)) ([ff850f8](https://github.com/anthropics/anthropic-sdk-python/commit/ff850f8081a72090eaaa31e09e560acd3ce18b09)) ## 0.43.1 (2025-01-17) Full Changelog: [v0.43.0...v0.43.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.43.0...v0.43.1) ### Bug Fixes * **docs:** correct results return type ([69ad511](https://github.com/anthropics/anthropic-sdk-python/commit/69ad5112596f6e9aaf5cd2d495cb57516f2afbd4)) ### Chores * **internal:** bump pyright dependency ([#822](https://github.com/anthropics/anthropic-sdk-python/issues/822)) ([f8ddb90](https://github.com/anthropics/anthropic-sdk-python/commit/f8ddb90112a432a750fd4123c747ca581cff54ab)) * **internal:** fix lint ([483cc27](https://github.com/anthropics/anthropic-sdk-python/commit/483cc277b66cb5b1a767e9d91347f22bcf69dc28)) * **streaming:** add runtime type check for better error messages ([#826](https://github.com/anthropics/anthropic-sdk-python/issues/826)) ([cf69e09](https://github.com/anthropics/anthropic-sdk-python/commit/cf69e091d230aa0befb6ace74e64357b1cf2e4cd)) * **types:** add more discriminator metadata ([#825](https://github.com/anthropics/anthropic-sdk-python/issues/825)) ([d0de8e5](https://github.com/anthropics/anthropic-sdk-python/commit/d0de8e564038cc6f801dc663b1938ac571ab47be)) ## 0.43.0 (2025-01-14) Full Changelog: [v0.42.0...v0.43.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.42.0...v0.43.0) ### Features * **api:** add message batch delete endpoint ([#802](https://github.com/anthropics/anthropic-sdk-python/issues/802)) ([9cf1e99](https://github.com/anthropics/anthropic-sdk-python/commit/9cf1e9920d3e0ce8496859b119f19eed8cd75e2b)) * **beta:** add streaming helpers for beta messages ([#819](https://github.com/anthropics/anthropic-sdk-python/issues/819)) ([d913ba3](https://github.com/anthropics/anthropic-sdk-python/commit/d913ba35eb3a95e80154b9d35e4c0a9f4a8dfeb1)) ### Bug Fixes * **client:** only call .close() when needed ([#811](https://github.com/anthropics/anthropic-sdk-python/issues/811)) ([21e0eb3](https://github.com/anthropics/anthropic-sdk-python/commit/21e0eb3c2bb043814541c9dcb68498066be1fc78)) * correctly handle deserialising `cls` fields ([#817](https://github.com/anthropics/anthropic-sdk-python/issues/817)) ([60e56a5](https://github.com/anthropics/anthropic-sdk-python/commit/60e56a5fb4413a97586df84c86765947b7ff92e5)) * **types:** allow extra properties in input schemas ([d0961c2](https://github.com/anthropics/anthropic-sdk-python/commit/d0961c2fcbe7370f145512facad8aab175798158)) ### Chores * add missing isclass check ([#806](https://github.com/anthropics/anthropic-sdk-python/issues/806)) ([1fc034d](https://github.com/anthropics/anthropic-sdk-python/commit/1fc034d784e9a8b30866a8058a4bd50ec2605fd3)) * bump testing data uri ([#800](https://github.com/anthropics/anthropic-sdk-python/issues/800)) ([641ae8d](https://github.com/anthropics/anthropic-sdk-python/commit/641ae8d412e365e44c8965222f487e30a63d57ee)) * **internal:** bump httpx dependency ([#809](https://github.com/anthropics/anthropic-sdk-python/issues/809)) ([7d678f1](https://github.com/anthropics/anthropic-sdk-python/commit/7d678f19b86ac1ad5d18ed47739d3df64187c843)) * **internal:** minor reformatting ([5a80668](https://github.com/anthropics/anthropic-sdk-python/commit/5a806684c4aaaf7d493bf9ef193e8031f7290b78)) * **internal:** update deps ([#820](https://github.com/anthropics/anthropic-sdk-python/issues/820)) ([32c3e1a](https://github.com/anthropics/anthropic-sdk-python/commit/32c3e1a63da74919dc0cb10a16b731afc2589cf5)) * **internal:** update examples ([#810](https://github.com/anthropics/anthropic-sdk-python/issues/810)) ([bb588ca](https://github.com/anthropics/anthropic-sdk-python/commit/bb588ca71a374b38797390c62bee66a0329c28a0)) * **vertex:** remove deprecated HTTP client options ([3f4eada](https://github.com/anthropics/anthropic-sdk-python/commit/3f4eada664421accec6f33a7ead44101323d0b14)) * **vertex:** remove deprecated HTTP client options ([c82f3e8](https://github.com/anthropics/anthropic-sdk-python/commit/c82f3e8ce16e8840cce94e023a82c596432f5c98)) ### Documentation * fix typos ([#812](https://github.com/anthropics/anthropic-sdk-python/issues/812)) ([8f46cae](https://github.com/anthropics/anthropic-sdk-python/commit/8f46cae8af228c9520bf95383afd1dce49198517)) * fix typos ([#813](https://github.com/anthropics/anthropic-sdk-python/issues/813)) ([ac44348](https://github.com/anthropics/anthropic-sdk-python/commit/ac443484c21e89bf0c491179613ae61709f87cb9)) * **readme:** fix misplaced period ([#816](https://github.com/anthropics/anthropic-sdk-python/issues/816)) ([4358226](https://github.com/anthropics/anthropic-sdk-python/commit/4358226929ffc3a7f1cb49489b7288ab870e636b)) ### Refactors * **stream:** make `MessageStream` wrap `Stream` directly ([#805](https://github.com/anthropics/anthropic-sdk-python/issues/805)) ([5669399](https://github.com/anthropics/anthropic-sdk-python/commit/56693993cce931fb0ae12d8890099069c4c95dff)) * **vertex:** remove deprecated HTTP client options ([#808](https://github.com/anthropics/anthropic-sdk-python/issues/808)) ([3f4eada](https://github.com/anthropics/anthropic-sdk-python/commit/3f4eada664421accec6f33a7ead44101323d0b14)) ## 0.42.0 (2024-12-17) Full Changelog: [v0.41.0...v0.42.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.41.0...v0.42.0) ### Features * **api:** general availability updates ([#795](https://github.com/anthropics/anthropic-sdk-python/issues/795)) ([0954c48](https://github.com/anthropics/anthropic-sdk-python/commit/0954c488e64a8d80d2dfa160b0ffdd8366996d2e)) ### Bug Fixes * **vertex:** remove `anthropic_version` deletion for token counting ([f613929](https://github.com/anthropics/anthropic-sdk-python/commit/f613929150591e8927af590554e71f197fc243fc)) ### Chores * **internal:** fix some typos ([#799](https://github.com/anthropics/anthropic-sdk-python/issues/799)) ([45addb6](https://github.com/anthropics/anthropic-sdk-python/commit/45addb671fde3c7e06735fbd09fee278e0ddff18)) ## 0.41.0 (2024-12-17) Full Changelog: [v0.40.0...v0.41.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.40.0...v0.41.0) ### Features * **api:** general availability updates ([5db8538](https://github.com/anthropics/anthropic-sdk-python/commit/5db8538cca2ab957ccb5460bf3f33636de0a5106)) * **api:** general availability updates ([#795](https://github.com/anthropics/anthropic-sdk-python/issues/795)) ([c8d5e43](https://github.com/anthropics/anthropic-sdk-python/commit/c8d5e43d00e0e68a68b9ecac15414135750495ff)) * **vertex:** support token counting ([6c3eded](https://github.com/anthropics/anthropic-sdk-python/commit/6c3ededeb68f878a94998d61d0c78209ec640d0c)) ### Bug Fixes * **internal:** correct support for TypeAliasType ([2f6ba9e](https://github.com/anthropics/anthropic-sdk-python/commit/2f6ba9e9f827b39b373a4b2904df04fef940001a)) ### Chores * **api:** update spec version ([#792](https://github.com/anthropics/anthropic-sdk-python/issues/792)) ([f54c1da](https://github.com/anthropics/anthropic-sdk-python/commit/f54c1daf964d0cca09e023bd89adf7d9c97f385d)) * **bedrock/vertex:** explicit error for unsupported messages endpoints ([c4cf816](https://github.com/anthropics/anthropic-sdk-python/commit/c4cf8164c20081cc75fefbe39db5b76be1c724e1)) * **internal:** add support for TypeAliasType ([#786](https://github.com/anthropics/anthropic-sdk-python/issues/786)) ([287ebd2](https://github.com/anthropics/anthropic-sdk-python/commit/287ebd2287ca90408999fe6be3b6f8c0295b46ef)) * **internal:** bump pydantic dependency ([#775](https://github.com/anthropics/anthropic-sdk-python/issues/775)) ([99b4d06](https://github.com/anthropics/anthropic-sdk-python/commit/99b4d06e73cdae3f2c97c304b8c0b64ec4758768)) * **internal:** bump pyright ([#769](https://github.com/anthropics/anthropic-sdk-python/issues/769)) ([81f7d70](https://github.com/anthropics/anthropic-sdk-python/commit/81f7d70fa85029f86de30ac1701ec39d01dde8f9)) * **internal:** bump pyright ([#785](https://github.com/anthropics/anthropic-sdk-python/issues/785)) ([44ab333](https://github.com/anthropics/anthropic-sdk-python/commit/44ab3339b7f3860e3a492a1784f247702bea5be0)) * **internal:** remove some duplicated imports ([#788](https://github.com/anthropics/anthropic-sdk-python/issues/788)) ([576ae9b](https://github.com/anthropics/anthropic-sdk-python/commit/576ae9b83214fd78fb02c420abfc0760270ffba8)) * **internal:** update spec ([#793](https://github.com/anthropics/anthropic-sdk-python/issues/793)) ([7cffc99](https://github.com/anthropics/anthropic-sdk-python/commit/7cffc992b17c475ceaef90868660c5a536e51624)) * **internal:** updated imports ([#789](https://github.com/anthropics/anthropic-sdk-python/issues/789)) ([d163c08](https://github.com/anthropics/anthropic-sdk-python/commit/d163c08caa9515fc5f59f284d236b16e7f0adb40)) * make the `Omit` type public ([#772](https://github.com/anthropics/anthropic-sdk-python/issues/772)) ([4ed0419](https://github.com/anthropics/anthropic-sdk-python/commit/4ed041961b59a7943b00a8e592ead0e962f36174)) * remove deprecated HTTP client options ([#777](https://github.com/anthropics/anthropic-sdk-python/issues/777)) ([3933368](https://github.com/anthropics/anthropic-sdk-python/commit/3933368e8a54d1f81c9503576e461c3d75292c39)) ### Documentation * **readme:** example snippet for client context manager ([#791](https://github.com/anthropics/anthropic-sdk-python/issues/791)) ([d0a5f0c](https://github.com/anthropics/anthropic-sdk-python/commit/d0a5f0c0568afcac5680d4c38943c8d634521c06)) * **readme:** fix http client proxies example ([#778](https://github.com/anthropics/anthropic-sdk-python/issues/778)) ([df1a549](https://github.com/anthropics/anthropic-sdk-python/commit/df1a5494d2d3be86717c344654ce54e2f97f19be)) * use latest sonnet in example snippets ([#781](https://github.com/anthropics/anthropic-sdk-python/issues/781)) ([1ad9e4f](https://github.com/anthropics/anthropic-sdk-python/commit/1ad9e4ff559f16760de15e2352a64bb2b3103071)) ## 0.40.0 (2024-11-28) Full Changelog: [v0.39.0...v0.40.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.39.0...v0.40.0) ### Features * **client:** add ._request_id property to object responses ([#743](https://github.com/anthropics/anthropic-sdk-python/issues/743)) ([9fb64a6](https://github.com/anthropics/anthropic-sdk-python/commit/9fb64a627821730fcf48662f6326d4c0f8c623ab)) ### Bug Fixes * **asyncify:** avoid hanging process under certain conditions ([#756](https://github.com/anthropics/anthropic-sdk-python/issues/756)) ([c71bba2](https://github.com/anthropics/anthropic-sdk-python/commit/c71bba2ad5248400c0142fca5e53c505f9e6d417)) * **bedrock:** correct URL encoding for model params ([#759](https://github.com/anthropics/anthropic-sdk-python/issues/759)) ([be4e73a](https://github.com/anthropics/anthropic-sdk-python/commit/be4e73a6d6ced33c887cc338c7755f5fe1697e54)) * **client:** compat with new httpx 0.28.0 release ([#765](https://github.com/anthropics/anthropic-sdk-python/issues/765)) ([de51f60](https://github.com/anthropics/anthropic-sdk-python/commit/de51f6089f7b025db5d150438caf78a615431cde)) * don't use dicts as iterables in transform ([#750](https://github.com/anthropics/anthropic-sdk-python/issues/750)) ([1f71464](https://github.com/anthropics/anthropic-sdk-python/commit/1f71464a818066687bf6c1bcae0abb991d6ed9cd)) * **types:** remove anthropic-instant-1.2 model ([#744](https://github.com/anthropics/anthropic-sdk-python/issues/744)) ([23637de](https://github.com/anthropics/anthropic-sdk-python/commit/23637de028c6c870f062fc0fbaefa9ae54a0e053)) ### Chores * **api:** update spec version ([#751](https://github.com/anthropics/anthropic-sdk-python/issues/751)) ([4ec986c](https://github.com/anthropics/anthropic-sdk-python/commit/4ec986ccfa601a78f9fff721710390c1fb4727cc)) * **ci:** remove unneeded workflow ([#742](https://github.com/anthropics/anthropic-sdk-python/issues/742)) ([472b7d3](https://github.com/anthropics/anthropic-sdk-python/commit/472b7d362c4bd32e7b32c5a10ed3d40e6821f052)) * **internal:** exclude mypy from running on tests ([#764](https://github.com/anthropics/anthropic-sdk-python/issues/764)) ([bce763a](https://github.com/anthropics/anthropic-sdk-python/commit/bce763a35f5420d0e811ff3cd4d2bf7494f11081)) * **internal:** fix compat model_dump method when warnings are passed ([#760](https://github.com/anthropics/anthropic-sdk-python/issues/760)) ([0e09236](https://github.com/anthropics/anthropic-sdk-python/commit/0e0923612bb1ce4eb18f82966055df4fb8cd348d)) * **internal:** minor formatting changes ([493020e](https://github.com/anthropics/anthropic-sdk-python/commit/493020eed859bd20e49f4ac7ec0b6c3293c7d3fd)) * remove now unused `cached-property` dep ([#762](https://github.com/anthropics/anthropic-sdk-python/issues/762)) ([b9ffefe](https://github.com/anthropics/anthropic-sdk-python/commit/b9ffefec20279705a86e4ad342597886bd7064ca)) * **tests:** adjust retry timeout values ([#736](https://github.com/anthropics/anthropic-sdk-python/issues/736)) ([27ed781](https://github.com/anthropics/anthropic-sdk-python/commit/27ed7816aa8ae32f179652ea6171dd621ef8a6b5)) * **tests:** limit array example length ([#754](https://github.com/anthropics/anthropic-sdk-python/issues/754)) ([6cab2b9](https://github.com/anthropics/anthropic-sdk-python/commit/6cab2b9237c9679ce40e319d035fb4267bca03a7)) ### Documentation * add info log level to readme ([#761](https://github.com/anthropics/anthropic-sdk-python/issues/761)) ([5966b85](https://github.com/anthropics/anthropic-sdk-python/commit/5966b855f3e58d735d8ccfe3244f549baa3a87ed)) * move comments in example snippets ([#749](https://github.com/anthropics/anthropic-sdk-python/issues/749)) ([f887930](https://github.com/anthropics/anthropic-sdk-python/commit/f887930773cbb2d5cb0d4d46ec6cd4f320d045ea)) ## 0.39.0 (2024-11-04) Full Changelog: [v0.38.0...v0.39.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.38.0...v0.39.0) ### ⚠ BREAKING CHANGES * **client:** remove legacy `client.count_tokens()` & `client.get_tokenizer()` methods ([#726](https://github.com/anthropics/anthropic-sdk-python/issues/726)) * This functionality has been replaced by the `client.beta.messages.count_tokens()` API which supports newer models and all content functionality, such as images and PDFs. ### Features * **api:** add new haiku model ([#731](https://github.com/anthropics/anthropic-sdk-python/issues/731)) ([77eaaf9](https://github.com/anthropics/anthropic-sdk-python/commit/77eaaf9c76f9b267706c830a5f7c1d81df6013d9)) * **project:** drop support for Python 3.7 ([#729](https://github.com/anthropics/anthropic-sdk-python/issues/729)) ([7f897e2](https://github.com/anthropics/anthropic-sdk-python/commit/7f897e253ae09e6a85fe64ba8004c2c3a8133e4e)) ### Bug Fixes * don't use dicts as iterables in transform ([#724](https://github.com/anthropics/anthropic-sdk-python/issues/724)) ([62bb863](https://github.com/anthropics/anthropic-sdk-python/commit/62bb8636a3d7156bc0caab5f574b1fa72445cead)) * support json safe serialization for basemodel subclasses ([#727](https://github.com/anthropics/anthropic-sdk-python/issues/727)) ([5be855e](https://github.com/anthropics/anthropic-sdk-python/commit/5be855e20f40042f59e839c7747dd994dc88c456)) * **types:** add missing token-counting-2024-11-01 ([#722](https://github.com/anthropics/anthropic-sdk-python/issues/722)) ([c549736](https://github.com/anthropics/anthropic-sdk-python/commit/c5497360a385f5dbaa5ab775bc19a0d7eee713bc)) ### Documentation * **readme:** mention new token counting endpoint ([#728](https://github.com/anthropics/anthropic-sdk-python/issues/728)) ([72a4636](https://github.com/anthropics/anthropic-sdk-python/commit/72a4636a7798170d69e7551ba58a0213d82d1711)) ### Refactors * **client:** remove legacy `client.count_tokens()` method ([#726](https://github.com/anthropics/anthropic-sdk-python/issues/726)) ([14e4244](https://github.com/anthropics/anthropic-sdk-python/commit/14e4244752b656cedfe7d160088e9744d07470a1)) ## 0.38.0 (2024-11-01) Full Changelog: [v0.37.1...v0.38.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.37.1...v0.38.0) ### Features * **api:** add message token counting & PDFs support ([#721](https://github.com/anthropics/anthropic-sdk-python/issues/721)) ([e4856dd](https://github.com/anthropics/anthropic-sdk-python/commit/e4856dd6be698e797eaee2d6a669a6aaa6719e7d)) ### Bug Fixes * **count_tokens:** correctly set beta header ([e5b4b54](https://github.com/anthropics/anthropic-sdk-python/commit/e5b4b54e3ea1b4fc2d947d45df17996f66900387)) * **types:** add missing token-counting-2024-11-01 ([1897883](https://github.com/anthropics/anthropic-sdk-python/commit/1897883d6332bd0ad10cf13ad09e30563c3e7232)) ### Chores * **internal:** bump mypy ([#720](https://github.com/anthropics/anthropic-sdk-python/issues/720)) ([fe8d19e](https://github.com/anthropics/anthropic-sdk-python/commit/fe8d19e265c57fa9e34a09e46e808322e70c721d)) * **internal:** bump pytest to v8 & pydantic ([#716](https://github.com/anthropics/anthropic-sdk-python/issues/716)) ([00fe1f8](https://github.com/anthropics/anthropic-sdk-python/commit/00fe1f8b0c9c1312c7f1e62ce6ef9c5c56478ede)) * **internal:** update spec version ([#712](https://github.com/anthropics/anthropic-sdk-python/issues/712)) ([f71b0f5](https://github.com/anthropics/anthropic-sdk-python/commit/f71b0f5e54aab20b93cd13609151aa833583145a)) * **tests:** move lazy tokenizer test outside of pytest ([d8f2402](https://github.com/anthropics/anthropic-sdk-python/commit/d8f24023c7110b89528b7b37ddf9c1e6630562c4)) ## 0.37.1 (2024-10-22) Full Changelog: [v0.37.0...v0.37.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.37.0...v0.37.1) ### Bug Fixes * **bedrock:** correct handling of messages beta ([#711](https://github.com/anthropics/anthropic-sdk-python/issues/711)) ([4cba32b](https://github.com/anthropics/anthropic-sdk-python/commit/4cba32b41e82377e155612e05c847baf2ca166d0)) * **vertex:** use correct beta url ([b76db5c](https://github.com/anthropics/anthropic-sdk-python/commit/b76db5c90a9b22d4078a15ac6844a4f75dcbc857)) ## 0.37.0 (2024-10-22) Full Changelog: [v0.36.2...v0.37.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.36.2...v0.37.0) ### Features * **api:** add new model and `computer-use-2024-10-22` beta ([dd93d87](https://github.com/anthropics/anthropic-sdk-python/commit/dd93d872dd00a52b5bd65f84451fc9d368692cde)) * **bedrock:** add messages beta ([2566c93](https://github.com/anthropics/anthropic-sdk-python/commit/2566c93a7d7a861136ebdfde0eb90287977d43d1)) * **vertex:** add messages beta ([0d1f1a6](https://github.com/anthropics/anthropic-sdk-python/commit/0d1f1a663a7bd43f1f524ddaad1d6e18d6d68a61)) ### Bug Fixes * **client/async:** correctly retry in all cases ([#704](https://github.com/anthropics/anthropic-sdk-python/issues/704)) ([ee6febc](https://github.com/anthropics/anthropic-sdk-python/commit/ee6febc4b5c58db9aed835b021e476b46f68033e)) ### Chores * **api:** add title ([#703](https://github.com/anthropics/anthropic-sdk-python/issues/703)) ([a046817](https://github.com/anthropics/anthropic-sdk-python/commit/a046817e9181d35f145249eeb070cfbfd2c36901)) * **internal:** bump ruff dependency ([#700](https://github.com/anthropics/anthropic-sdk-python/issues/700)) ([d5bf9e1](https://github.com/anthropics/anthropic-sdk-python/commit/d5bf9e1f88486552dfba1409cfc699994a1e9aab)) * **internal:** remove unused black config ([#705](https://github.com/anthropics/anthropic-sdk-python/issues/705)) ([3259eb0](https://github.com/anthropics/anthropic-sdk-python/commit/3259eb0a740e65ec649da41667a703d0a4ec1eee)) * **internal:** update spec ([#706](https://github.com/anthropics/anthropic-sdk-python/issues/706)) ([6ab0ce9](https://github.com/anthropics/anthropic-sdk-python/commit/6ab0ce9acf3fdfb217c3885198f88a9ece0969af)) ## 0.36.2 (2024-10-17) Full Changelog: [v0.36.1...v0.36.2](https://github.com/anthropics/anthropic-sdk-python/compare/v0.36.1...v0.36.2) ### Bug Fixes * **types:** remove misleading betas TypedDict property for the Batch API ([#697](https://github.com/anthropics/anthropic-sdk-python/issues/697)) ([e1b9e31](https://github.com/anthropics/anthropic-sdk-python/commit/e1b9e311644103466904fdce78469380d971ccad)) ### Chores * **internal:** update test syntax ([#699](https://github.com/anthropics/anthropic-sdk-python/issues/699)) ([a836157](https://github.com/anthropics/anthropic-sdk-python/commit/a836157d1c0cefc452f5f27fe90eea3b4ff687d2)) ## 0.36.1 (2024-10-15) Full Changelog: [v0.36.0...v0.36.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.36.0...v0.36.1) ### Bug Fixes * allow header params to override default headers ([#690](https://github.com/anthropics/anthropic-sdk-python/issues/690)) ([56f195f](https://github.com/anthropics/anthropic-sdk-python/commit/56f195ff1a67f2ba6e546ad897cbb0fe39f36a3b)) * **beta:** merge betas param with the default value ([#695](https://github.com/anthropics/anthropic-sdk-python/issues/695)) ([f52eac9](https://github.com/anthropics/anthropic-sdk-python/commit/f52eac9357c0c496f1307def2628376d8a36e5ba)) ### Chores * **internal:** update spec URL ([#694](https://github.com/anthropics/anthropic-sdk-python/issues/694)) ([1b437cc](https://github.com/anthropics/anthropic-sdk-python/commit/1b437cc40f2e02e59df06744cc1458ee0cae202a)) ## 0.36.0 (2024-10-08) Full Changelog: [v0.35.0...v0.36.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.35.0...v0.36.0) ### Features * **api:** add message batches api ([cd1ffcb](https://github.com/anthropics/anthropic-sdk-python/commit/cd1ffcb5e506c62e82e6f1365718949840724b9a)) ### Bug Fixes * **client:** avoid OverflowError with very large retry counts ([#676](https://github.com/anthropics/anthropic-sdk-python/issues/676)) ([93d6eeb](https://github.com/anthropics/anthropic-sdk-python/commit/93d6eeb80e63424b8a97f949d5354052b6b16cf4)) ### Chores * add repr to PageInfo class ([#678](https://github.com/anthropics/anthropic-sdk-python/issues/678)) ([53e87e8](https://github.com/anthropics/anthropic-sdk-python/commit/53e87e8abed82fe90fb2d877f69a2cc695662e86)) ### Refactors * **types:** improve metadata type names ([#683](https://github.com/anthropics/anthropic-sdk-python/issues/683)) ([59f2088](https://github.com/anthropics/anthropic-sdk-python/commit/59f208855039bb7b31266ae5e12d7454ecd69f3b)) * **types:** improve metadata types ([#682](https://github.com/anthropics/anthropic-sdk-python/issues/682)) ([e037d1c](https://github.com/anthropics/anthropic-sdk-python/commit/e037d1c310a6487e4f94a751232399e75f10b46d)) * **types:** improve tool type names ([#679](https://github.com/anthropics/anthropic-sdk-python/issues/679)) ([f6f3afe](https://github.com/anthropics/anthropic-sdk-python/commit/f6f3afe2e26ba004a24f7c3bdd36c7b4c1ae4697)) * **types:** improve tool type names ([#680](https://github.com/anthropics/anthropic-sdk-python/issues/680)) ([fe2e417](https://github.com/anthropics/anthropic-sdk-python/commit/fe2e4178dbdea42e84fd925e9e259fef6134c3d3)) ## 0.35.0 (2024-10-04) Full Changelog: [v0.34.2...v0.35.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.34.2...v0.35.0) ### Features * **api:** support disabling parallel tool use ([#674](https://github.com/anthropics/anthropic-sdk-python/issues/674)) ([9079a99](https://github.com/anthropics/anthropic-sdk-python/commit/9079a99fffe5cf7bc91f052ed46b568e55792abf)) * **bedrock:** add `profile` argument to client ([#648](https://github.com/anthropics/anthropic-sdk-python/issues/648)) ([6ea5fce](https://github.com/anthropics/anthropic-sdk-python/commit/6ea5fce3b3a4d1ef4d5d3bbce8e27ea11e6dae72)) * **client:** allow overriding retry count header ([#670](https://github.com/anthropics/anthropic-sdk-python/issues/670)) ([1fb081f](https://github.com/anthropics/anthropic-sdk-python/commit/1fb081fa2005ad30d78a97755f14f81cbcfe28ab)) * **client:** send retry count header ([#664](https://github.com/anthropics/anthropic-sdk-python/issues/664)) ([17c26d5](https://github.com/anthropics/anthropic-sdk-python/commit/17c26d5761b3ee686525f43b22ab6d5e40fc90b1)) ### Bug Fixes * **client:** handle domains with underscores ([#663](https://github.com/anthropics/anthropic-sdk-python/issues/663)) ([84ad451](https://github.com/anthropics/anthropic-sdk-python/commit/84ad451bf1fa9ddff1f409472e8b63ae7678aa83)) * **types:** correctly mark stream discriminator as optional ([#657](https://github.com/anthropics/anthropic-sdk-python/issues/657)) ([2386f98](https://github.com/anthropics/anthropic-sdk-python/commit/2386f983593613034e6ca106be6a0cf95009ea4c)) ### Chores * add docstrings to raw response properties ([#654](https://github.com/anthropics/anthropic-sdk-python/issues/654)) ([35e6cf7](https://github.com/anthropics/anthropic-sdk-python/commit/35e6cf7c39d715181fb68f8fea6b835bf5d2085d)) * **internal:** add support for parsing bool response content ([#675](https://github.com/anthropics/anthropic-sdk-python/issues/675)) ([0bbc0a3](https://github.com/anthropics/anthropic-sdk-python/commit/0bbc0a365b9d64be93cfc8e6b992df95d83c06d7)) * **internal:** bump pyright / mypy version ([#662](https://github.com/anthropics/anthropic-sdk-python/issues/662)) ([c03a71f](https://github.com/anthropics/anthropic-sdk-python/commit/c03a71f71af845eef0b38ff29cdbaa444464fc6e)) * **internal:** bump ruff ([#660](https://github.com/anthropics/anthropic-sdk-python/issues/660)) ([0a34018](https://github.com/anthropics/anthropic-sdk-python/commit/0a34018057f818bf11ec0019ed1e9f413919b682)) * **internal:** update pydantic v1 compat helpers ([#666](https://github.com/anthropics/anthropic-sdk-python/issues/666)) ([ee8e2bd](https://github.com/anthropics/anthropic-sdk-python/commit/ee8e2bdd66b017ef87431ac8ff0b550b18548a3d)) * **internal:** use `typing_extensions.overload` instead of `typing` ([#667](https://github.com/anthropics/anthropic-sdk-python/issues/667)) ([153361d](https://github.com/anthropics/anthropic-sdk-python/commit/153361d4f24cc3497bd62a0a403007c889a8ed51)) * pyproject.toml formatting changes ([#650](https://github.com/anthropics/anthropic-sdk-python/issues/650)) ([4c229dc](https://github.com/anthropics/anthropic-sdk-python/commit/4c229dcdddb59785469390f330f82763d052cf4d)) ### Documentation * fix typo in fenced code block language ([#673](https://github.com/anthropics/anthropic-sdk-python/issues/673)) ([a03414e](https://github.com/anthropics/anthropic-sdk-python/commit/a03414e2d84c76db2cdf5e7ef2d04fef3b74b01a)) * improve and reference contributing documentation ([#672](https://github.com/anthropics/anthropic-sdk-python/issues/672)) ([5bd9690](https://github.com/anthropics/anthropic-sdk-python/commit/5bd96900d56338336efa37156ea144df7b69c624)) * **readme:** add section on determining installed version ([#655](https://github.com/anthropics/anthropic-sdk-python/issues/655)) ([5898f42](https://github.com/anthropics/anthropic-sdk-python/commit/5898f42ec2b794bcc26c98336768a10d6efed44f)) * update CONTRIBUTING.md ([#659](https://github.com/anthropics/anthropic-sdk-python/issues/659)) ([2df25bf](https://github.com/anthropics/anthropic-sdk-python/commit/2df25bf6d65a39fea6f526b692298e25667b1148)) ## 0.34.2 (2024-09-04) Full Changelog: [v0.34.1...v0.34.2](https://github.com/anthropics/anthropic-sdk-python/compare/v0.34.1...v0.34.2) ### Chores * **api:** deprecate claude-1 model ([eab07dc](https://github.com/anthropics/anthropic-sdk-python/commit/eab07dc1984ea20918bb0d902108a1ce4646a1e0)) * **ci:** also run pydantic v1 tests ([#644](https://github.com/anthropics/anthropic-sdk-python/issues/644)) ([c61fe89](https://github.com/anthropics/anthropic-sdk-python/commit/c61fe899e79f21691c7a19d40f1bc397b3f3f82d)) ## 0.34.1 (2024-08-19) Full Changelog: [v0.34.0...v0.34.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.34.0...v0.34.1) ### Chores * **ci:** add CODEOWNERS file ([#639](https://github.com/anthropics/anthropic-sdk-python/issues/639)) ([33001cc](https://github.com/anthropics/anthropic-sdk-python/commit/33001ccf80f6ec2ac43b74f5f41034ec6a12552b)) * **client:** fix parsing union responses when non-json is returned ([#643](https://github.com/anthropics/anthropic-sdk-python/issues/643)) ([45be91d](https://github.com/anthropics/anthropic-sdk-python/commit/45be91dbcc2789a71a048a34f1f23977b9829818)) * **docs/api:** update prompt caching helpers ([6a55aee](https://github.com/anthropics/anthropic-sdk-python/commit/6a55aeeaca83ade0adc18eae0f8682558769d5ff)) * **internal:** use different 32bit detection method ([#640](https://github.com/anthropics/anthropic-sdk-python/issues/640)) ([d6b2b63](https://github.com/anthropics/anthropic-sdk-python/commit/d6b2b630613f7c5f01fc3cd005a055989e7d8e71)) ## 0.34.0 (2024-08-14) Full Changelog: [v0.33.1...v0.34.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.33.1...v0.34.0) ### Features * **api:** add prompt caching beta ([3978411](https://github.com/anthropics/anthropic-sdk-python/commit/397841125164a2420d5abf8f45d47f2467e36cd9)) * **client:** add streaming helpers for prompt caching ([98a0a7b](https://github.com/anthropics/anthropic-sdk-python/commit/98a0a7b9c679539c98d212b12c0a9a950fd6371d)) ### Chores * **examples:** minor formatting changes ([#633](https://github.com/anthropics/anthropic-sdk-python/issues/633)) ([20487ea](https://github.com/anthropics/anthropic-sdk-python/commit/20487ea0080969511e7c41f199387b87a84f6ab4)) ## 0.33.1 (2024-08-12) Full Changelog: [v0.33.0...v0.33.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.33.0...v0.33.1) ### Chores * **ci:** bump prism mock server version ([#630](https://github.com/anthropics/anthropic-sdk-python/issues/630)) ([29545ee](https://github.com/anthropics/anthropic-sdk-python/commit/29545eee2e7bfdfe73b590d9301aa68bbf2c361d)) * **internal:** ensure package is importable in lint cmd ([#632](https://github.com/anthropics/anthropic-sdk-python/issues/632)) ([d685824](https://github.com/anthropics/anthropic-sdk-python/commit/d685824b2c080bd1b17f677f4af422b5cb0e7ed5)) ## 0.33.0 (2024-08-09) Full Changelog: [v0.32.0...v0.33.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.32.0...v0.33.0) ### Features * **client:** add `retries_taken` to raw response class ([43fb587](https://github.com/anthropics/anthropic-sdk-python/commit/43fb5874b0a2398221d1f1d0fea316faca9f6484)) ### Chores * **internal:** bump pyright ([#622](https://github.com/anthropics/anthropic-sdk-python/issues/622)) ([9480109](https://github.com/anthropics/anthropic-sdk-python/commit/9480109c380ff571487429d5f50f50e23947d788)) * **internal:** bump ruff version ([#625](https://github.com/anthropics/anthropic-sdk-python/issues/625)) ([b1a4e7b](https://github.com/anthropics/anthropic-sdk-python/commit/b1a4e7b9a8c17184038d1816ff08619cb03f6296)) * **internal:** test updates ([#624](https://github.com/anthropics/anthropic-sdk-python/issues/624)) ([2cea1f5](https://github.com/anthropics/anthropic-sdk-python/commit/2cea1f52bad2fb6b8f0705fd672f75d8a6281ba0)) * **internal:** update pydantic compat helper function ([#627](https://github.com/anthropics/anthropic-sdk-python/issues/627)) ([dc18ee0](https://github.com/anthropics/anthropic-sdk-python/commit/dc18ee0af5a86429ee8bcc9d5c186493f8d5c622)) * **internal:** updates ([#629](https://github.com/anthropics/anthropic-sdk-python/issues/629)) ([d6357a6](https://github.com/anthropics/anthropic-sdk-python/commit/d6357a6172a38d7cf5ab51d9d7b699d44d2adc21)) * **internal:** use `TypeAlias` marker for type assignments ([#621](https://github.com/anthropics/anthropic-sdk-python/issues/621)) ([a4bff9c](https://github.com/anthropics/anthropic-sdk-python/commit/a4bff9cee99d3ee2083426ec41b40bdcf70d6b4f)) * sync openapi version ([#617](https://github.com/anthropics/anthropic-sdk-python/issues/617)) ([9c0ad95](https://github.com/anthropics/anthropic-sdk-python/commit/9c0ad95b530f1fbd2293a15dcce7f583a982aad0)) * sync openapi version ([#620](https://github.com/anthropics/anthropic-sdk-python/issues/620)) ([0a3f3fa](https://github.com/anthropics/anthropic-sdk-python/commit/0a3f3fa8d89f90f321c27b0cb8c4187b68161fc5)) * sync openapi version ([#628](https://github.com/anthropics/anthropic-sdk-python/issues/628)) ([cfad41f](https://github.com/anthropics/anthropic-sdk-python/commit/cfad41f8a36836060d1b2bba0f32ee291ff8df05)) ## 0.32.0 (2024-07-29) Full Changelog: [v0.31.2...v0.32.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.31.2...v0.32.0) ### Features * add back compat alias for InputJsonDelta ([25a5b6c](https://github.com/anthropics/anthropic-sdk-python/commit/25a5b6c81ffb5996ef697aab22a22d8be5751bc1)) ### Bug Fixes * change signatures for the stream function ([c9eb11b](https://github.com/anthropics/anthropic-sdk-python/commit/c9eb11b1f9656202ee88e9869e59160bc37f5434)) * **client:** correctly apply client level timeout for messages ([#615](https://github.com/anthropics/anthropic-sdk-python/issues/615)) ([5f8d88f](https://github.com/anthropics/anthropic-sdk-python/commit/5f8d88f6fcc2ba05cd9fc6f8ae7aa8c61dc6b0d0)) ### Chores * **docs:** document how to do per-request http client customization ([#603](https://github.com/anthropics/anthropic-sdk-python/issues/603)) ([5161f62](https://github.com/anthropics/anthropic-sdk-python/commit/5161f626a0bec757b96217dc0f81e8908546f29a)) * **internal:** add type construction helper ([#613](https://github.com/anthropics/anthropic-sdk-python/issues/613)) ([5e36940](https://github.com/anthropics/anthropic-sdk-python/commit/5e36940a42e401c3f0c1e42aa248d431fdf7192c)) * sync spec ([#605](https://github.com/anthropics/anthropic-sdk-python/issues/605)) ([6b7707f](https://github.com/anthropics/anthropic-sdk-python/commit/6b7707f62788fca2e166209e82935a2a2fa8204a)) * **tests:** update prism version ([#607](https://github.com/anthropics/anthropic-sdk-python/issues/607)) ([1797dc6](https://github.com/anthropics/anthropic-sdk-python/commit/1797dc6139ffaca6436ed897972471e67ba1b828)) ### Refactors * extract model out to a named type and rename partialjson ([#612](https://github.com/anthropics/anthropic-sdk-python/issues/612)) ([c53efc7](https://github.com/anthropics/anthropic-sdk-python/commit/c53efc786fa95831a398f37740a81b42f7b64c94)) ## 0.31.2 (2024-07-17) Full Changelog: [v0.31.1...v0.31.2](https://github.com/anthropics/anthropic-sdk-python/compare/v0.31.1...v0.31.2) ### Bug Fixes * **vertex:** also refresh auth if there is no token ([4a8d02d](https://github.com/anthropics/anthropic-sdk-python/commit/4a8d02d0616c04a2acc31a3179b7d50093d6371e)) * **vertex:** correct request options in retries ([460547b](https://github.com/anthropics/anthropic-sdk-python/commit/460547b7e6bafa4044127760946d141d1e49131b)) ### Chores * **docs:** minor update to formatting of API link in README ([#594](https://github.com/anthropics/anthropic-sdk-python/issues/594)) ([113b6ac](https://github.com/anthropics/anthropic-sdk-python/commit/113b6ac65de2a670b0d957d11d48b060106150d3)) * **internal:** update formatting ([#597](https://github.com/anthropics/anthropic-sdk-python/issues/597)) ([565dfcd](https://github.com/anthropics/anthropic-sdk-python/commit/565dfcd4610c26b598f6c72e9182e8c60bffc2a0)) * **tests:** faster bedrock retry tests ([4ff067f](https://github.com/anthropics/anthropic-sdk-python/commit/4ff067f48e8e177ebdb8f06d6a4a0ffe9a096a8b)) ## 0.31.1 (2024-07-15) Full Changelog: [v0.31.0...v0.31.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.31.0...v0.31.1) ### Bug Fixes * **bedrock:** correct request options for retries ([#593](https://github.com/anthropics/anthropic-sdk-python/issues/593)) ([f68c81d](https://github.com/anthropics/anthropic-sdk-python/commit/f68c81d072fceb46d4c0d8ee62cf274eeea99415)) ### Chores * **ci:** also run workflows for PRs targeting `next` ([#587](https://github.com/anthropics/anthropic-sdk-python/issues/587)) ([f7e49f2](https://github.com/anthropics/anthropic-sdk-python/commit/f7e49f2f2ceb62cccd6961fc1bd799655ccd83ab)) * **internal:** minor changes to tests ([#591](https://github.com/anthropics/anthropic-sdk-python/issues/591)) ([fabd591](https://github.com/anthropics/anthropic-sdk-python/commit/fabd5910f2e769b8bfbeaaa8b65ca8383b4954e3)) * **internal:** minor formatting changes ([a71927b](https://github.com/anthropics/anthropic-sdk-python/commit/a71927b7c7cff4e83eb485d3b0eef928a18acef6)) * **internal:** minor import restructuring ([#588](https://github.com/anthropics/anthropic-sdk-python/issues/588)) ([1d9db4f](https://github.com/anthropics/anthropic-sdk-python/commit/1d9db4f6c1393c3879e83e1a3e1d1b4fedc33b5a)) * **internal:** minor options / compat functions updates ([#592](https://github.com/anthropics/anthropic-sdk-python/issues/592)) ([d41a880](https://github.com/anthropics/anthropic-sdk-python/commit/d41a8807057958d4505e16325e4a06359a760260)) * **internal:** update mypy ([#584](https://github.com/anthropics/anthropic-sdk-python/issues/584)) ([0a0edce](https://github.com/anthropics/anthropic-sdk-python/commit/0a0edce53e9eebd47770e71493302527e7f43751)) ## 0.31.0 (2024-07-10) Full Changelog: [v0.30.1...v0.31.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.30.1...v0.31.0) ### Features * **client:** make request-id header more accessible ([#581](https://github.com/anthropics/anthropic-sdk-python/issues/581)) ([130d470](https://github.com/anthropics/anthropic-sdk-python/commit/130d470fc624a25defb9d8e787462b77bdc0aad5)) * **vertex:** add copy and with_options ([#578](https://github.com/anthropics/anthropic-sdk-python/issues/578)) ([fcd425f](https://github.com/anthropics/anthropic-sdk-python/commit/fcd425f724fee45195118aa218bd5c51fb9abed0)) ### Bug Fixes * **client:** always respect content-type multipart/form-data if provided ([#574](https://github.com/anthropics/anthropic-sdk-python/issues/574)) ([6051763](https://github.com/anthropics/anthropic-sdk-python/commit/6051763d886aa7107389d8b8aeacf74d296eed3d)) * **streaming/messages:** more robust event type construction ([#576](https://github.com/anthropics/anthropic-sdk-python/issues/576)) ([98e2075](https://github.com/anthropics/anthropic-sdk-python/commit/98e2075869d816cd85af1a0588bd27719eff02a4)) * **types:** allow arbitrary types in image block param ([#582](https://github.com/anthropics/anthropic-sdk-python/issues/582)) ([ebd6590](https://github.com/anthropics/anthropic-sdk-python/commit/ebd659014b63b51fa2f67fe88ef3fc9922be830d)) * Updated doc typo ([17be06b](https://github.com/anthropics/anthropic-sdk-python/commit/17be06bf3e39eff9de588d99cd59fa509c5ee6a6)) * **vertex:** avoid credentials refresh on every request ([#575](https://github.com/anthropics/anthropic-sdk-python/issues/575)) ([37bd433](https://github.com/anthropics/anthropic-sdk-python/commit/37bd4337828f3efa14b194fa3025638229129416)) ### Chores * **ci:** update rye to v0.35.0 ([#577](https://github.com/anthropics/anthropic-sdk-python/issues/577)) ([e271d69](https://github.com/anthropics/anthropic-sdk-python/commit/e271d694babfb4bcb506064aa353ee29a8394c1d)) * **internal:** add helper method for constructing `BaseModel`s ([#572](https://github.com/anthropics/anthropic-sdk-python/issues/572)) ([8e626ac](https://github.com/anthropics/anthropic-sdk-python/commit/8e626ac7c88bab413bc1e2d83b7556aa4a44fb63)) * **internal:** fix formatting ([a912917](https://github.com/anthropics/anthropic-sdk-python/commit/a912917686d6e4a46d192abf002ac69357b1d955)) * **internal:** minor request options handling changes ([#580](https://github.com/anthropics/anthropic-sdk-python/issues/580)) ([d1dcf42](https://github.com/anthropics/anthropic-sdk-python/commit/d1dcf427ea78f57dd267d891c276b03d4010de78)) ## 0.30.1 (2024-07-01) Full Changelog: [v0.30.0...v0.30.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.30.0...v0.30.1) ### Bug Fixes * **build:** include more files in sdist builds ([#559](https://github.com/anthropics/anthropic-sdk-python/issues/559)) ([9170d08](https://github.com/anthropics/anthropic-sdk-python/commit/9170d08e056ecb33f1441f50b8407a1c60c45d94)) ### Chores * **deps:** bump anyio to v4.4.0 ([#562](https://github.com/anthropics/anthropic-sdk-python/issues/562)) ([70fc936](https://github.com/anthropics/anthropic-sdk-python/commit/70fc9361848e4825f8036da2b76a189d602e0baf)) * gitignore test server logs ([#567](https://github.com/anthropics/anthropic-sdk-python/issues/567)) ([f7b9283](https://github.com/anthropics/anthropic-sdk-python/commit/f7b928386b9f6dfdea6842ce729024afdc55da3f)) * **internal:** add reflection helper function ([#565](https://github.com/anthropics/anthropic-sdk-python/issues/565)) ([9483573](https://github.com/anthropics/anthropic-sdk-python/commit/948357378f2234e7ddc3843c0427cfa0b9914a21)) * **internal:** add rich as a dev dependency ([#568](https://github.com/anthropics/anthropic-sdk-python/issues/568)) ([07903ac](https://github.com/anthropics/anthropic-sdk-python/commit/07903acb9388ce6a3c35058880c89e1275aab1e3)) ## 0.30.0 (2024-06-26) Full Changelog: [v0.29.2...v0.30.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.29.2...v0.30.0) ### Features * **vertex:** add credentials argument ([#542](https://github.com/anthropics/anthropic-sdk-python/issues/542)) ([3bfb2ea](https://github.com/anthropics/anthropic-sdk-python/commit/3bfb2eaf59410053870c7a598bef6404f2201145)) ## 0.29.2 (2024-06-26) Full Changelog: [v0.29.1...v0.29.2](https://github.com/anthropics/anthropic-sdk-python/compare/v0.29.1...v0.29.2) ### Bug Fixes * temporarily patch upstream version to fix broken release flow ([#555](https://github.com/anthropics/anthropic-sdk-python/issues/555)) ([5471710](https://github.com/anthropics/anthropic-sdk-python/commit/54717101f3844791bdde8b9b76f47abf04c6a971)) ## 0.29.1 (2024-06-25) Full Changelog: [v0.29.0...v0.29.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.29.0...v0.29.1) ### Bug Fixes * **api:** add string to tool result block ([#554](https://github.com/anthropics/anthropic-sdk-python/issues/554)) ([f283b4e](https://github.com/anthropics/anthropic-sdk-python/commit/f283b4eb9e4f118bb4ada38479747b22dd5282fa)) * **docs:** fix link to advanced python httpx docs ([#550](https://github.com/anthropics/anthropic-sdk-python/issues/550)) ([474ff7c](https://github.com/anthropics/anthropic-sdk-python/commit/474ff7cad99039f3539a787ec535b5b13e2832a9)) ## 0.29.0 (2024-06-20) Full Changelog: [v0.28.1...v0.29.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.28.1...v0.29.0) ### Features * **api:** add new claude-3-5-sonnet-20240620 model ([#545](https://github.com/anthropics/anthropic-sdk-python/issues/545)) ([5ea6b18](https://github.com/anthropics/anthropic-sdk-python/commit/5ea6b182715cd355cc405554b81f3d0f725486f6)) ### Bug Fixes * **client/async:** avoid blocking io call for platform headers ([#544](https://github.com/anthropics/anthropic-sdk-python/issues/544)) ([3c2b75f](https://github.com/anthropics/anthropic-sdk-python/commit/3c2b75fac662e48effc8ec032266d966e548007d)) ### Chores * **internal:** add a `default_query` method ([#540](https://github.com/anthropics/anthropic-sdk-python/issues/540)) ([0253ebc](https://github.com/anthropics/anthropic-sdk-python/commit/0253ebc9cda491ab909cc752d719e797086691ed)) ## 0.28.1 (2024-06-14) Full Changelog: [v0.28.0...v0.28.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.28.0...v0.28.1) ### Documentation * **readme:** tool use is no longer in beta ([d2be3c0](https://github.com/anthropics/anthropic-sdk-python/commit/d2be3c0438429b6521fc49f5a5ff17fae71fb589)) ## 0.28.0 (2024-05-30) Full Changelog: [v0.27.0...v0.28.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.27.0...v0.28.0) ### ⚠ BREAKING CHANGES * **streaming:** remove old event_handler API ([#532](https://github.com/anthropics/anthropic-sdk-python/issues/532)) ### Refactors * **streaming:** remove old event_handler API ([#532](https://github.com/anthropics/anthropic-sdk-python/issues/532)) ([d9acfd4](https://github.com/anthropics/anthropic-sdk-python/commit/d9acfd427e3d7d8c6bc3d6ed8994194a07ed6a92)) ## 0.27.0 (2024-05-30) Full Changelog: [v0.26.2...v0.27.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.26.2...v0.27.0) ### Features * **api:** tool use is GA and available on 3P ([#530](https://github.com/anthropics/anthropic-sdk-python/issues/530)) ([ad7adbd](https://github.com/anthropics/anthropic-sdk-python/commit/ad7adbd2a732db98665333c27065ff4f4c946f15)) * **streaming/messages:** refactor to event iterator structure ([997af69](https://github.com/anthropics/anthropic-sdk-python/commit/997af696a713a604d4146f36caf91397ba488e33)) * **streaming/tools:** refactor to event iterator structure ([bdcc283](https://github.com/anthropics/anthropic-sdk-python/commit/bdcc28303206fde2da01296cdae553c1e8efb60a)) * **streaming:** add tools support ([9f00950](https://github.com/anthropics/anthropic-sdk-python/commit/9f00950b81d388f14027c48aca1ca3c044b93a03)) ### Bug Fixes * **beta:** streaming breakage due to breaking change in dependency ([afe3c87](https://github.com/anthropics/anthropic-sdk-python/commit/afe3c8726576cdc7e0503707f53fa9a80caed962)) ### Chores * add missing __all__ definitions ([#526](https://github.com/anthropics/anthropic-sdk-python/issues/526)) ([5021787](https://github.com/anthropics/anthropic-sdk-python/commit/5021787caeda8a38775c69449a5794b1072dbfe5)) * **examples:** update tools ([56edecc](https://github.com/anthropics/anthropic-sdk-python/commit/56edecc2de1e943d6ca09a788c4fabac5978ea2d)) * **formatting:** misc fixups ([fbad5a0](https://github.com/anthropics/anthropic-sdk-python/commit/fbad5a0e0d7f4dbeeffa8a038600c9acb88002fc)) * **internal:** fix lint issues in tests ([d857640](https://github.com/anthropics/anthropic-sdk-python/commit/d857640c1e30b580e7e94e034a1fbc07f655acc6)) * **internal:** update bootstrap script ([#527](https://github.com/anthropics/anthropic-sdk-python/issues/527)) ([93ae152](https://github.com/anthropics/anthropic-sdk-python/commit/93ae1528c0404631f32c49341032ca0d11314b80)) * **internal:** update some references to rye-up.com ([00e34e7](https://github.com/anthropics/anthropic-sdk-python/commit/00e34e7fbbb3a797d55bb94c07d551ad083dc7d9)) * **tests:** ensure messages.create() and messages.stream() stay in sync ([52bd67b](https://github.com/anthropics/anthropic-sdk-python/commit/52bd67b041283adeee662355d8df297ca4b1d560)) ### Documentation * **helpers:** mention input json event ([02d482c](https://github.com/anthropics/anthropic-sdk-python/commit/02d482c03c039bc635c4d35e04cebe4670e1762c)) * **helpers:** update for new event iterator ([26f9533](https://github.com/anthropics/anthropic-sdk-python/commit/26f9533df19ee3da55c590238eba745051cccf6c)) ### Refactors * **api:** add Raw prefix to API stream event type names ([#529](https://github.com/anthropics/anthropic-sdk-python/issues/529)) ([bb62980](https://github.com/anthropics/anthropic-sdk-python/commit/bb629806887de6cd3e5d517af4d9615f40076542)) ## 0.26.2 (2024-05-27) Full Changelog: [v0.26.1...v0.26.2](https://github.com/anthropics/anthropic-sdk-python/compare/v0.26.1...v0.26.2) ### Bug Fixes * **vertex:** don't error if project_id couldn't be loaded if it was already explicitly given ([#513](https://github.com/anthropics/anthropic-sdk-python/issues/513)) ([e7159d8](https://github.com/anthropics/anthropic-sdk-python/commit/e7159d87b207592eff364c1d75bab348dd414257)) ### Chores * **ci:** update rye install location ([#516](https://github.com/anthropics/anthropic-sdk-python/issues/516)) ([a6e347a](https://github.com/anthropics/anthropic-sdk-python/commit/a6e347a2c4aa75d00ee3ada3dfa707a080d890b6)) * **ci:** update rye install location ([#518](https://github.com/anthropics/anthropic-sdk-python/issues/518)) ([5122420](https://github.com/anthropics/anthropic-sdk-python/commit/51224208a732136caeb30d839685a91d7a26beda)) * **internal:** bump pyright ([196e4b0](https://github.com/anthropics/anthropic-sdk-python/commit/196e4b06cb4794a06d813b4e59dd8c5fbb61d71d)) * **internal:** remove unused __events stream property ([472b831](https://github.com/anthropics/anthropic-sdk-python/commit/472b831a552e7ebe20a9d503b129d8c1e1cef0c8)) * **internal:** restructure streaming implementation to use composition ([b1a1c03](https://github.com/anthropics/anthropic-sdk-python/commit/b1a1c0354a9aca450a7d512fdbdeb59c0ead688a)) * **messages:** add back-compat for isinstance() checks ([7794bcb](https://github.com/anthropics/anthropic-sdk-python/commit/7794bcb680300249cd9be48562ce190eed8b9cff)) * **tests:** fix lints ([#521](https://github.com/anthropics/anthropic-sdk-python/issues/521)) ([d96fc53](https://github.com/anthropics/anthropic-sdk-python/commit/d96fc530902bfe4b6a0c75044bf60e90f32997e4)) ### Documentation * **contributing:** update references to rye-up.com ([6486898](https://github.com/anthropics/anthropic-sdk-python/commit/6486898e874784f39be36a0a011867dd2fe8a5d5)) ## 0.26.1 (2024-05-21) Full Changelog: [v0.26.0...v0.26.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.26.0...v0.26.1) ### Chores * **docs:** fix typo ([#511](https://github.com/anthropics/anthropic-sdk-python/issues/511)) ([d7401bd](https://github.com/anthropics/anthropic-sdk-python/commit/d7401bdca637958171bad6b17406e8201c5bc6f6)) * **tools:** rely on pydantic's JSON parser instead of pydantic ([#510](https://github.com/anthropics/anthropic-sdk-python/issues/510)) ([8e7edca](https://github.com/anthropics/anthropic-sdk-python/commit/8e7edca45525be97a4a12a365db72b1668b3e4a1)) ## 0.26.0 (2024-05-16) Full Changelog: [v0.25.9...v0.26.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.25.9...v0.26.0) ### Features * **api:** add `tool_choice` param, image block params inside `tool_result.content`, and streaming for `tool_use` blocks ([#502](https://github.com/anthropics/anthropic-sdk-python/issues/502)) ([e0bc274](https://github.com/anthropics/anthropic-sdk-python/commit/e0bc2749d4be57fe9f0d60635b3198de89608bb9)) ### Chores * **internal:** minor formatting changes ([#500](https://github.com/anthropics/anthropic-sdk-python/issues/500)) ([8b32558](https://github.com/anthropics/anthropic-sdk-python/commit/8b32558e95d83badea1bfe4084fb5db86f7f78cd)) ## 0.25.9 (2024-05-14) Full Changelog: [v0.25.8...v0.25.9](https://github.com/anthropics/anthropic-sdk-python/compare/v0.25.8...v0.25.9) ### Bug Fixes * **types:** correct type for InputSchema ([#498](https://github.com/anthropics/anthropic-sdk-python/issues/498)) ([b86936c](https://github.com/anthropics/anthropic-sdk-python/commit/b86936ccb4ebe27bfb04a8fda2cbfdf88bbdc111)) ### Chores * **docs:** add SECURITY.md ([#493](https://github.com/anthropics/anthropic-sdk-python/issues/493)) ([d5cba46](https://github.com/anthropics/anthropic-sdk-python/commit/d5cba4634213b57f39dbc0f339c3320c651cf1bc)) * **internal:** add slightly better logging to scripts ([#497](https://github.com/anthropics/anthropic-sdk-python/issues/497)) ([acb0149](https://github.com/anthropics/anthropic-sdk-python/commit/acb0149b4659c932ca6f3abac46c4de166b5341b)) * **internal:** bump pydantic dependency ([#495](https://github.com/anthropics/anthropic-sdk-python/issues/495)) ([00cd840](https://github.com/anthropics/anthropic-sdk-python/commit/00cd8408254622d7e95812c0208fe09396d07ca4)) * **types:** add union discriminator metadata ([#491](https://github.com/anthropics/anthropic-sdk-python/issues/491)) ([95544a9](https://github.com/anthropics/anthropic-sdk-python/commit/95544a9e9fec7cfaab034355426a2f4634b8e26a)) ## 0.25.8 (2024-05-07) Full Changelog: [v0.25.7...v0.25.8](https://github.com/anthropics/anthropic-sdk-python/compare/v0.25.7...v0.25.8) ### Chores * **client:** log response headers in debug mode ([#480](https://github.com/anthropics/anthropic-sdk-python/issues/480)) ([d1c4d14](https://github.com/anthropics/anthropic-sdk-python/commit/d1c4d14c881b0e754ca220cdcda4d06fe23c81ab)) * **internal:** add link to openapi spec ([#484](https://github.com/anthropics/anthropic-sdk-python/issues/484)) ([876cd0d](https://github.com/anthropics/anthropic-sdk-python/commit/876cd0d5b30ca823c4088124ec303e0765d993b8)) * **internal:** add scripts/test, scripts/mock and add ci job ([#486](https://github.com/anthropics/anthropic-sdk-python/issues/486)) ([6111fe8](https://github.com/anthropics/anthropic-sdk-python/commit/6111fe897d8111f8b3e301923a94eabe1cb96558)) * **internal:** bump prism version ([#487](https://github.com/anthropics/anthropic-sdk-python/issues/487)) ([98fb3e6](https://github.com/anthropics/anthropic-sdk-python/commit/98fb3e63f16adccb6ff46d4c259d1953c91f041e)) ### Documentation * **readme:** fix misleading timeout example value ([#489](https://github.com/anthropics/anthropic-sdk-python/issues/489)) ([b465bce](https://github.com/anthropics/anthropic-sdk-python/commit/b465bce54de95d30190154dbfc53446b1586dade)) ## 0.25.7 (2024-04-29) Full Changelog: [v0.25.6...v0.25.7](https://github.com/anthropics/anthropic-sdk-python/compare/v0.25.6...v0.25.7) ### Bug Fixes * **docs:** doc improvements ([#472](https://github.com/anthropics/anthropic-sdk-python/issues/472)) ([1b6d4e2](https://github.com/anthropics/anthropic-sdk-python/commit/1b6d4e2c6be01dd794824a912cd78545d5bba135)) ### Chores * **internal:** minor reformatting ([#478](https://github.com/anthropics/anthropic-sdk-python/issues/478)) ([de4b2e0](https://github.com/anthropics/anthropic-sdk-python/commit/de4b2e088a997760e177abc765172bb495ccb978)) * **internal:** reformat imports ([#477](https://github.com/anthropics/anthropic-sdk-python/issues/477)) ([553e955](https://github.com/anthropics/anthropic-sdk-python/commit/553e955de5d6aae29ee28e1edfcc24d1ee9f3c25)) * **internal:** restructure imports ([#470](https://github.com/anthropics/anthropic-sdk-python/issues/470)) ([49e0044](https://github.com/anthropics/anthropic-sdk-python/commit/49e0044bcf1949699275d67dbed8dbf1c5412366)) * **internal:** update test helper function ([#476](https://github.com/anthropics/anthropic-sdk-python/issues/476)) ([f46e454](https://github.com/anthropics/anthropic-sdk-python/commit/f46e454f04ccb320fed2639235f9b382f3de27cd)) * **internal:** use actions/checkout@v4 for codeflow ([#474](https://github.com/anthropics/anthropic-sdk-python/issues/474)) ([8b18b52](https://github.com/anthropics/anthropic-sdk-python/commit/8b18b5211a200a1e09647441cd16244dfda05253)) * **tests:** rename test file ([#473](https://github.com/anthropics/anthropic-sdk-python/issues/473)) ([5b8261c](https://github.com/anthropics/anthropic-sdk-python/commit/5b8261c251e765ac239f1c0176ec3001b12769dd)) ## 0.25.6 (2024-04-18) Full Changelog: [v0.25.5...v0.25.6](https://github.com/anthropics/anthropic-sdk-python/compare/v0.25.5...v0.25.6) ### Chores * **internal:** bump pyright to 1.1.359 ([#466](https://github.com/anthropics/anthropic-sdk-python/issues/466)) ([8088160](https://github.com/anthropics/anthropic-sdk-python/commit/808816044cb33499c45e12b609f7a7664c628c88)) ## 0.25.5 (2024-04-17) Full Changelog: [v0.25.4...v0.25.5](https://github.com/anthropics/anthropic-sdk-python/compare/v0.25.4...v0.25.5) ### Chores * **internal:** ban usage of lru_cache ([#464](https://github.com/anthropics/anthropic-sdk-python/issues/464)) ([dc8ca22](https://github.com/anthropics/anthropic-sdk-python/commit/dc8ca22b1994af994ce9502494f4df1741c0559d)) ## 0.25.4 (2024-04-17) Full Changelog: [v0.25.3...v0.25.4](https://github.com/anthropics/anthropic-sdk-python/compare/v0.25.3...v0.25.4) ### Bug Fixes * **bedrock:** correct auth implementation ([#462](https://github.com/anthropics/anthropic-sdk-python/issues/462)) ([2f456f5](https://github.com/anthropics/anthropic-sdk-python/commit/2f456f59f42876dfabde94b6e36f9349fc409aef)) ## 0.25.3 (2024-04-17) Full Changelog: [v0.25.2...v0.25.3](https://github.com/anthropics/anthropic-sdk-python/compare/v0.25.2...v0.25.3) ### Chores * **bedrock:** cache boto sessions ([#455](https://github.com/anthropics/anthropic-sdk-python/issues/455)) ([d58adef](https://github.com/anthropics/anthropic-sdk-python/commit/d58adefc7097d98e25bb1665be2037f968000d76)) ## 0.25.2 (2024-04-15) Full Changelog: [v0.25.1...v0.25.2](https://github.com/anthropics/anthropic-sdk-python/compare/v0.25.1...v0.25.2) ### Chores * **internal:** formatting ([#452](https://github.com/anthropics/anthropic-sdk-python/issues/452)) ([8ac016b](https://github.com/anthropics/anthropic-sdk-python/commit/8ac016b3be19247a7323f3f9fb5aad4d4f30ced5)) ## 0.25.1 (2024-04-11) Full Changelog: [v0.25.0...v0.25.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.25.0...v0.25.1) ### Chores * fix typo ([#449](https://github.com/anthropics/anthropic-sdk-python/issues/449)) ([420a6c5](https://github.com/anthropics/anthropic-sdk-python/commit/420a6c5081ecd58e16b40ca5dfca582aa704c34a)) ## 0.25.0 (2024-04-09) Full Changelog: [v0.24.0...v0.25.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.24.0...v0.25.0) ### Features * **bedrock:** add `copy` / `with_options` to bedrock client ([8af7c41](https://github.com/anthropics/anthropic-sdk-python/commit/8af7c41886c9e599a2199e3e496d9d04157699da)) ### Chores * unknown commit message ([8af7c41](https://github.com/anthropics/anthropic-sdk-python/commit/8af7c41886c9e599a2199e3e496d9d04157699da)) ## 0.24.0 (2024-04-09) Full Changelog: [v0.23.1...v0.24.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.23.1...v0.24.0) ### Features * **client:** add DefaultHttpxClient and DefaultAsyncHttpxClient ([#444](https://github.com/anthropics/anthropic-sdk-python/issues/444)) ([51d2427](https://github.com/anthropics/anthropic-sdk-python/commit/51d2427c0bb51cbd17d55f827da7fb9cc05f5d06)) * **models:** add to_dict & to_json helper methods ([#446](https://github.com/anthropics/anthropic-sdk-python/issues/446)) ([6709f58](https://github.com/anthropics/anthropic-sdk-python/commit/6709f58d0980669100ea0b7935259d3c05cf9648)) ## 0.23.1 (2024-04-04) Full Changelog: [v0.23.0...v0.23.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.23.0...v0.23.1) ### Documentation * **readme:** mention tool use ([#441](https://github.com/anthropics/anthropic-sdk-python/issues/441)) ([e6cd916](https://github.com/anthropics/anthropic-sdk-python/commit/e6cd916b5f4d9cbbae4610828ffb51d81404d74f)) ## 0.23.0 (2024-04-04) Full Changelog: [v0.22.1...v0.23.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.22.1...v0.23.0) ### Features * **api:** tool use beta ([#438](https://github.com/anthropics/anthropic-sdk-python/issues/438)) ([5e35ffe](https://github.com/anthropics/anthropic-sdk-python/commit/5e35ffeec0a38055bba2f3998aa3e7c85790627a)) ## 0.22.1 (2024-04-04) Full Changelog: [v0.22.0...v0.22.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.22.0...v0.22.1) ### Bug Fixes * **types:** correctly mark type as a required property in requests ([#435](https://github.com/anthropics/anthropic-sdk-python/issues/435)) ([efc35ec](https://github.com/anthropics/anthropic-sdk-python/commit/efc35ec7b87b4e7033509431e828fdf42579f74d)) ### Chores * **types:** consistent naming for text block types ([#437](https://github.com/anthropics/anthropic-sdk-python/issues/437)) ([e979fe1](https://github.com/anthropics/anthropic-sdk-python/commit/e979fe14f868e1bc428440c00092decc590bb545)) ## 0.22.0 (2024-04-04) Full Changelog: [v0.21.3...v0.22.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.21.3...v0.22.0) ### Features * **client:** increase default HTTP max_connections to 1000 and max_keepalive_connections to 100 ([#428](https://github.com/anthropics/anthropic-sdk-python/issues/428)) ([9a43940](https://github.com/anthropics/anthropic-sdk-python/commit/9a4394008db937a9ad851589b9adfbd9e15333ef)) * **package:** export default constants ([#423](https://github.com/anthropics/anthropic-sdk-python/issues/423)) ([0d694e1](https://github.com/anthropics/anthropic-sdk-python/commit/0d694e157b040993d937f136c5072c98b87434ff)) ### Bug Fixes * **client:** correct logic for line decoding in streaming ([#433](https://github.com/anthropics/anthropic-sdk-python/issues/433)) ([6bf9379](https://github.com/anthropics/anthropic-sdk-python/commit/6bf93794127a62a077f2e50a2acfe01464742319)) * **project:** use absolute github links on PyPi ([#427](https://github.com/anthropics/anthropic-sdk-python/issues/427)) ([cbd8b1c](https://github.com/anthropics/anthropic-sdk-python/commit/cbd8b1c789e83d2c84ba10165778e4ad2af1ac20)) * revert regression with 3.7 support ([#419](https://github.com/anthropics/anthropic-sdk-python/issues/419)) ([fa21f36](https://github.com/anthropics/anthropic-sdk-python/commit/fa21f3643714d985b10b45dc8bfc3887ed20eba7)) * **streaming:** correct accumulation of output tokens ([#426](https://github.com/anthropics/anthropic-sdk-python/issues/426)) ([b50ed05](https://github.com/anthropics/anthropic-sdk-python/commit/b50ed05a991f02bccfd9f65a1c59e56540adba08)) ### Chores * **client:** validate that max_retries is not None ([#430](https://github.com/anthropics/anthropic-sdk-python/issues/430)) ([31b2a2f](https://github.com/anthropics/anthropic-sdk-python/commit/31b2a2fd4069a670c795eeaf51b641fbf2097af1)) * **internal:** bump dependencies ([#421](https://github.com/anthropics/anthropic-sdk-python/issues/421)) ([30e8031](https://github.com/anthropics/anthropic-sdk-python/commit/30e8031469a4c4beb0bb906920f53d5d4da2e2c3)) * **internal:** defer model build for import latency ([#431](https://github.com/anthropics/anthropic-sdk-python/issues/431)) ([51d4783](https://github.com/anthropics/anthropic-sdk-python/commit/51d47832ae44415604725bb763cf567fb9dc1b34)) * **internal:** formatting change ([#415](https://github.com/anthropics/anthropic-sdk-python/issues/415)) ([1474f44](https://github.com/anthropics/anthropic-sdk-python/commit/1474f443201949c9b8a7d0a8562968d57d421fb5)) ### Documentation * **contributing:** fix typo ([#414](https://github.com/anthropics/anthropic-sdk-python/issues/414)) ([aeaf995](https://github.com/anthropics/anthropic-sdk-python/commit/aeaf99573a9140b6bb5c0af4cefddbd6f469a6a5)) * **readme:** change undocumented params wording ([#429](https://github.com/anthropics/anthropic-sdk-python/issues/429)) ([1336958](https://github.com/anthropics/anthropic-sdk-python/commit/13369583fc74101e002427079c9871e05e5536e8)) ## 0.21.3 (2024-03-21) Full Changelog: [v0.21.2...v0.21.3](https://github.com/anthropics/anthropic-sdk-python/compare/v0.21.2...v0.21.3) ### Bug Fixes * **types:** correct typo claude-2.1' to claude-2.1 ([#400](https://github.com/anthropics/anthropic-sdk-python/issues/400)) ([7f82aa3](https://github.com/anthropics/anthropic-sdk-python/commit/7f82aa3aa28c7134b69eeb42d5f0b7523c7cb5df)) * **types:** correct typo claude-2.1' to claude-2.1 ([#413](https://github.com/anthropics/anthropic-sdk-python/issues/413)) ([bb1aebe](https://github.com/anthropics/anthropic-sdk-python/commit/bb1aebe6225b7d854b8125344846e77c6e13f3f9)) ## 0.21.2 (2024-03-21) Full Changelog: [v0.21.1...v0.21.2](https://github.com/anthropics/anthropic-sdk-python/compare/v0.21.1...v0.21.2) ### Documentation * **readme:** consistent use of sentence case in headings ([#405](https://github.com/anthropics/anthropic-sdk-python/issues/405)) ([495ca87](https://github.com/anthropics/anthropic-sdk-python/commit/495ca87e95ac645d4f387614adac1a20c26729b9)) * **readme:** document how to make undocumented requests ([#407](https://github.com/anthropics/anthropic-sdk-python/issues/407)) ([b046d0d](https://github.com/anthropics/anthropic-sdk-python/commit/b046d0dd5be5fc9a21f9ac352627b7bb5e2b9ced)) ## 0.21.1 (2024-03-20) Full Changelog: [v0.21.0...v0.21.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.21.0...v0.21.1) ### Chores * **internal:** loosen input type for util function ([#402](https://github.com/anthropics/anthropic-sdk-python/issues/402)) ([9a6ca55](https://github.com/anthropics/anthropic-sdk-python/commit/9a6ca5528ee5b96577df4d657937c35cdc263f85)) ## 0.21.0 (2024-03-19) Full Changelog: [v0.20.0...v0.21.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.20.0...v0.21.0) ### Features * **vertex:** api is no longer in private beta ([#399](https://github.com/anthropics/anthropic-sdk-python/issues/399)) ([4cb0e64](https://github.com/anthropics/anthropic-sdk-python/commit/4cb0e6453ed185646b652b7942ed75f8e49be8e3)) ### Performance Improvements * cache TypeAdapters ([#396](https://github.com/anthropics/anthropic-sdk-python/issues/396)) ([a902c47](https://github.com/anthropics/anthropic-sdk-python/commit/a902c472b986d7c7bfda52fc20d737f0bcf80b6a)) ### Chores * **internal:** update generated pragma comment ([#398](https://github.com/anthropics/anthropic-sdk-python/issues/398)) ([330b61e](https://github.com/anthropics/anthropic-sdk-python/commit/330b61eccfd8af3ee587a91dd2491d66abfe159a)) ### Documentation * fix typo in CONTRIBUTING.md ([#397](https://github.com/anthropics/anthropic-sdk-python/issues/397)) ([d46629f](https://github.com/anthropics/anthropic-sdk-python/commit/d46629f385b65a0c099ca7a94ebaae9bcb0ecb2c)) * **helpers:** fix example code ([#391](https://github.com/anthropics/anthropic-sdk-python/issues/391)) ([9fe0c8b](https://github.com/anthropics/anthropic-sdk-python/commit/9fe0c8b9b257d18e7f5fb7ac03de2073552c083d)) ## 0.20.0 (2024-03-13) Full Changelog: [v0.19.2...v0.20.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.19.2...v0.20.0) ### Features * **api:** add haiku model ([#390](https://github.com/anthropics/anthropic-sdk-python/issues/390)) ([43b57fc](https://github.com/anthropics/anthropic-sdk-python/commit/43b57fca5426774929bfcac81bf00659740db796)) ### Documentation * **readme:** mention vertex API ([#388](https://github.com/anthropics/anthropic-sdk-python/issues/388)) ([8bb6b98](https://github.com/anthropics/anthropic-sdk-python/commit/8bb6b9841db322db8c5e8357c2c379482be15441)) ## 0.19.2 (2024-03-11) Full Changelog: [v0.19.1...v0.19.2](https://github.com/anthropics/anthropic-sdk-python/compare/v0.19.1...v0.19.2) ### Bug Fixes * **vertex:** use correct auth scopes ([#385](https://github.com/anthropics/anthropic-sdk-python/issues/385)) ([e4de056](https://github.com/anthropics/anthropic-sdk-python/commit/e4de056ddc24e2d3d8f742124b0a965ff3404341)) ### Chores * export NOT_GIVEN sentinel value ([#379](https://github.com/anthropics/anthropic-sdk-python/issues/379)) ([ba127bc](https://github.com/anthropics/anthropic-sdk-python/commit/ba127bc44b70490a7c9e8ff76b7a742631e94c5c)) * **internal:** improve deserialisation of discriminated unions ([#386](https://github.com/anthropics/anthropic-sdk-python/issues/386)) ([fbc7e0b](https://github.com/anthropics/anthropic-sdk-python/commit/fbc7e0b2cf5e8f5bcd316393a7483509ed9f790e)) * **internal:** support parsing Annotated types ([#377](https://github.com/anthropics/anthropic-sdk-python/issues/377)) ([f44efd5](https://github.com/anthropics/anthropic-sdk-python/commit/f44efd5a587fca5021bfc2c068a715a7a550a5d0)) ## 0.19.1 (2024-03-06) Full Changelog: [v0.19.0...v0.19.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.19.0...v0.19.1) ### Chores * **internal:** add core support for deserializing into number response ([#373](https://github.com/anthropics/anthropic-sdk-python/issues/373)) ([b62c422](https://github.com/anthropics/anthropic-sdk-python/commit/b62c4224fafe0544877ebb57278526a5ddd1955d)) ## 0.19.0 (2024-03-06) Full Changelog: [v0.18.1...v0.19.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.18.1...v0.19.0) ### Features * **api:** add enum to model param for message ([#371](https://github.com/anthropics/anthropic-sdk-python/issues/371)) ([f96765f](https://github.com/anthropics/anthropic-sdk-python/commit/f96765f188676bb688f599a3574c16dbfb27430c)) ### Chores * **client:** improve error message for invalid http_client argument ([#367](https://github.com/anthropics/anthropic-sdk-python/issues/367)) ([2f4df72](https://github.com/anthropics/anthropic-sdk-python/commit/2f4df724410bc6213bf559739724bec0242becd7)) ### Documentation * **readme:** fix async streaming snippet ([#366](https://github.com/anthropics/anthropic-sdk-python/issues/366)) ([37c469d](https://github.com/anthropics/anthropic-sdk-python/commit/37c469deecad9f6244d42dce7d3cedc289ca129b)) ## 0.18.1 (2024-03-04) Full Changelog: [v0.18.0...v0.18.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.18.0...v0.18.1) ### Chores * **readme:** update bedrock example ([#364](https://github.com/anthropics/anthropic-sdk-python/issues/364)) ([81e4d10](https://github.com/anthropics/anthropic-sdk-python/commit/81e4d10f6b7c5e06d5d2844441350731dbddbfad)) ## 0.18.0 (2024-03-04) Full Changelog: [v0.17.0...v0.18.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.17.0...v0.18.0) ### Features * **bedrock:** add messages API ([#362](https://github.com/anthropics/anthropic-sdk-python/issues/362)) ([5409be9](https://github.com/anthropics/anthropic-sdk-python/commit/5409be98d0fd4e65e6dd766238fc8789efb3cb49)) ### Chores * remove old examples ([4895381](https://github.com/anthropics/anthropic-sdk-python/commit/489538163ada7de07c3f4b5237c551949fee4232)) ## 0.17.0 (2024-03-04) Full Changelog: [v0.16.0...v0.17.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.16.0...v0.17.0) ### Features * **messages:** add support for image inputs ([#359](https://github.com/anthropics/anthropic-sdk-python/issues/359)) ([579f013](https://github.com/anthropics/anthropic-sdk-python/commit/579f013dd294f34b3c44e2b331a4aa25b6cdfd6a)) ### Chores * **client:** use anyio.sleep instead of asyncio.sleep ([#351](https://github.com/anthropics/anthropic-sdk-python/issues/351)) ([2778a22](https://github.com/anthropics/anthropic-sdk-python/commit/2778a2228e82704dde9176d970274e806422c02b)) * **docs:** mention install from git repo ([#356](https://github.com/anthropics/anthropic-sdk-python/issues/356)) ([9d503ba](https://github.com/anthropics/anthropic-sdk-python/commit/9d503ba9cc462e33166594ca19f666819a3a5a87)) * **docs:** remove references to old bedrock package ([#344](https://github.com/anthropics/anthropic-sdk-python/issues/344)) ([3323883](https://github.com/anthropics/anthropic-sdk-python/commit/3323883750b9d61fa084cadc99519b2f6cf8d39c)) * **internal:** bump pyright ([#350](https://github.com/anthropics/anthropic-sdk-python/issues/350)) ([ee0161c](https://github.com/anthropics/anthropic-sdk-python/commit/ee0161c2d7d2fefd06ee5b1001131cd6d6d236d7)) * **internal:** bump rye to v0.24.0 ([#348](https://github.com/anthropics/anthropic-sdk-python/issues/348)) ([be8597b](https://github.com/anthropics/anthropic-sdk-python/commit/be8597b33c2f2f6e8b9ae77738f4c898e48c8e91)) * **internal:** improve bedrock streaming setup ([#354](https://github.com/anthropics/anthropic-sdk-python/issues/354)) ([2b55c68](https://github.com/anthropics/anthropic-sdk-python/commit/2b55c688514e4b13abce547362f0c0a3e7f0e97f)) * **internal:** refactor release environment script ([#347](https://github.com/anthropics/anthropic-sdk-python/issues/347)) ([a87443a](https://github.com/anthropics/anthropic-sdk-python/commit/a87443a90374aedaac80451f61046c6f1aefeaa9)) * **internal:** split up transforms into sync / async ([#357](https://github.com/anthropics/anthropic-sdk-python/issues/357)) ([f55ee71](https://github.com/anthropics/anthropic-sdk-python/commit/f55ee71b0b517f3e605bfd7a4aa948a9c2fc6552)) * **internal:** support more input types ([#358](https://github.com/anthropics/anthropic-sdk-python/issues/358)) ([35b0347](https://github.com/anthropics/anthropic-sdk-python/commit/35b0347bfddecc94fc8ac09b42ff3d96f4523bf8)) * **internal:** update deps ([#349](https://github.com/anthropics/anthropic-sdk-python/issues/349)) ([ab82b2d](https://github.com/anthropics/anthropic-sdk-python/commit/ab82b2d7ce16f3fed4b20e60f0c8e7981c22c191)) ### Documentation * **contributing:** improve wording ([#355](https://github.com/anthropics/anthropic-sdk-python/issues/355)) ([f9093a0](https://github.com/anthropics/anthropic-sdk-python/commit/f9093a0ee8d590185f572749d58280f7eda5ed8b)) ### Refactors * **api:** mark completions API as legacy ([#346](https://github.com/anthropics/anthropic-sdk-python/issues/346)) ([2bb25a1](https://github.com/anthropics/anthropic-sdk-python/commit/2bb25a12509b87557f3da2125ab955b60e32713f)) ## 0.16.0 (2024-02-13) Full Changelog: [v0.15.1...v0.16.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.15.1...v0.16.0) ### Features * **api:** messages is generally available ([#343](https://github.com/anthropics/anthropic-sdk-python/issues/343)) ([f682594](https://github.com/anthropics/anthropic-sdk-python/commit/f6825941acc09b33af386b40718bd2f3c01b29ef)) * **messages:** allow message response in params ([#339](https://github.com/anthropics/anthropic-sdk-python/issues/339)) ([86c63f0](https://github.com/anthropics/anthropic-sdk-python/commit/86c63f0e7441a9fe894b3ae7cd7e871060d5ebbf)) ### Documentation * add CONTRIBUTING.md ([#340](https://github.com/anthropics/anthropic-sdk-python/issues/340)) ([78469ad](https://github.com/anthropics/anthropic-sdk-python/commit/78469ade1658bf6b12b7cb947136e228d6992303)) ## 0.15.1 (2024-02-07) Full Changelog: [v0.15.0...v0.15.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.15.0...v0.15.1) ### Bug Fixes * prevent crash when platform.architecture() is not allowed ([#334](https://github.com/anthropics/anthropic-sdk-python/issues/334)) ([fefb5c1](https://github.com/anthropics/anthropic-sdk-python/commit/fefb5c10c10054f28fcccf0d9f44204de93e9fe3)) * **types:** loosen most List params types to Iterable ([#338](https://github.com/anthropics/anthropic-sdk-python/issues/338)) ([6e7761b](https://github.com/anthropics/anthropic-sdk-python/commit/6e7761b89c9ef226bd8f7df465445526c08fdb2f)) ### Chores * **internal:** add lint command ([#337](https://github.com/anthropics/anthropic-sdk-python/issues/337)) ([2ebaf1d](https://github.com/anthropics/anthropic-sdk-python/commit/2ebaf1d6a85b638b502661735e3ffc5b58d5c241)) * **internal:** support serialising iterable types ([#336](https://github.com/anthropics/anthropic-sdk-python/issues/336)) ([ea3ed7b](https://github.com/anthropics/anthropic-sdk-python/commit/ea3ed7b8b91314721129480d164d7bf3bafec26c)) ## 0.15.0 (2024-02-02) Full Changelog: [v0.14.1...v0.15.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.14.1...v0.15.0) ### Features * **api:** add new usage response fields ([#332](https://github.com/anthropics/anthropic-sdk-python/issues/332)) ([554098e](https://github.com/anthropics/anthropic-sdk-python/commit/554098e544d49575d2d9d24edfb46f2fa0f77ba1)) ## 0.14.1 (2024-02-02) Full Changelog: [v0.14.0...v0.14.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.14.0...v0.14.1) ### Chores * **interal:** make link to api.md relative ([#330](https://github.com/anthropics/anthropic-sdk-python/issues/330)) ([e393317](https://github.com/anthropics/anthropic-sdk-python/commit/e393317362d8cd74442d7a802ea965211c913115)) ## 0.14.0 (2024-01-31) Full Changelog: [v0.13.0...v0.14.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.13.0...v0.14.0) ### Features * **bedrock:** include bedrock SDK ([#328](https://github.com/anthropics/anthropic-sdk-python/issues/328)) ([a03f21f](https://github.com/anthropics/anthropic-sdk-python/commit/a03f21fef1ab3225f9839002b69aa5cb5840b375)) ## 0.13.0 (2024-01-30) Full Changelog: [v0.12.0...v0.13.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.12.0...v0.13.0) ### Features * **client:** support parsing custom response types ([#325](https://github.com/anthropics/anthropic-sdk-python/issues/325)) ([416633f](https://github.com/anthropics/anthropic-sdk-python/commit/416633fedb962d207fb841e80d7d7947fe52bb33)) ### Chores * **internal:** cast type in mocked test ([#326](https://github.com/anthropics/anthropic-sdk-python/issues/326)) ([fd22d8e](https://github.com/anthropics/anthropic-sdk-python/commit/fd22d8e584c5f3d6a029b4b0e87b98827746fda9)) * **internal:** enable ruff type checking misuse lint rule ([#324](https://github.com/anthropics/anthropic-sdk-python/issues/324)) ([6587598](https://github.com/anthropics/anthropic-sdk-python/commit/6587598162387c0aada958df22610a93198e813d)) * **internal:** support multipart data with overlapping keys ([#322](https://github.com/anthropics/anthropic-sdk-python/issues/322)) ([9ecab60](https://github.com/anthropics/anthropic-sdk-python/commit/9ecab6048afeca544146b9629bcdaa5250012cc9)) * **internal:** support pre-release versioning ([#327](https://github.com/anthropics/anthropic-sdk-python/issues/327)) ([78b1bfe](https://github.com/anthropics/anthropic-sdk-python/commit/78b1bfe3e694e0400477fc25ae1aaab34c28e61e)) ## 0.12.0 (2024-01-25) Full Changelog: [v0.11.0...v0.12.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.11.0...v0.12.0) ### Features * **client:** enable follow redirects by default ([#320](https://github.com/anthropics/anthropic-sdk-python/issues/320)) ([9959c32](https://github.com/anthropics/anthropic-sdk-python/commit/9959c32d24acd7199e6ce8124a18bcfa263fac85)) ## 0.11.0 (2024-01-23) Full Changelog: [v0.10.0...v0.11.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.10.0...v0.11.0) ### Features * **vertex:** add support for google vertex ([#319](https://github.com/anthropics/anthropic-sdk-python/issues/319)) ([5324415](https://github.com/anthropics/anthropic-sdk-python/commit/53244155d657e782d4ec9cc85f557233ee3698be)) ### Chores * **internal:** add internal helpers ([#316](https://github.com/anthropics/anthropic-sdk-python/issues/316)) ([8c75cdf](https://github.com/anthropics/anthropic-sdk-python/commit/8c75cdfe5e236c08bb6ecc09e27f69932cc523f1)) * **internal:** update resource client type ([#318](https://github.com/anthropics/anthropic-sdk-python/issues/318)) ([bdd8d84](https://github.com/anthropics/anthropic-sdk-python/commit/bdd8d84023814f390b8f5eca7bd64cb340c1e8a8)) ## 0.10.0 (2024-01-18) Full Changelog: [v0.9.0...v0.10.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.9.0...v0.10.0) ### Features * **client:** add support for streaming raw responses ([#307](https://github.com/anthropics/anthropic-sdk-python/issues/307)) ([f295982](https://github.com/anthropics/anthropic-sdk-python/commit/f2959827fe2cd555db38a62c1b3df1a12e6dee40)) ### Bug Fixes * **ci:** ignore stainless-app edits to release PR title ([#315](https://github.com/anthropics/anthropic-sdk-python/issues/315)) ([69e8b03](https://github.com/anthropics/anthropic-sdk-python/commit/69e8b03cd12e3c12de7c528a0b2c064f709a239a)) ### Chores * add write_to_file binary helper method ([#309](https://github.com/anthropics/anthropic-sdk-python/issues/309)) ([8ac7988](https://github.com/anthropics/anthropic-sdk-python/commit/8ac7988dee11745495290f38fa5a2b8fddd0b993)) * **client:** improve debug logging for failed requests ([#303](https://github.com/anthropics/anthropic-sdk-python/issues/303)) ([5e58c25](https://github.com/anthropics/anthropic-sdk-python/commit/5e58c2537eccadbccef9aadcd6433cf35328e678)) * **internal:** fix typing util function ([#310](https://github.com/anthropics/anthropic-sdk-python/issues/310)) ([3671aa6](https://github.com/anthropics/anthropic-sdk-python/commit/3671aa6b3b05776b727a727020366bb6c349f66a)) * **internal:** remove redundant client test ([#311](https://github.com/anthropics/anthropic-sdk-python/issues/311)) ([d7140f7](https://github.com/anthropics/anthropic-sdk-python/commit/d7140f7c16554dfacdac642173516625f2540496)) * **internal:** share client instances between all tests ([#314](https://github.com/anthropics/anthropic-sdk-python/issues/314)) ([ccf731b](https://github.com/anthropics/anthropic-sdk-python/commit/ccf731b047809264d073f86c08c7f36ee360fda1)) * **internal:** speculative retry-after-ms support ([#312](https://github.com/anthropics/anthropic-sdk-python/issues/312)) ([4b27da9](https://github.com/anthropics/anthropic-sdk-python/commit/4b27da9d05ce90944f566c20b122653adc0b9ab1)) * **internal:** updates to proxy helper ([#308](https://github.com/anthropics/anthropic-sdk-python/issues/308)) ([a0b3cdb](https://github.com/anthropics/anthropic-sdk-python/commit/a0b3cdb655d150d3703f793c82e4a3945f45c82f)) * lazy load raw resource class properties ([#313](https://github.com/anthropics/anthropic-sdk-python/issues/313)) ([b13f824](https://github.com/anthropics/anthropic-sdk-python/commit/b13f8249be1a4f77611598b4cce465481af35d83)) ### Documentation * **readme:** improve api reference ([#306](https://github.com/anthropics/anthropic-sdk-python/issues/306)) ([c3ab836](https://github.com/anthropics/anthropic-sdk-python/commit/c3ab836e4654dff259f19071bf0e1cdff249a268)) ## 0.9.0 (2024-01-08) Full Changelog: [v0.8.1...v0.9.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.8.1...v0.9.0) ### Features * add `None` default value to nullable response properties ([#299](https://github.com/anthropics/anthropic-sdk-python/issues/299)) ([da423db](https://github.com/anthropics/anthropic-sdk-python/commit/da423db5c14b213c52fe0986981c4f01aff0d2c3)) ### Bug Fixes * **client:** correctly use custom http client auth ([#296](https://github.com/anthropics/anthropic-sdk-python/issues/296)) ([6289d6e](https://github.com/anthropics/anthropic-sdk-python/commit/6289d6e205f872c02114f05333d5426055f2416f)) ### Chores * add .keep files for examples and custom code directories ([#302](https://github.com/anthropics/anthropic-sdk-python/issues/302)) ([73a07ea](https://github.com/anthropics/anthropic-sdk-python/commit/73a07ea7a5254d205b68e25c46c1f2267604ac9b)) * **internal:** loosen type var restrictions ([#301](https://github.com/anthropics/anthropic-sdk-python/issues/301)) ([5e5e1e7](https://github.com/anthropics/anthropic-sdk-python/commit/5e5e1e716a8732af66e2234307521b4620b07361)) * **internal:** replace isort with ruff ([#298](https://github.com/anthropics/anthropic-sdk-python/issues/298)) ([7c60904](https://github.com/anthropics/anthropic-sdk-python/commit/7c60904f5da10c4ef6ab8af4e8631bc938b35131)) * use property declarations for resource members ([#300](https://github.com/anthropics/anthropic-sdk-python/issues/300)) ([8671297](https://github.com/anthropics/anthropic-sdk-python/commit/8671297b87105635accefd574c44dbffd8a4f9e9)) ## 0.8.1 (2023-12-22) Full Changelog: [v0.8.0...v0.8.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.8.0...v0.8.1) ### Chores * **internal:** add bin script ([#292](https://github.com/anthropics/anthropic-sdk-python/issues/292)) ([ba2953d](https://github.com/anthropics/anthropic-sdk-python/commit/ba2953dcaa8a8fcebaa7e8891304687c95b17499)) * **internal:** fix typos ([#287](https://github.com/anthropics/anthropic-sdk-python/issues/287)) ([4ffbcdf](https://github.com/anthropics/anthropic-sdk-python/commit/4ffbcdf1d3c8c2fbaf7152d207b24cdb0ea82ac9)) * **internal:** use ruff instead of black for formatting ([#294](https://github.com/anthropics/anthropic-sdk-python/issues/294)) ([1753887](https://github.com/anthropics/anthropic-sdk-python/commit/1753887a776f41bdc2d648329cfe6f20c91125e5)) * **package:** bump minimum typing-extensions to 4.7 ([#290](https://github.com/anthropics/anthropic-sdk-python/issues/290)) ([9ec5c57](https://github.com/anthropics/anthropic-sdk-python/commit/9ec5c57ba9a14a769d540e48755b05a1c190b45b)) ### Documentation * **messages:** improvements to helpers reference + typos ([#291](https://github.com/anthropics/anthropic-sdk-python/issues/291)) ([d18a895](https://github.com/anthropics/anthropic-sdk-python/commit/d18a895d380fc0c6610443486d73247b0cd97376)) * **readme:** remove old migration guide ([#289](https://github.com/anthropics/anthropic-sdk-python/issues/289)) ([eec4574](https://github.com/anthropics/anthropic-sdk-python/commit/eec4574f1f6668804c88bda67b901db10400fbc3)) ## 0.8.0 (2023-12-19) Full Changelog: [v0.7.8...v0.8.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.7.8...v0.8.0) ### Features * **api:** add messages endpoint with streaming helpers ([#286](https://github.com/anthropics/anthropic-sdk-python/issues/286)) ([c464b87](https://github.com/anthropics/anthropic-sdk-python/commit/c464b87b72ebbf9255418a02c627b0f0c52d03dd)) ### Chores * **ci:** run release workflow once per day ([#282](https://github.com/anthropics/anthropic-sdk-python/issues/282)) ([3a23912](https://github.com/anthropics/anthropic-sdk-python/commit/3a239127713c68ae53fa8b338e1f60ca25840a90)) * **client:** only import tokenizers when needed ([#284](https://github.com/anthropics/anthropic-sdk-python/issues/284)) ([b9e38b2](https://github.com/anthropics/anthropic-sdk-python/commit/b9e38b2a2e2be2b5fb31842fa409b95abcbccbc6)) * **streaming:** update constructor to use direct client names ([#285](https://github.com/anthropics/anthropic-sdk-python/issues/285)) ([0c55c84](https://github.com/anthropics/anthropic-sdk-python/commit/0c55c84ab3527199401f387fbc3338572b264fef)) ## 0.7.8 (2023-12-12) Full Changelog: [v0.7.7...v0.7.8](https://github.com/anthropics/anthropic-sdk-python/compare/v0.7.7...v0.7.8) ### Bug Fixes * avoid leaking memory when Client.with_options is used ([#275](https://github.com/anthropics/anthropic-sdk-python/issues/275)) ([5e51ebd](https://github.com/anthropics/anthropic-sdk-python/commit/5e51ebdbc6e5c23c8c237b5e0231ef66f585f964)) * **client:** correct base_url setter implementation ([#265](https://github.com/anthropics/anthropic-sdk-python/issues/265)) ([29d0c8b](https://github.com/anthropics/anthropic-sdk-python/commit/29d0c8b0eb174b499a904e02cce7fe7a6aaa1a01)) * **client:** ensure retried requests are closed ([#261](https://github.com/anthropics/anthropic-sdk-python/issues/261)) ([5d9aa75](https://github.com/anthropics/anthropic-sdk-python/commit/5d9aa754ace5d53eb90c1055dd6b1ca8e7deee4f)) * **errors:** properly assign APIError.body ([#274](https://github.com/anthropics/anthropic-sdk-python/issues/274)) ([342846f](https://github.com/anthropics/anthropic-sdk-python/commit/342846fa4d424a4d18dd2289d2b652bf53c97901)) ### Chores * **internal:** enable more lint rules ([#273](https://github.com/anthropics/anthropic-sdk-python/issues/273)) ([0ac62bc](https://github.com/anthropics/anthropic-sdk-python/commit/0ac62bc127ddf0367561427836ff19c1272fb0e1)) * **internal:** reformat imports ([#270](https://github.com/anthropics/anthropic-sdk-python/issues/270)) ([dc55724](https://github.com/anthropics/anthropic-sdk-python/commit/dc55724673dfa59911a05fe4827b8804beba0b05)) * **internal:** reformat imports ([#272](https://github.com/anthropics/anthropic-sdk-python/issues/272)) ([0d82ce4](https://github.com/anthropics/anthropic-sdk-python/commit/0d82ce4784c3a6c9599e6c09b8190e97ea028dc3)) * **internal:** remove unused file ([#264](https://github.com/anthropics/anthropic-sdk-python/issues/264)) ([1bfc69b](https://github.com/anthropics/anthropic-sdk-python/commit/1bfc69b0e2a1eb79598409cbfcba060f699d28a7)) * **internal:** replace string concatenation with f-strings ([#263](https://github.com/anthropics/anthropic-sdk-python/issues/263)) ([f545c35](https://github.com/anthropics/anthropic-sdk-python/commit/f545c350dd802079d057d34ff29444e32dc7bdcb)) * **internal:** update formatting ([#271](https://github.com/anthropics/anthropic-sdk-python/issues/271)) ([802ab59](https://github.com/anthropics/anthropic-sdk-python/commit/802ab59401b06986b8023e9ef0d0f9e0d6858b86)) * **package:** lift anyio v4 restriction ([#266](https://github.com/anthropics/anthropic-sdk-python/issues/266)) ([a217e99](https://github.com/anthropics/anthropic-sdk-python/commit/a217e9955569852d35ab1bc1351dd66ba807fc44)) ### Documentation * update examples to show claude-2.1 ([#276](https://github.com/anthropics/anthropic-sdk-python/issues/276)) ([8f562f4](https://github.com/anthropics/anthropic-sdk-python/commit/8f562f47f13ffaaab93f08b9b4c59d06e4a18b6c)) ### Refactors * **client:** simplify cleanup ([#278](https://github.com/anthropics/anthropic-sdk-python/issues/278)) ([3611ae2](https://github.com/anthropics/anthropic-sdk-python/commit/3611ae24d93fa33e55f2e9193a3c787bfd041da5)) * simplify internal error handling ([#279](https://github.com/anthropics/anthropic-sdk-python/issues/279)) ([993b51a](https://github.com/anthropics/anthropic-sdk-python/commit/993b51aa4f41bae3938a12d60919065c4865a734)) ## 0.7.7 (2023-11-29) Full Changelog: [v0.7.6...v0.7.7](https://github.com/anthropics/anthropic-sdk-python/compare/v0.7.6...v0.7.7) ### Chores * **internal:** add tests for proxy change ([#260](https://github.com/anthropics/anthropic-sdk-python/issues/260)) ([3b52136](https://github.com/anthropics/anthropic-sdk-python/commit/3b521362f6ee33c3ff66371e4f2d3bdcea2827bb)) * **internal:** updates to proxy helper ([#258](https://github.com/anthropics/anthropic-sdk-python/issues/258)) ([94c4de8](https://github.com/anthropics/anthropic-sdk-python/commit/94c4de88b9d202d780c4dfbee6db138d7a663373)) ## 0.7.6 (2023-11-28) Full Changelog: [v0.7.5...v0.7.6](https://github.com/anthropics/anthropic-sdk-python/compare/v0.7.5...v0.7.6) ### Chores * **deps:** bump mypy to v1.7.1 ([#256](https://github.com/anthropics/anthropic-sdk-python/issues/256)) ([02d4ed8](https://github.com/anthropics/anthropic-sdk-python/commit/02d4ed8ae8e4fb9221fc9bfb5f45357ed239de5e)) ## 0.7.5 (2023-11-24) Full Changelog: [v0.7.4...v0.7.5](https://github.com/anthropics/anthropic-sdk-python/compare/v0.7.4...v0.7.5) ### Chores * **internal:** revert recent options change ([#252](https://github.com/anthropics/anthropic-sdk-python/issues/252)) ([d60d5c3](https://github.com/anthropics/anthropic-sdk-python/commit/d60d5c33aec2964b3dbbc69bdf8556b4100a684f)) * **internal:** send more detailed x-stainless headers ([#254](https://github.com/anthropics/anthropic-sdk-python/issues/254)) ([a268d4b](https://github.com/anthropics/anthropic-sdk-python/commit/a268d4bf4f2fb17707c5328e1ba25e623e7b9b78)) ## 0.7.4 (2023-11-23) Full Changelog: [v0.7.3...v0.7.4](https://github.com/anthropics/anthropic-sdk-python/compare/v0.7.3...v0.7.4) ### Chores * **internal:** options updates ([#248](https://github.com/anthropics/anthropic-sdk-python/issues/248)) ([5a3b236](https://github.com/anthropics/anthropic-sdk-python/commit/5a3b2362af3b7556babb99095df88443c56579ec)) ## 0.7.3 (2023-11-21) Full Changelog: [v0.7.2...v0.7.3](https://github.com/anthropics/anthropic-sdk-python/compare/v0.7.2...v0.7.3) ### Bug Fixes * **client:** attempt to parse unknown json content types ([#243](https://github.com/anthropics/anthropic-sdk-python/issues/243)) ([9fc275f](https://github.com/anthropics/anthropic-sdk-python/commit/9fc275f606b52690d5ccda78c72a6fded68ccb1e)) ### Chores * **client:** improve copy method ([#246](https://github.com/anthropics/anthropic-sdk-python/issues/246)) ([c84563f](https://github.com/anthropics/anthropic-sdk-python/commit/c84563fc69554b322d2a4254b6470ba7819689c3)) * **package:** add license classifier metadata ([#247](https://github.com/anthropics/anthropic-sdk-python/issues/247)) ([500d0ca](https://github.com/anthropics/anthropic-sdk-python/commit/500d0ca1e4d08f8c6b5d58071f438de9e1a31217)) ## 0.7.2 (2023-11-17) Full Changelog: [v0.7.1...v0.7.2](https://github.com/anthropics/anthropic-sdk-python/compare/v0.7.1...v0.7.2) ### Chores * **internal:** update type hint for helper function ([#241](https://github.com/anthropics/anthropic-sdk-python/issues/241)) ([3179104](https://github.com/anthropics/anthropic-sdk-python/commit/31791042c52e825d1763123b14f44b9e68cc3466)) ## 0.7.1 (2023-11-16) Full Changelog: [v0.7.0...v0.7.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.7.0...v0.7.1) ### Documentation * **readme:** minor updates ([#238](https://github.com/anthropics/anthropic-sdk-python/issues/238)) ([c40c4e1](https://github.com/anthropics/anthropic-sdk-python/commit/c40c4e1c9979f62a485df52bf51a5d730c3af38f)) ## 0.7.0 (2023-11-15) Full Changelog: [v0.6.0...v0.7.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.6.0...v0.7.0) ### Features * **client:** support reading the base url from an env variable ([#237](https://github.com/anthropics/anthropic-sdk-python/issues/237)) ([dd91bfd](https://github.com/anthropics/anthropic-sdk-python/commit/dd91bfd278f4e2e76b2f194098f34070fd5a3ff9)) ### Bug Fixes * **client:** correctly flush the stream response body ([#230](https://github.com/anthropics/anthropic-sdk-python/issues/230)) ([a60d543](https://github.com/anthropics/anthropic-sdk-python/commit/a60d54331f8f6d28bf57dc979d4393759f5e1534)) * **client:** retry if SSLWantReadError occurs in the async client ([#233](https://github.com/anthropics/anthropic-sdk-python/issues/233)) ([33b553a](https://github.com/anthropics/anthropic-sdk-python/commit/33b553a8de5d45273ca9f335c59a263136385f14)) * **client:** serialise pydantic v1 default fields correctly in params ([#232](https://github.com/anthropics/anthropic-sdk-python/issues/232)) ([d5e70e8](https://github.com/anthropics/anthropic-sdk-python/commit/d5e70e8b803c96c8640508b31773b8b9d827d903)) * **models:** mark unknown fields as set in pydantic v1 ([#231](https://github.com/anthropics/anthropic-sdk-python/issues/231)) ([4ce7a1e](https://github.com/anthropics/anthropic-sdk-python/commit/4ce7a1e676023984be80fe0eacb1a0223780886c)) ### Chores * **internal:** fix devcontainer interpeter path ([#235](https://github.com/anthropics/anthropic-sdk-python/issues/235)) ([7f92e25](https://github.com/anthropics/anthropic-sdk-python/commit/7f92e25d6fa15bed799994d173ad62bcf60e5b3b)) * **internal:** fix typo in NotGiven docstring ([#234](https://github.com/anthropics/anthropic-sdk-python/issues/234)) ([ce5cccc](https://github.com/anthropics/anthropic-sdk-python/commit/ce5cccc9bc8482e4e3f6af034892a347eb2b52fc)) ### Documentation * fix code comment typo ([#236](https://github.com/anthropics/anthropic-sdk-python/issues/236)) ([7ef0464](https://github.com/anthropics/anthropic-sdk-python/commit/7ef0464724346d930ff1580526fd70b592759641)) * reword package description ([#228](https://github.com/anthropics/anthropic-sdk-python/issues/228)) ([c18e5ed](https://github.com/anthropics/anthropic-sdk-python/commit/c18e5ed77700bc98ba1c85638a503e9e0a35afb7)) ## 0.6.0 (2023-11-08) Full Changelog: [v0.5.1...v0.6.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.5.1...v0.6.0) ### Features * **client:** adjust retry behavior to be exponential backoff ([#205](https://github.com/anthropics/anthropic-sdk-python/issues/205)) ([c8a4119](https://github.com/anthropics/anthropic-sdk-python/commit/c8a4119661c8ff74c7efa308963c2f187728a46f)) * **client:** allow binary returns ([#217](https://github.com/anthropics/anthropic-sdk-python/issues/217)) ([159ddd6](https://github.com/anthropics/anthropic-sdk-python/commit/159ddd69e6c438baf9abb1e518d0c2467c8f952c)) * **client:** improve file upload types ([#204](https://github.com/anthropics/anthropic-sdk-python/issues/204)) ([d85d1e0](https://github.com/anthropics/anthropic-sdk-python/commit/d85d1e04e36a90d43d134992ff4a5b1589aa6e0a)) * **client:** support accessing raw response objects ([#211](https://github.com/anthropics/anthropic-sdk-python/issues/211)) ([ebe8e4a](https://github.com/anthropics/anthropic-sdk-python/commit/ebe8e4a274f21d73cbc2fbb94fe56172f335cbd2)) * **client:** support passing BaseModels to request params at runtime ([#218](https://github.com/anthropics/anthropic-sdk-python/issues/218)) ([9f04ea6](https://github.com/anthropics/anthropic-sdk-python/commit/9f04ea6cf4a68e2ce65e8e00448b4d3de18a8dec)) * **client:** support passing chunk size for binary responses ([#227](https://github.com/anthropics/anthropic-sdk-python/issues/227)) ([c88f01e](https://github.com/anthropics/anthropic-sdk-python/commit/c88f01ed17b505e3e8a30c8a6adc9231e096b3e2)) * **client:** support passing httpx.Timeout to method timeout argument ([#222](https://github.com/anthropics/anthropic-sdk-python/issues/222)) ([ef58166](https://github.com/anthropics/anthropic-sdk-python/commit/ef58166e0fac68256ca8154792d2157698ed6a9d)) * **github:** include a devcontainer setup ([#216](https://github.com/anthropics/anthropic-sdk-python/issues/216)) ([c9fee19](https://github.com/anthropics/anthropic-sdk-python/commit/c9fee192863fa5f894035ce3e1cf52a78b56895d)) * **package:** add classifiers ([#214](https://github.com/anthropics/anthropic-sdk-python/issues/214)) ([380967e](https://github.com/anthropics/anthropic-sdk-python/commit/380967e515279482e7a93570f172f52324f8aa26)) ### Bug Fixes * **binaries:** don't synchronously block in astream_to_file ([#219](https://github.com/anthropics/anthropic-sdk-python/issues/219)) ([2a2a617](https://github.com/anthropics/anthropic-sdk-python/commit/2a2a617d6862eb83b8a671acad08825c3a20d11b)) * prevent TypeError in Python 3.8 (ABC is not subscriptable) ([#221](https://github.com/anthropics/anthropic-sdk-python/issues/221)) ([893e885](https://github.com/anthropics/anthropic-sdk-python/commit/893e885859b5fb94d7673bfa9ad0a04434fec196)) ### Chores * **docs:** fix github links ([#225](https://github.com/anthropics/anthropic-sdk-python/issues/225)) ([dfa9935](https://github.com/anthropics/anthropic-sdk-python/commit/dfa99352291b15b8c885eb558c8b738b26d33373)) * **internal:** fix some typos ([#223](https://github.com/anthropics/anthropic-sdk-python/issues/223)) ([9038193](https://github.com/anthropics/anthropic-sdk-python/commit/9038193db52612f756194fd735aab899bed0931f)) * **internal:** improve github devcontainer setup ([#226](https://github.com/anthropics/anthropic-sdk-python/issues/226)) ([3cd90ab](https://github.com/anthropics/anthropic-sdk-python/commit/3cd90abe2c57375438a4209e31253f758f408b17)) * **internal:** minor restructuring of base client ([#213](https://github.com/anthropics/anthropic-sdk-python/issues/213)) ([60dc609](https://github.com/anthropics/anthropic-sdk-python/commit/60dc609aa9c4b01b88d9c7e8d1eb35bf9561f210)) * **internal:** remove unused int/float conversion ([#220](https://github.com/anthropics/anthropic-sdk-python/issues/220)) ([a6bf20d](https://github.com/anthropics/anthropic-sdk-python/commit/a6bf20d8cb64f13618c3122f8285d240840884f8)) * **internal:** require explicit overrides ([#210](https://github.com/anthropics/anthropic-sdk-python/issues/210)) ([72f4339](https://github.com/anthropics/anthropic-sdk-python/commit/72f4339749f144e75e0e7dc0a7b2bb26f728044e)) ### Documentation * fix github links ([#215](https://github.com/anthropics/anthropic-sdk-python/issues/215)) ([8cbed15](https://github.com/anthropics/anthropic-sdk-python/commit/8cbed150d6e8f6ac8de8962e169ca46cdd0643c5)) * improve to dictionary example ([#207](https://github.com/anthropics/anthropic-sdk-python/issues/207)) ([5e32c20](https://github.com/anthropics/anthropic-sdk-python/commit/5e32c201f7017c2d4aa7416d1a7de3f0c5247fcc)) ## 0.5.1 (2023-10-20) Full Changelog: [v0.5.0...v0.5.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.5.0...v0.5.1) ### Chores * **internal:** bump mypy ([#203](https://github.com/anthropics/anthropic-sdk-python/issues/203)) ([aa9a67e](https://github.com/anthropics/anthropic-sdk-python/commit/aa9a67e9286146e088af74ded73e3b4d6dde9c7b)) * **internal:** bump pyright ([#202](https://github.com/anthropics/anthropic-sdk-python/issues/202)) ([f96f5f7](https://github.com/anthropics/anthropic-sdk-python/commit/f96f5f75e4b54481bceb033f432f2911355f02e4)) * **internal:** update gitignore ([#199](https://github.com/anthropics/anthropic-sdk-python/issues/199)) ([b92fa57](https://github.com/anthropics/anthropic-sdk-python/commit/b92fa57ac997d80166dd758e1bc9bb58b217c572)) ## 0.5.0 (2023-10-18) Full Changelog: [v0.4.1...v0.5.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.4.1...v0.5.0) ### Features * **client:** support passing httpx.URL instances to base_url ([#197](https://github.com/anthropics/anthropic-sdk-python/issues/197)) ([fe61308](https://github.com/anthropics/anthropic-sdk-python/commit/fe61308baa7d11993e72b3a282633a24fb4e61e4)) ### Chores * **internal:** improve publish script ([#196](https://github.com/anthropics/anthropic-sdk-python/issues/196)) ([7c92b90](https://github.com/anthropics/anthropic-sdk-python/commit/7c92b90864f9510e7cbb68c6b703eec7fd4b7b28)) * **internal:** migrate from Poetry to Rye ([#194](https://github.com/anthropics/anthropic-sdk-python/issues/194)) ([1dd605e](https://github.com/anthropics/anthropic-sdk-python/commit/1dd605e7daf6f8542cb0ff5f5af4f161153f239a)) * **internal:** update gitignore ([#198](https://github.com/anthropics/anthropic-sdk-python/issues/198)) ([4c210b7](https://github.com/anthropics/anthropic-sdk-python/commit/4c210b75ce9fee9a781fbcbab8711409de2d9eea)) ## 0.4.1 (2023-10-16) Full Changelog: [v0.4.0...v0.4.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.4.0...v0.4.1) ### Bug Fixes * **client:** accept io.IOBase instances in file params ([#190](https://github.com/anthropics/anthropic-sdk-python/issues/190)) ([5da5f0c](https://github.com/anthropics/anthropic-sdk-python/commit/5da5f0cbfddfc04fc3b1c86dcbd04aa9d5f1b1e4)) * **streaming:** add additional overload for ambiguous stream param ([#185](https://github.com/anthropics/anthropic-sdk-python/issues/185)) ([794dc4d](https://github.com/anthropics/anthropic-sdk-python/commit/794dc4daa1c7ccea4157eed725e47409fe7f23dc)) ### Chores * **internal:** cleanup some redundant code ([#188](https://github.com/anthropics/anthropic-sdk-python/issues/188)) ([cb0bd8c](https://github.com/anthropics/anthropic-sdk-python/commit/cb0bd8c4e7f311c547674ee3c39dec23829e9422)) * **internal:** enable lint rule ([#187](https://github.com/anthropics/anthropic-sdk-python/issues/187)) ([123b5c1](https://github.com/anthropics/anthropic-sdk-python/commit/123b5c196ef87b4293fb5cbee2c6f3e6da739df8)) ### Documentation * organisation -> organization (UK to US English) ([#192](https://github.com/anthropics/anthropic-sdk-python/issues/192)) ([901a330](https://github.com/anthropics/anthropic-sdk-python/commit/901a33004bcf9d2ff10c742924a70a919ae1cfef)) ## 0.4.0 (2023-10-13) Full Changelog: [v0.3.14...v0.4.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.3.14...v0.4.0) ### Features * **client:** add logging setup ([#177](https://github.com/anthropics/anthropic-sdk-python/issues/177)) ([a5f87ad](https://github.com/anthropics/anthropic-sdk-python/commit/a5f87ad433ab8332b7c253160bedba0adcc2b3e2)) ### Bug Fixes * **client:** correctly handle arguments with env vars ([#178](https://github.com/anthropics/anthropic-sdk-python/issues/178)) ([91a0e2a](https://github.com/anthropics/anthropic-sdk-python/commit/91a0e2a9e436f47f46e36c7072c917a62a08ce16)) ### Chores * add case insensitive get header function ([#182](https://github.com/anthropics/anthropic-sdk-python/issues/182)) ([708fd02](https://github.com/anthropics/anthropic-sdk-python/commit/708fd027b113911f2e1801c4213f6700a9399aa7)) * update comment ([#183](https://github.com/anthropics/anthropic-sdk-python/issues/183)) ([649d6f4](https://github.com/anthropics/anthropic-sdk-python/commit/649d6f468a09648e91ae69cbc07420f055029edf)) * update README ([#174](https://github.com/anthropics/anthropic-sdk-python/issues/174)) ([bb581b5](https://github.com/anthropics/anthropic-sdk-python/commit/bb581b585e776dee50d05f3fcd2853483c3c2ac1)) ### Documentation * minor readme reordering ([#180](https://github.com/anthropics/anthropic-sdk-python/issues/180)) ([92345e3](https://github.com/anthropics/anthropic-sdk-python/commit/92345e31eca3036ab571c57f8c76424a578b55f4)) ### Refactors * **test:** refactor authentication tests ([#175](https://github.com/anthropics/anthropic-sdk-python/issues/175)) ([c82da53](https://github.com/anthropics/anthropic-sdk-python/commit/c82da53502dbb884fc92f1da094a968c9237927b)) ## 0.3.14 (2023-10-11) Full Changelog: [v0.3.13...v0.3.14](https://github.com/anthropics/anthropic-sdk-python/compare/v0.3.13...v0.3.14) ### Features * **client:** add forwards-compatible pydantic methods ([#171](https://github.com/anthropics/anthropic-sdk-python/issues/171)) ([4c5289e](https://github.com/anthropics/anthropic-sdk-python/commit/4c5289eb8519ca9a53e9483422237aa25944f8d8)) * **client:** add support for passing in a httpx client ([#173](https://github.com/anthropics/anthropic-sdk-python/issues/173)) ([25046c4](https://github.com/anthropics/anthropic-sdk-python/commit/25046c4fbc6f9d343e3b1f21024cf3982ac48c35)) * **client:** handle retry-after header with a date format ([#168](https://github.com/anthropics/anthropic-sdk-python/issues/168)) ([afeabf1](https://github.com/anthropics/anthropic-sdk-python/commit/afeabf13aa5795a7fadd141e53ec81eadbce099a)) * **client:** retry on 408 Request Timeout ([#155](https://github.com/anthropics/anthropic-sdk-python/issues/155)) ([46386f8](https://github.com/anthropics/anthropic-sdk-python/commit/46386f8f60223f45bc133ddfcfda8d9ca9da26a8)) * **package:** export a root error type ([#163](https://github.com/anthropics/anthropic-sdk-python/issues/163)) ([e7aa3e7](https://github.com/anthropics/anthropic-sdk-python/commit/e7aa3e7785ae511fa35a68ac72079a6230ca84f3)) * **types:** improve params type names ([#160](https://github.com/anthropics/anthropic-sdk-python/issues/160)) ([43544a6](https://github.com/anthropics/anthropic-sdk-python/commit/43544a62c8410061c1a50282f4c45d029db7779b)) ### Bug Fixes * **client:** don't error by default for unexpected content types ([#161](https://github.com/anthropics/anthropic-sdk-python/issues/161)) ([76cfcf9](https://github.com/anthropics/anthropic-sdk-python/commit/76cfcf91172f9804056a7d5c1ec99666ad5991a2)) * **client:** properly configure model set fields ([#154](https://github.com/anthropics/anthropic-sdk-python/issues/154)) ([da6ccb1](https://github.com/anthropics/anthropic-sdk-python/commit/da6ccb10a38e862153871a540cb75af0afdaefb3)) ### Chores * **internal:** add helpers ([#156](https://github.com/anthropics/anthropic-sdk-python/issues/156)) ([00f5a19](https://github.com/anthropics/anthropic-sdk-python/commit/00f5a19c9393f6238759faea40405e60b2054da3)) * **internal:** move error classes from _base_exceptions to _exceptions (⚠️ breaking) ([#162](https://github.com/anthropics/anthropic-sdk-python/issues/162)) ([329b307](https://github.com/anthropics/anthropic-sdk-python/commit/329b307c205435d367c0d4b29b252be807c61c68)) * **tests:** improve raw response test ([#166](https://github.com/anthropics/anthropic-sdk-python/issues/166)) ([8042473](https://github.com/anthropics/anthropic-sdk-python/commit/8042473bd73faa0b819c27a68bfc19b918361461)) ### Documentation * add some missing inline documentation ([#151](https://github.com/anthropics/anthropic-sdk-python/issues/151)) ([1f98257](https://github.com/anthropics/anthropic-sdk-python/commit/1f9825775d58ed8a62b000caaddd622ed4ba3fd2)) * update readme ([#172](https://github.com/anthropics/anthropic-sdk-python/issues/172)) ([351095b](https://github.com/anthropics/anthropic-sdk-python/commit/351095b189b111a74e9e1825ce5b6da6673a1635)) ## 0.3.13 (2023-09-11) Full Changelog: [v0.3.12...v0.3.13](https://github.com/anthropics/anthropic-sdk-python/compare/v0.3.12...v0.3.13) ### Features * **types:** de-duplicate nested streaming params types ([#141](https://github.com/anthropics/anthropic-sdk-python/issues/141)) ([f76f053](https://github.com/anthropics/anthropic-sdk-python/commit/f76f05320df3059d57ed57153f30be3a8d91fddf)) ### Bug Fixes * **client:** properly handle optional file params ([#142](https://github.com/anthropics/anthropic-sdk-python/issues/142)) ([11196b7](https://github.com/anthropics/anthropic-sdk-python/commit/11196b757c4ef334f8b6db069ecfc6a57c200389)) ### Chores * **internal:** add `pydantic.generics` import for compatibility ([#135](https://github.com/anthropics/anthropic-sdk-python/issues/135)) ([951446d](https://github.com/anthropics/anthropic-sdk-python/commit/951446dbd48e0e5b674fd988865f3aef60c86720)) * **internal:** minor restructuring ([#137](https://github.com/anthropics/anthropic-sdk-python/issues/137)) ([e601206](https://github.com/anthropics/anthropic-sdk-python/commit/e60120670adbc404b06b0fef9e40134929bc7bbd)) * **internal:** minor update ([#145](https://github.com/anthropics/anthropic-sdk-python/issues/145)) ([6a505ef](https://github.com/anthropics/anthropic-sdk-python/commit/6a505ef95523b725a8fdcba71faf9719292e5085)) * **internal:** update base client ([#143](https://github.com/anthropics/anthropic-sdk-python/issues/143)) ([8e0dca4](https://github.com/anthropics/anthropic-sdk-python/commit/8e0dca4fe290833f2aa8b25d6c80b0154ea2a703)) * **internal:** update lock file ([#147](https://github.com/anthropics/anthropic-sdk-python/issues/147)) ([a72b5ca](https://github.com/anthropics/anthropic-sdk-python/commit/a72b5ca4caa8963961d97e5d689393953e00c49b)) * **internal:** update pyright ([#149](https://github.com/anthropics/anthropic-sdk-python/issues/149)) ([9661f94](https://github.com/anthropics/anthropic-sdk-python/commit/9661f941ede82f0023c47b0d9c9beacbd5bbb703)) * **internal:** updates ([#148](https://github.com/anthropics/anthropic-sdk-python/issues/148)) ([9f7fbbc](https://github.com/anthropics/anthropic-sdk-python/commit/9f7fbbcd36ed2accb3a59275255f84200ab17b66)) ### Documentation * **readme:** add link to api.md ([#146](https://github.com/anthropics/anthropic-sdk-python/issues/146)) ([1fcb30a](https://github.com/anthropics/anthropic-sdk-python/commit/1fcb30ae85153d4ab34935a86dcaf0d0fc4470e9)) * **readme:** reference pydantic helpers ([#138](https://github.com/anthropics/anthropic-sdk-python/issues/138)) ([ccaab99](https://github.com/anthropics/anthropic-sdk-python/commit/ccaab990df18404db636f206575ed0548e9420e9)) ## 0.3.12 (2023-08-29) Full Changelog: [v0.3.11...v0.3.12](https://github.com/anthropics/anthropic-sdk-python/compare/v0.3.11...v0.3.12) ### Chores * **ci:** setup workflows to create releases and release PRs ([#130](https://github.com/anthropics/anthropic-sdk-python/issues/130)) ([8f1048b](https://github.com/anthropics/anthropic-sdk-python/commit/8f1048b0f25116ecf4cdedec651a5f8f38fe0d72)) * **internal:** use shared params references ([#133](https://github.com/anthropics/anthropic-sdk-python/issues/133)) ([feaf6aa](https://github.com/anthropics/anthropic-sdk-python/commit/feaf6aa84e83a12e2bd51d78141c2626bfd228e6)) ## [0.3.11](https://github.com/anthropics/anthropic-sdk-python/compare/v0.3.10...v0.3.11) (2023-08-26) ### Documentation * **readme:** make print statements in streaming examples flush ([#123](https://github.com/anthropics/anthropic-sdk-python/issues/123)) ([d24dfaf](https://github.com/anthropics/anthropic-sdk-python/commit/d24dfaffbfd7e82c20c7d846eeddd2af1404e26b)) ### Chores * **internal:** update anyio ([#125](https://github.com/anthropics/anthropic-sdk-python/issues/125)) ([34c7fa1](https://github.com/anthropics/anthropic-sdk-python/commit/34c7fa16006cb2842ccc59c416441b930ed855e7)) ## [0.3.10](https://github.com/anthropics/anthropic-sdk-python/compare/v0.3.9...v0.3.10) (2023-08-16) ### Features * add support for Pydantic v2 ([#121](https://github.com/anthropics/anthropic-sdk-python/issues/121)) ([cafa9be](https://github.com/anthropics/anthropic-sdk-python/commit/cafa9beef10afcec8cc537946c0ee5574f1c96e7)) * allow a default timeout to be set for clients ([#117](https://github.com/anthropics/anthropic-sdk-python/issues/117)) ([a115d2c](https://github.com/anthropics/anthropic-sdk-python/commit/a115d2c978ee6bbe749c55851833e52b8671e343)) ### Chores * assign default reviewers to release PRs ([#119](https://github.com/anthropics/anthropic-sdk-python/issues/119)) ([029a9e1](https://github.com/anthropics/anthropic-sdk-python/commit/029a9e157a4831203f0599d25a223a775fb937a6)) * **internal:** minor formatting change ([#120](https://github.com/anthropics/anthropic-sdk-python/issues/120)) ([7f2f54a](https://github.com/anthropics/anthropic-sdk-python/commit/7f2f54a76dbf182ce13a8d36741421a9c5cf2001)) ## [0.3.9](https://github.com/anthropics/anthropic-sdk-python/compare/v0.3.8...v0.3.9) (2023-08-12) ### Features * **docs:** remove extraneous space in examples ([#109](https://github.com/anthropics/anthropic-sdk-python/issues/109)) ([6d5c1f7](https://github.com/anthropics/anthropic-sdk-python/commit/6d5c1f72aea3156a4773ffb25ac00cdd75191652)) ### Bug Fixes * **docs:** correct async imports ([1ea1bf3](https://github.com/anthropics/anthropic-sdk-python/commit/1ea1bf342c8d54ff9c37ba1d1c591b4fd3362868)) ### Documentation * **readme:** remove beta status + document versioning policy ([#102](https://github.com/anthropics/anthropic-sdk-python/issues/102)) ([2f0a0f9](https://github.com/anthropics/anthropic-sdk-python/commit/2f0a0f9aeac863c18cfc9fff83b3c7675447f408)) ### Chores * **deps:** bump typing-extensions to 4.5 ([#112](https://github.com/anthropics/anthropic-sdk-python/issues/112)) ([f903269](https://github.com/anthropics/anthropic-sdk-python/commit/f9032699e6610363f0490026fb65e05f2283f782)) * **docs:** remove trailing spaces ([#113](https://github.com/anthropics/anthropic-sdk-python/issues/113)) ([e876a6b](https://github.com/anthropics/anthropic-sdk-python/commit/e876a6b957aa2f73f63b4b314942461e4f72de57)) * **internal:** bump pytest-asyncio ([#114](https://github.com/anthropics/anthropic-sdk-python/issues/114)) ([679ecd0](https://github.com/anthropics/anthropic-sdk-python/commit/679ecd0c3c365c70c1c677e5b7e33281cf36fafe)) * **internal:** update mypy to v1.4.1 ([#100](https://github.com/anthropics/anthropic-sdk-python/issues/100)) ([f615753](https://github.com/anthropics/anthropic-sdk-python/commit/f615753a4b6413f1e6af69e3698d19e74bafcdca)) * **internal:** update ruff to v0.0.282 ([#103](https://github.com/anthropics/anthropic-sdk-python/issues/103)) ([9db4b34](https://github.com/anthropics/anthropic-sdk-python/commit/9db4b34844c5bfee65ab4e1ad448ae13d6469e5f)) ## [0.3.8](https://github.com/anthropics/anthropic-sdk-python/compare/v0.3.7...v0.3.8) (2023-08-01) ### Features * **client:** add constants to client instances as well ([#95](https://github.com/anthropics/anthropic-sdk-python/issues/95)) ([d0fbe33](https://github.com/anthropics/anthropic-sdk-python/commit/d0fbe33bd9bab72438c2b80b48b80908bd994797)) ### Chores * **internal:** bump pyright ([#94](https://github.com/anthropics/anthropic-sdk-python/issues/94)) ([d2872dc](https://github.com/anthropics/anthropic-sdk-python/commit/d2872dcc19c409cb7383e70f0472378a0ae86ff0)) * **internal:** make demo example runnable and more portable ([#92](https://github.com/anthropics/anthropic-sdk-python/issues/92)) ([dea1aa2](https://github.com/anthropics/anthropic-sdk-python/commit/dea1aa2f4b699043780b61d92e93c0f2a8fe59bd)) ### Documentation * **readme:** add token counting reference ([#96](https://github.com/anthropics/anthropic-sdk-python/issues/96)) ([79a339e](https://github.com/anthropics/anthropic-sdk-python/commit/79a339e962aa51cf79064af787ce11bd7984e0e4)) ## [0.3.7](https://github.com/anthropics/anthropic-sdk-python/compare/v0.3.6...v0.3.7) (2023-07-29) ### Features * **client:** add client close handlers ([#89](https://github.com/anthropics/anthropic-sdk-python/issues/89)) ([2520a03](https://github.com/anthropics/anthropic-sdk-python/commit/2520a034eed3e218f25f369783ebd09e2763e803)) ### Bug Fixes * **client:** correctly handle environment variable access ([aa53754](https://github.com/anthropics/anthropic-sdk-python/commit/aa53754c71cdfc31f236b41222752f3a58602061)) ### Documentation * **readme:** use `client` everywhere for consistency ([0ff8924](https://github.com/anthropics/anthropic-sdk-python/commit/0ff89245f4aa7ca3f6282827ab7c5cca3be534fb)) ### Chores * **internal:** minor refactoring of client instantiation ([adf9158](https://github.com/anthropics/anthropic-sdk-python/commit/adf91584ade62e3a4c2fbef011a62cf9284db931)) * **internal:** minor reformatting of code ([#90](https://github.com/anthropics/anthropic-sdk-python/issues/90)) ([1175572](https://github.com/anthropics/anthropic-sdk-python/commit/1175572db453b681b5aa8469d09f9400ddcd4946)) ## [0.3.6](https://github.com/anthropics/anthropic-sdk-python/compare/v0.3.5...v0.3.6) (2023-07-22) ### Documentation * **readme:** reference "client" in errors section and add missing import ([#79](https://github.com/anthropics/anthropic-sdk-python/issues/79)) ([ddc81cf](https://github.com/anthropics/anthropic-sdk-python/commit/ddc81cf0c1593ed9d4855e27fbcc0a393cf2c3a2)) ## [0.3.5](https://github.com/anthropics/anthropic-sdk-python/compare/v0.3.4...v0.3.5) (2023-07-19) ### Features * add flexible enum to model param ([#75](https://github.com/anthropics/anthropic-sdk-python/issues/75)) ([d16bb45](https://github.com/anthropics/anthropic-sdk-python/commit/d16bb45c49f4f401bd33ab57d5f9a586bd1e9a01)) ### Documentation * **examples:** bump model to claude-2 in example scripts ([#67](https://github.com/anthropics/anthropic-sdk-python/issues/67)) ([cd68de2](https://github.com/anthropics/anthropic-sdk-python/commit/cd68de2c5351fca85784e44d6eee5d90c835f64b)) ### Chores * **internal:** add `codegen.log` to `.gitignore` ([#72](https://github.com/anthropics/anthropic-sdk-python/issues/72)) ([d9b7e30](https://github.com/anthropics/anthropic-sdk-python/commit/d9b7e30b26235860fe9e7e3053171615173e32ca)) ## [0.3.4](https://github.com/anthropics/anthropic-sdk-python/compare/v0.3.3...v0.3.4) (2023-07-11) ### Chores * **package:** pin major versions of dependencies ([#59](https://github.com/anthropics/anthropic-sdk-python/issues/59)) ([3a75464](https://github.com/anthropics/anthropic-sdk-python/commit/3a754645aa7381d160e985451f385ce231a66904)) ### Documentation * **api:** reference claude-2 ([#61](https://github.com/anthropics/anthropic-sdk-python/issues/61)) ([91ece29](https://github.com/anthropics/anthropic-sdk-python/commit/91ece29cd6ae9ba9a060bee8b55fb62ddc1b69ac)) * **readme:** update examples to use claude-2 ([#65](https://github.com/anthropics/anthropic-sdk-python/issues/65)) ([7e4714c](https://github.com/anthropics/anthropic-sdk-python/commit/7e4714c19a64b2da74531ee7c051a5eef55d693c)) anthropic-sdk-python-0.69.0/CONTRIBUTING.md000066400000000000000000000070151506653454500201440ustar00rootroot00000000000000## Setting up the environment ### With `uv` 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 uv manually](https://docs.astral.sh/uv/getting-started/installation/) and run: ```sh $ uv sync --all-extras ``` You can then run scripts using `uv run python script.py` or by manually activating the virtual environment: ```sh # manually activate - https://docs.python.org/3/library/venv.html#how-venvs-work $ source .venv/bin/activate # now you can omit the `uv run` prefix $ python script.py ``` ### Without `uv` 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 ``` ## Modifying/Adding code Most of the SDK is generated code. Modifications to code will be persisted between generations, but may result in merge conflicts between manual patches and changes from the generator. The generator will never modify the contents of the `src/anthropic/lib/` and `examples/` directories. ## Adding and running examples All files in the `examples/` directory are not modified by the generator and can be freely edited or added to. ```py # add an example to examples/.py #!/usr/bin/env -S uv run python … ``` ```sh $ chmod +x examples/.py # run the example against your api $ ./examples/.py ``` ## Using the repository from source If you’d like to use the repository from source, you can either install from git or link to a cloned repository: To install via git: ```sh $ pip install git+ssh://git@github.com/anthropics/anthropic-sdk-python.git ``` Alternatively, you can build from source and install the wheel file: Building this package will create two files in the `dist/` directory, a `.tar.gz` containing the source files and a `.whl` that can be used to install the package efficiently. To create a distributable version of the library, all you have to do is run this command: ```sh $ uv build # or $ python -m build ``` Then to install: ```sh $ 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. ```sh # you will need npm installed $ npx prism mock path/to/your/openapi.yml ``` ```sh $ ./scripts/test ``` ## Linting and formatting This repository uses [ruff](https://github.com/astral-sh/ruff) and [black](https://github.com/psf/black) to format the code in the repository. To lint: ```sh $ ./scripts/lint ``` To format and fix all ruff issues automatically: ```sh $ ./scripts/format ``` ## Publishing and releases Changes made to this repository via the automated release PR pipeline should publish to PyPI automatically. If the changes aren't made through the automated pipeline, you may want to make releases manually. ### Publish with a GitHub workflow You can release to package managers by using [the `Publish PyPI` GitHub action](https://www.github.com/anthropics/anthropic-sdk-python/actions/workflows/publish-pypi.yml). This requires a setup organization or repository secret to be set up. ### Publish manually If you need to manually release a package, you can run the `bin/publish-pypi` script with a `PYPI_TOKEN` set on the environment. anthropic-sdk-python-0.69.0/LICENSE000066400000000000000000000020401506653454500167110ustar00rootroot00000000000000Copyright 2023 Anthropic, PBC. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. anthropic-sdk-python-0.69.0/README.md000066400000000000000000000631051506653454500171740ustar00rootroot00000000000000# Anthropic Python API library [![PyPI version](https://img.shields.io/pypi/v/anthropic.svg?label=pypi%20(stable))](https://pypi.org/project/anthropic/) The Anthropic Python library provides convenient access to the Anthropic REST API from any Python 3.8+ application. It includes type definitions for all request params and response fields, and offers both synchronous and asynchronous clients powered by [httpx](https://github.com/encode/httpx). ## Documentation The REST API documentation can be found on [docs.anthropic.com](https://docs.anthropic.com/claude/reference/). The full API of this library can be found in [api.md](api.md). ## Installation ```sh # install from PyPI pip install anthropic ``` ## Usage The full API of this library can be found in [api.md](api.md). ```python import os from anthropic import Anthropic client = Anthropic( api_key=os.environ.get("ANTHROPIC_API_KEY"), # This is the default and can be omitted ) message = client.messages.create( max_tokens=1024, messages=[ { "role": "user", "content": "Hello, Claude", } ], model="claude-sonnet-4-5-20250929", ) print(message.content) ``` While you can provide an `api_key` keyword argument, we recommend using [python-dotenv](https://pypi.org/project/python-dotenv/) to add `ANTHROPIC_API_KEY="my-anthropic-api-key"` to your `.env` file so that your API Key is not stored in source control. ## Async usage Simply import `AsyncAnthropic` instead of `Anthropic` and use `await` with each API call: ```python import os import asyncio from anthropic import AsyncAnthropic client = AsyncAnthropic( api_key=os.environ.get("ANTHROPIC_API_KEY"), # This is the default and can be omitted ) async def main() -> None: message = await client.messages.create( max_tokens=1024, messages=[ { "role": "user", "content": "Hello, Claude", } ], model="claude-sonnet-4-5-20250929", ) print(message.content) asyncio.run(main()) ``` Functionality between the synchronous and asynchronous clients is otherwise identical. ### With aiohttp By default, the async client uses `httpx` for HTTP requests. However, for improved concurrency performance you may also use `aiohttp` as the HTTP backend. You can enable this by installing `aiohttp`: ```sh # install from PyPI pip install anthropic[aiohttp] ``` Then you can enable it by instantiating the client with `http_client=DefaultAioHttpClient()`: ```python import asyncio from anthropic import DefaultAioHttpClient from anthropic import AsyncAnthropic async def main() -> None: async with AsyncAnthropic( api_key="my-anthropic-api-key", http_client=DefaultAioHttpClient(), ) as client: message = await client.messages.create( max_tokens=1024, messages=[ { "role": "user", "content": "Hello, Claude", } ], model="claude-sonnet-4-5-20250929", ) print(message.content) asyncio.run(main()) ``` ## Streaming responses We provide support for streaming responses using Server Side Events (SSE). ```python from anthropic import Anthropic client = Anthropic() stream = client.messages.create( max_tokens=1024, messages=[ { "role": "user", "content": "Hello, Claude", } ], model="claude-sonnet-4-5-20250929", stream=True, ) for event in stream: print(event.type) ``` The async client uses the exact same interface. ```python from anthropic import AsyncAnthropic client = AsyncAnthropic() stream = await client.messages.create( max_tokens=1024, messages=[ { "role": "user", "content": "Hello, Claude", } ], model="claude-sonnet-4-5-20250929", stream=True, ) async for event in stream: print(event.type) ``` ### Tool helpers This library provides helper functions for defining and running tools as pure python functions, for example: ```py import json import rich from typing_extensions import Literal from anthropic import Anthropic, beta_tool client = Anthropic() @beta_tool def get_weather(location: str) -> str: """Lookup the weather for a given city in either celsius or fahrenheit Args: location: The city and state, e.g. San Francisco, CA Returns: A dictionary containing the location, temperature, and weather condition. """ # Here you would typically make an API call to a weather service # For demonstration, we return a mock response return json.dumps( { "location": location, "temperature": "68°F", "condition": "Sunny", } ) runner = client.beta.messages.tool_runner( max_tokens=1024, model="claude-sonnet-4-5-20250929", tools=[get_weather], messages=[ {"role": "user", "content": "What is the weather in SF?"}, ], ) for message in runner: rich.print(message) ``` On every iteration, an API request will be made, if Claude wants to call one of the given tools then it will be automatically called, and the result will be returned directly to the model in the next iteration. For more information see the [full docs](tools.md). ### Streaming Helpers This library provides several conveniences for streaming messages, for example: ```py import asyncio from anthropic import AsyncAnthropic client = AsyncAnthropic() async def main() -> None: async with client.messages.stream( max_tokens=1024, messages=[ { "role": "user", "content": "Say hello there!", } ], model="claude-sonnet-4-5-20250929", ) as stream: async for text in stream.text_stream: print(text, end="", flush=True) print() message = await stream.get_final_message() print(message.to_json()) asyncio.run(main()) ``` Streaming with `client.messages.stream(...)` exposes [various helpers for your convenience](helpers.md) including accumulation & SDK-specific events. Alternatively, you can use `client.messages.create(..., stream=True)` which only returns an async iterable of the events in the stream and thus uses less memory (it does not build up a final message object for you). ## Token counting To get the token count for a message without creating it you can use the `client.messages.count_tokens()` method. This takes the same `messages` list as the `.create()` method. ```py count = client.messages.count_tokens( model="claude-sonnet-4-5-20250929", messages=[ {"role": "user", "content": "Hello, world"} ] ) count.input_tokens # 10 ``` You can also see the exact usage for a given request through the `usage` response property, e.g. ```py message = client.messages.create(...) message.usage # Usage(input_tokens=25, output_tokens=13) ``` ## Message Batches This SDK provides support for the [Message Batches API](https://docs.anthropic.com/en/docs/build-with-claude/message-batches) under the `client.messages.batches` namespace. ### Creating a batch Message Batches take the exact same request params as the standard Messages API: ```python await client.messages.batches.create( requests=[ { "custom_id": "my-first-request", "params": { "model": "claude-sonnet-4-5-20250929", "max_tokens": 1024, "messages": [{"role": "user", "content": "Hello, world"}], }, }, { "custom_id": "my-second-request", "params": { "model": "claude-sonnet-4-5-20250929", "max_tokens": 1024, "messages": [{"role": "user", "content": "Hi again, friend"}], }, }, ] ) ``` ### Getting results from a batch Once a Message Batch has been processed, indicated by `.processing_status === 'ended'`, you can access the results with `.batches.results()` ```python result_stream = await client.messages.batches.results(batch_id) async for entry in result_stream: if entry.result.type == "succeeded": print(entry.result.message.content) ``` ## Tool use This SDK provides support for tool use, aka function calling. More details can be found in [the documentation](https://docs.anthropic.com/claude/docs/tool-use). ## AWS Bedrock This library also provides support for the [Anthropic Bedrock API](https://aws.amazon.com/bedrock/claude/) if you install this library with the `bedrock` extra, e.g. `pip install -U anthropic[bedrock]`. You can then import and instantiate a separate `AnthropicBedrock` class, the rest of the API is the same. ```py from anthropic import AnthropicBedrock client = AnthropicBedrock() message = client.messages.create( max_tokens=1024, messages=[ { "role": "user", "content": "Hello!", } ], model="anthropic.claude-sonnet-4-5-20250929-v1:0", ) print(message) ``` The bedrock client supports the following arguments for authentication ```py AnthropicBedrock( aws_profile='...', aws_region='us-east' aws_secret_key='...', aws_access_key='...', aws_session_token='...', ) ``` For a more fully fledged example see [`examples/bedrock.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/examples/bedrock.py). ## Google Vertex This library also provides support for the [Anthropic Vertex API](https://cloud.google.com/vertex-ai?hl=en) if you install this library with the `vertex` extra, e.g. `pip install -U anthropic[vertex]`. You can then import and instantiate a separate `AnthropicVertex`/`AsyncAnthropicVertex` class, which has the same API as the base `Anthropic`/`AsyncAnthropic` class. ```py from anthropic import AnthropicVertex client = AnthropicVertex() message = client.messages.create( model="claude-sonnet-4@20250514", max_tokens=100, messages=[ { "role": "user", "content": "Hello!", } ], ) print(message) ``` For a more complete example see [`examples/vertex.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/examples/vertex.py). ## Using types Nested request parameters are [TypedDicts](https://docs.python.org/3/library/typing.html#typing.TypedDict). Responses are [Pydantic models](https://docs.pydantic.dev) which also provide helper methods for things like: - Serializing back into JSON, `model.to_json()` - Converting to a dictionary, `model.to_dict()` Typed requests and responses provide autocomplete and documentation within your editor. If you would like to see type errors in VS Code to help catch bugs earlier, set `python.analysis.typeCheckingMode` to `basic`. ## Pagination List methods in the Anthropic API are paginated. This library provides auto-paginating iterators with each list response, so you do not have to request successive pages manually: ```python from anthropic import Anthropic client = Anthropic() all_batches = [] # Automatically fetches more pages as needed. for batch in client.messages.batches.list( limit=20, ): # Do something with batch here all_batches.append(batch) print(all_batches) ``` Or, asynchronously: ```python import asyncio from anthropic import AsyncAnthropic client = AsyncAnthropic() async def main() -> None: all_batches = [] # Iterate through items across all pages, issuing requests as needed. async for batch in client.messages.batches.list( limit=20, ): all_batches.append(batch) print(all_batches) asyncio.run(main()) ``` Alternatively, you can use the `.has_next_page()`, `.next_page_info()`, or `.get_next_page()` methods for more granular control working with pages: ```python first_page = await client.messages.batches.list( limit=20, ) if first_page.has_next_page(): print(f"will fetch next page using these details: {first_page.next_page_info()}") next_page = await first_page.get_next_page() print(f"number of items we just fetched: {len(next_page.data)}") # Remove `await` for non-async usage. ``` Or just work directly with the returned data: ```python first_page = await client.messages.batches.list( limit=20, ) print(f"next page cursor: {first_page.last_id}") # => "next page cursor: ..." for batch in first_page.data: print(batch.id) # Remove `await` for non-async usage. ``` ## Nested params Nested parameters are dictionaries, typed using `TypedDict`, for example: ```python from anthropic import Anthropic client = Anthropic() message = client.messages.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-5-20250929", metadata={}, ) print(message.metadata) ``` ## File uploads Request parameters that correspond to file uploads can be passed as `bytes`, or a [`PathLike`](https://docs.python.org/3/library/os.html#os.PathLike) instance or a tuple of `(filename, contents, media type)`. ```python from pathlib import Path from anthropic import Anthropic client = Anthropic() client.beta.files.upload( file=Path("/path/to/file"), ) ``` The async client uses the exact same interface. If you pass a [`PathLike`](https://docs.python.org/3/library/os.html#os.PathLike) instance, the file contents will be read asynchronously automatically. ## Handling errors When the library is unable to connect to the API (for example, due to network connection problems or a timeout), a subclass of `anthropic.APIConnectionError` is raised. When the API returns a non-success status code (that is, 4xx or 5xx response), a subclass of `anthropic.APIStatusError` is raised, containing `status_code` and `response` properties. All errors inherit from `anthropic.APIError`. ```python import anthropic from anthropic import Anthropic client = Anthropic() try: client.messages.create( max_tokens=1024, messages=[ { "role": "user", "content": "Hello, Claude", } ], model="claude-sonnet-4-5-20250929", ) except anthropic.APIConnectionError as e: print("The server could not be reached") print(e.__cause__) # an underlying Exception, likely raised within httpx. except anthropic.RateLimitError as e: print("A 429 status code was received; we should back off a bit.") except anthropic.APIStatusError as e: print("Another non-200-range status code was received") print(e.status_code) print(e.response) ``` Error codes are as follows: | Status Code | Error Type | | ----------- | -------------------------- | | 400 | `BadRequestError` | | 401 | `AuthenticationError` | | 403 | `PermissionDeniedError` | | 404 | `NotFoundError` | | 422 | `UnprocessableEntityError` | | 429 | `RateLimitError` | | >=500 | `InternalServerError` | | N/A | `APIConnectionError` | ## Request IDs > For more information on debugging requests, see [these docs](https://docs.anthropic.com/en/api/errors#request-id) All object responses in the SDK provide a `_request_id` property which is added from the `request-id` response header so that you can quickly log failing requests and report them back to Anthropic. ```python message = client.messages.create( max_tokens=1024, messages=[ { "role": "user", "content": "Hello, Claude", } ], model="claude-sonnet-4-5-20250929", ) print(message._request_id) # req_018EeWyXxfu5pfWkrYcMdjWG ``` Note that unlike other properties that use an `_` prefix, the `_request_id` property _is_ public. Unless documented otherwise, _all_ other `_` prefix properties, methods and modules are _private_. ### Retries Certain errors are automatically retried 2 times by default, with a short exponential backoff. Connection errors (for example, due to a network connectivity problem), 408 Request Timeout, 409 Conflict, 429 Rate Limit, and >=500 Internal errors are all retried by default. You can use the `max_retries` option to configure or disable retry settings: ```python from anthropic import Anthropic # Configure the default for all requests: client = Anthropic( # default is 2 max_retries=0, ) # Or, configure per-request: client.with_options(max_retries=5).messages.create( max_tokens=1024, messages=[ { "role": "user", "content": "Hello, Claude", } ], model="claude-sonnet-4-5-20250929", ) ``` ### Timeouts By default requests time out after 10 minutes. You can configure this with a `timeout` option, which accepts a float or an [`httpx.Timeout`](https://www.python-httpx.org/advanced/timeouts/#fine-tuning-the-configuration) object: ```python from anthropic import Anthropic # Configure the default for all requests: client = Anthropic( # 20 seconds (default is 10 minutes) timeout=20.0, ) # More granular control: client = Anthropic( timeout=httpx.Timeout(60.0, read=5.0, write=10.0, connect=2.0), ) # Override per-request: client.with_options(timeout=5.0).messages.create( max_tokens=1024, messages=[ { "role": "user", "content": "Hello, Claude", } ], model="claude-sonnet-4-5-20250929", ) ``` On timeout, an `APITimeoutError` is thrown. Note that requests that time out are [retried twice by default](#retries). ### Long Requests > [!IMPORTANT] > We highly encourage you use the streaming [Messages API](#streaming-responses) for longer running requests. We do not recommend setting a large `max_tokens` values without using streaming. Some networks may drop idle connections after a certain period of time, which can cause the request to fail or [timeout](#timeouts) without receiving a response from Anthropic. This SDK will also throw a `ValueError` if a non-streaming request is expected to be above roughly 10 minutes long. Passing `stream=True` or [overriding](#timeouts) the `timeout` option at the client or request level disables this error. An expected request latency longer than the [timeout](#timeouts) for a non-streaming request will result in the client terminating the connection and retrying without receiving a response. We set a [TCP socket keep-alive](https://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html) option in order to reduce the impact of idle connection timeouts on some networks. This can be [overriden](#Configuring-the-HTTP-client) by passing a `http_client` option to the client. ## Default Headers We automatically send the `anthropic-version` header set to `2023-06-01`. If you need to, you can override it by setting default headers per-request or on the client object. Be aware that doing so may result in incorrect types and other unexpected or undefined behavior in the SDK. ```python from anthropic import Anthropic client = Anthropic( default_headers={"anthropic-version": "My-Custom-Value"}, ) ``` ## Advanced ### Logging We use the standard library [`logging`](https://docs.python.org/3/library/logging.html) module. You can enable logging by setting the environment variable `ANTHROPIC_LOG` to `info`. ```shell $ export ANTHROPIC_LOG=info ``` Or to `debug` for more verbose logging. ### How to tell whether `None` means `null` or missing In an API response, a field may be explicitly `null`, or missing entirely; in either case, its value is `None` in this library. You can differentiate the two cases with `.model_fields_set`: ```py if response.my_field is None: if 'my_field' not in response.model_fields_set: print('Got json like {}, without a "my_field" key present at all.') else: print('Got json like {"my_field": null}.') ``` ### Accessing raw response data (e.g. headers) The "raw" Response object can be accessed by prefixing `.with_raw_response.` to any HTTP method call, e.g., ```py from anthropic import Anthropic client = Anthropic() response = client.messages.with_raw_response.create( max_tokens=1024, messages=[{ "role": "user", "content": "Hello, Claude", }], model="claude-sonnet-4-5-20250929", ) print(response.headers.get('X-My-Header')) message = response.parse() # get the object that `messages.create()` would have returned print(message.content) ``` These methods return a [`LegacyAPIResponse`](https://github.com/anthropics/anthropic-sdk-python/tree/main/src/anthropic/_legacy_response.py) object. This is a legacy class as we're changing it slightly in the next major version. For the sync client this will mostly be the same with the exception of `content` & `text` will be methods instead of properties. In the async client, all methods will be async. A migration script will be provided & the migration in general should be smooth. #### `.with_streaming_response` The above interface eagerly reads the full response body when you make the request, which may not always be what you want. To stream the response body, use `.with_streaming_response` instead, which requires a context manager and only reads the response body once you call `.read()`, `.text()`, `.json()`, `.iter_bytes()`, `.iter_text()`, `.iter_lines()` or `.parse()`. In the async client, these are async methods. As such, `.with_streaming_response` methods return a different [`APIResponse`](https://github.com/anthropics/anthropic-sdk-python/tree/main/src/anthropic/_response.py) object, and the async client returns an [`AsyncAPIResponse`](https://github.com/anthropics/anthropic-sdk-python/tree/main/src/anthropic/_response.py) object. ```python with client.messages.with_streaming_response.create( max_tokens=1024, messages=[ { "role": "user", "content": "Hello, Claude", } ], model="claude-sonnet-4-5-20250929", ) as response: print(response.headers.get("X-My-Header")) for line in response.iter_lines(): print(line) ``` The context manager is required so that the response will reliably be closed. ### Making custom/undocumented requests This library is typed for convenient access to the documented API. If you need to access undocumented endpoints, params, or response properties, the library can still be used. #### Undocumented endpoints To make requests to undocumented endpoints, you can make requests using `client.get`, `client.post`, and other http verbs. Options on the client will be respected (such as retries) when making this request. ```py import httpx response = client.post( "/foo", cast_to=httpx.Response, body={"my_param": True}, ) print(response.headers.get("x-foo")) ``` #### Undocumented request params If you want to explicitly send an extra param, you can do so with the `extra_query`, `extra_body`, and `extra_headers` request options. > [!WARNING] > > The `extra_` parameters of the same name overrides the documented parameters. For security reasons, ensure these methods are only used with trusted input data. #### Undocumented response properties To access undocumented response properties, you can access the extra fields like `response.unknown_prop`. You can also get all the extra fields on the Pydantic model as a dict with [`response.model_extra`](https://docs.pydantic.dev/latest/api/base_model/#pydantic.BaseModel.model_extra). ### Configuring the HTTP client You can directly override the [httpx client](https://www.python-httpx.org/api/#client) to customize it for your use case, including: - Support for [proxies](https://www.python-httpx.org/advanced/proxies/) - Custom [transports](https://www.python-httpx.org/advanced/transports/) - Additional [advanced](https://www.python-httpx.org/advanced/clients/) functionality ```python import httpx from anthropic import Anthropic, DefaultHttpxClient client = Anthropic( # Or use the `ANTHROPIC_BASE_URL` env var base_url="http://my.test.server.example.com:8083", http_client=DefaultHttpxClient( proxy="http://my.test.proxy.example.com", transport=httpx.HTTPTransport(local_address="0.0.0.0"), ), ) ``` You can also customize the client on a per-request basis by using `with_options()`: ```python client.with_options(http_client=DefaultHttpxClient(...)) ``` ### Managing HTTP resources By default the library closes underlying HTTP connections whenever the client is [garbage collected](https://docs.python.org/3/reference/datamodel.html#object.__del__). You can manually close the client using the `.close()` method if desired, or with a context manager that closes when exiting. ```py from anthropic import Anthropic with Anthropic() as client: # make requests here ... # HTTP client is now closed ``` ## Versioning This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions: 1. Changes that only affect static types, without breaking runtime behavior. 2. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals.)_ 3. Changes that we do not expect to impact the vast majority of users in practice. We take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience. We are keen for your feedback; please open an [issue](https://www.github.com/anthropics/anthropic-sdk-python/issues) with questions, bugs, or suggestions. ### Determining the installed version If you've upgraded to the latest version but aren't seeing any new features you were expecting then your python environment is likely still using an older version. You can determine the version that is being used at runtime with: ```py import anthropic print(anthropic.__version__) ``` ## Requirements Python 3.8 or higher. ## Contributing See [the contributing documentation](./CONTRIBUTING.md). anthropic-sdk-python-0.69.0/SECURITY.md000066400000000000000000000022641506653454500175050ustar00rootroot00000000000000# Security Policy ## Reporting Security Issues This SDK is generated by [Stainless Software Inc](http://stainless.com). Stainless takes security seriously, and encourages you to report any security vulnerability promptly so that appropriate action can be taken. To report a security issue, please contact the Stainless team at security@stainless.com. ## Responsible Disclosure We appreciate the efforts of security researchers and individuals who help us maintain the security of SDKs we generate. If you believe you have found a security vulnerability, please adhere to responsible disclosure practices by allowing us a reasonable amount of time to investigate and address the issue before making any information public. ## Reporting Non-SDK Related Security Issues If you encounter security issues that are not directly related to SDKs but pertain to the services or products provided by Anthropic, please follow the respective company's security reporting guidelines. ### Anthropic Terms and Policies Please contact support@anthropic.com for any questions or concerns regarding the security of our services. --- Thank you for helping us keep the SDKs and systems they interact with secure. anthropic-sdk-python-0.69.0/api.md000066400000000000000000000377721506653454500170230ustar00rootroot00000000000000# Shared Types ```python from anthropic.types import ( APIErrorObject, AuthenticationError, BillingError, ErrorObject, ErrorResponse, GatewayTimeoutError, InvalidRequestError, NotFoundError, OverloadedError, PermissionError, RateLimitError, ) ``` # Messages Types: ```python from anthropic.types import ( Base64ImageSource, Base64PDFSource, CacheControlEphemeral, CacheCreation, CitationCharLocation, CitationCharLocationParam, CitationContentBlockLocation, CitationContentBlockLocationParam, CitationPageLocation, CitationPageLocationParam, CitationSearchResultLocationParam, CitationWebSearchResultLocationParam, CitationsConfigParam, CitationsDelta, CitationsSearchResultLocation, CitationsWebSearchResultLocation, ContentBlock, ContentBlockParam, ContentBlockSource, ContentBlockSourceContent, DocumentBlockParam, ImageBlockParam, InputJSONDelta, Message, MessageCountTokensTool, MessageDeltaUsage, MessageParam, MessageTokensCount, Metadata, Model, PlainTextSource, RawContentBlockDelta, RawContentBlockDeltaEvent, RawContentBlockStartEvent, RawContentBlockStopEvent, RawMessageDeltaEvent, RawMessageStartEvent, RawMessageStopEvent, RawMessageStreamEvent, RedactedThinkingBlock, RedactedThinkingBlockParam, SearchResultBlockParam, ServerToolUsage, ServerToolUseBlock, ServerToolUseBlockParam, SignatureDelta, StopReason, TextBlock, TextBlockParam, TextCitation, TextCitationParam, TextDelta, ThinkingBlock, ThinkingBlockParam, ThinkingConfigDisabled, ThinkingConfigEnabled, ThinkingConfigParam, ThinkingDelta, Tool, ToolBash20250124, ToolChoice, ToolChoiceAny, ToolChoiceAuto, ToolChoiceNone, ToolChoiceTool, ToolResultBlockParam, ToolTextEditor20250124, ToolTextEditor20250429, ToolTextEditor20250728, ToolUnion, ToolUseBlock, ToolUseBlockParam, URLImageSource, URLPDFSource, Usage, WebSearchResultBlock, WebSearchResultBlockParam, WebSearchTool20250305, WebSearchToolRequestError, WebSearchToolResultBlock, WebSearchToolResultBlockContent, WebSearchToolResultBlockParam, WebSearchToolResultBlockParamContent, WebSearchToolResultError, MessageStreamEvent, MessageStartEvent, MessageDeltaEvent, MessageStopEvent, ContentBlockStartEvent, ContentBlockDeltaEvent, ContentBlockStopEvent, ) ``` Methods: - client.messages.create(\*\*params) -> Message - client.messages.stream(\*args) -> MessageStreamManager[MessageStream] | MessageStreamManager[MessageStreamT] - client.messages.count_tokens(\*\*params) -> MessageTokensCount ## Batches Types: ```python from anthropic.types.messages import ( DeletedMessageBatch, MessageBatch, MessageBatchCanceledResult, MessageBatchErroredResult, MessageBatchExpiredResult, MessageBatchIndividualResponse, MessageBatchRequestCounts, MessageBatchResult, MessageBatchSucceededResult, ) ``` Methods: - client.messages.batches.create(\*\*params) -> MessageBatch - client.messages.batches.retrieve(message_batch_id) -> MessageBatch - client.messages.batches.list(\*\*params) -> SyncPage[MessageBatch] - client.messages.batches.delete(message_batch_id) -> DeletedMessageBatch - client.messages.batches.cancel(message_batch_id) -> MessageBatch - client.messages.batches.results(message_batch_id) -> JSONLDecoder[MessageBatchIndividualResponse] # Models Types: ```python from anthropic.types import ModelInfo ``` Methods: - client.models.retrieve(model_id) -> ModelInfo - client.models.list(\*\*params) -> SyncPage[ModelInfo] # Beta Types: ```python from anthropic.types import ( AnthropicBeta, BetaAPIError, BetaAuthenticationError, BetaBillingError, BetaError, BetaErrorResponse, BetaGatewayTimeoutError, BetaInvalidRequestError, BetaNotFoundError, BetaOverloadedError, BetaPermissionError, BetaRateLimitError, ) ``` ## Models Types: ```python from anthropic.types.beta import BetaModelInfo ``` Methods: - client.beta.models.retrieve(model_id) -> BetaModelInfo - client.beta.models.list(\*\*params) -> SyncPage[BetaModelInfo] ## Messages Types: ```python from anthropic.types.beta import ( BetaBase64ImageSource, BetaBase64PDFSource, BetaBashCodeExecutionOutputBlock, BetaBashCodeExecutionOutputBlockParam, BetaBashCodeExecutionResultBlock, BetaBashCodeExecutionResultBlockParam, BetaBashCodeExecutionToolResultBlock, BetaBashCodeExecutionToolResultBlockParam, BetaBashCodeExecutionToolResultError, BetaBashCodeExecutionToolResultErrorParam, BetaCacheControlEphemeral, BetaCacheCreation, BetaCitationCharLocation, BetaCitationCharLocationParam, BetaCitationConfig, BetaCitationContentBlockLocation, BetaCitationContentBlockLocationParam, BetaCitationPageLocation, BetaCitationPageLocationParam, BetaCitationSearchResultLocation, BetaCitationSearchResultLocationParam, BetaCitationWebSearchResultLocationParam, BetaCitationsConfigParam, BetaCitationsDelta, BetaCitationsWebSearchResultLocation, BetaClearToolUses20250919Edit, BetaClearToolUses20250919EditResponse, BetaCodeExecutionOutputBlock, BetaCodeExecutionOutputBlockParam, BetaCodeExecutionResultBlock, BetaCodeExecutionResultBlockParam, BetaCodeExecutionTool20250522, BetaCodeExecutionTool20250825, BetaCodeExecutionToolResultBlock, BetaCodeExecutionToolResultBlockContent, BetaCodeExecutionToolResultBlockParam, BetaCodeExecutionToolResultBlockParamContent, BetaCodeExecutionToolResultError, BetaCodeExecutionToolResultErrorCode, BetaCodeExecutionToolResultErrorParam, BetaContainer, BetaContainerUploadBlock, BetaContainerUploadBlockParam, BetaContentBlock, BetaContentBlockParam, BetaContentBlockSource, BetaContentBlockSourceContent, BetaContextManagementConfig, BetaContextManagementResponse, BetaCountTokensContextManagementResponse, BetaDocumentBlock, BetaFileDocumentSource, BetaFileImageSource, BetaImageBlockParam, BetaInputJSONDelta, BetaInputTokensClearAtLeast, BetaInputTokensTrigger, BetaMCPToolResultBlock, BetaMCPToolUseBlock, BetaMCPToolUseBlockParam, BetaMemoryTool20250818, BetaMemoryTool20250818Command, BetaMemoryTool20250818CreateCommand, BetaMemoryTool20250818DeleteCommand, BetaMemoryTool20250818InsertCommand, BetaMemoryTool20250818RenameCommand, BetaMemoryTool20250818StrReplaceCommand, BetaMemoryTool20250818ViewCommand, BetaMessage, BetaMessageDeltaUsage, BetaMessageParam, BetaMessageTokensCount, BetaMetadata, BetaPlainTextSource, BetaRawContentBlockDelta, BetaRawContentBlockDeltaEvent, BetaRawContentBlockStartEvent, BetaRawContentBlockStopEvent, BetaRawMessageDeltaEvent, BetaRawMessageStartEvent, BetaRawMessageStopEvent, BetaRawMessageStreamEvent, BetaRedactedThinkingBlock, BetaRedactedThinkingBlockParam, BetaRequestDocumentBlock, BetaRequestMCPServerToolConfiguration, BetaRequestMCPServerURLDefinition, BetaRequestMCPToolResultBlockParam, BetaSearchResultBlockParam, BetaServerToolUsage, BetaServerToolUseBlock, BetaServerToolUseBlockParam, BetaSignatureDelta, BetaStopReason, BetaTextBlock, BetaTextBlockParam, BetaTextCitation, BetaTextCitationParam, BetaTextDelta, BetaTextEditorCodeExecutionCreateResultBlock, BetaTextEditorCodeExecutionCreateResultBlockParam, BetaTextEditorCodeExecutionStrReplaceResultBlock, BetaTextEditorCodeExecutionStrReplaceResultBlockParam, BetaTextEditorCodeExecutionToolResultBlock, BetaTextEditorCodeExecutionToolResultBlockParam, BetaTextEditorCodeExecutionToolResultError, BetaTextEditorCodeExecutionToolResultErrorParam, BetaTextEditorCodeExecutionViewResultBlock, BetaTextEditorCodeExecutionViewResultBlockParam, BetaThinkingBlock, BetaThinkingBlockParam, BetaThinkingConfigDisabled, BetaThinkingConfigEnabled, BetaThinkingConfigParam, BetaThinkingDelta, BetaTool, BetaToolBash20241022, BetaToolBash20250124, BetaToolChoice, BetaToolChoiceAny, BetaToolChoiceAuto, BetaToolChoiceNone, BetaToolChoiceTool, BetaToolComputerUse20241022, BetaToolComputerUse20250124, BetaToolResultBlockParam, BetaToolTextEditor20241022, BetaToolTextEditor20250124, BetaToolTextEditor20250429, BetaToolTextEditor20250728, BetaToolUnion, BetaToolUseBlock, BetaToolUseBlockParam, BetaToolUsesKeep, BetaToolUsesTrigger, BetaURLImageSource, BetaURLPDFSource, BetaUsage, BetaWebFetchBlock, BetaWebFetchBlockParam, BetaWebFetchTool20250910, BetaWebFetchToolResultBlock, BetaWebFetchToolResultBlockParam, BetaWebFetchToolResultErrorBlock, BetaWebFetchToolResultErrorBlockParam, BetaWebFetchToolResultErrorCode, BetaWebSearchResultBlock, BetaWebSearchResultBlockParam, BetaWebSearchTool20250305, BetaWebSearchToolRequestError, BetaWebSearchToolResultBlock, BetaWebSearchToolResultBlockContent, BetaWebSearchToolResultBlockParam, BetaWebSearchToolResultBlockParamContent, BetaWebSearchToolResultError, BetaWebSearchToolResultErrorCode, BetaBase64PDFBlock, ) ``` Methods: - client.beta.messages.create(\*\*params) -> BetaMessage - client.beta.messages.count_tokens(\*\*params) -> BetaMessageTokensCount ### Batches Types: ```python from anthropic.types.beta.messages import ( BetaDeletedMessageBatch, BetaMessageBatch, BetaMessageBatchCanceledResult, BetaMessageBatchErroredResult, BetaMessageBatchExpiredResult, BetaMessageBatchIndividualResponse, BetaMessageBatchRequestCounts, BetaMessageBatchResult, BetaMessageBatchSucceededResult, ) ``` Methods: - client.beta.messages.batches.create(\*\*params) -> BetaMessageBatch - client.beta.messages.batches.retrieve(message_batch_id) -> BetaMessageBatch - client.beta.messages.batches.list(\*\*params) -> SyncPage[BetaMessageBatch] - client.beta.messages.batches.delete(message_batch_id) -> BetaDeletedMessageBatch - client.beta.messages.batches.cancel(message_batch_id) -> BetaMessageBatch - client.beta.messages.batches.results(message_batch_id) -> JSONLDecoder[BetaMessageBatchIndividualResponse] ## Files Types: ```python from anthropic.types.beta import DeletedFile, FileMetadata ``` Methods: - client.beta.files.list(\*\*params) -> SyncPage[FileMetadata] - client.beta.files.delete(file_id) -> DeletedFile - client.beta.files.download(file_id) -> BinaryAPIResponse - client.beta.files.retrieve_metadata(file_id) -> FileMetadata - client.beta.files.upload(\*\*params) -> FileMetadata anthropic-sdk-python-0.69.0/bin/000077500000000000000000000000001506653454500164605ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/bin/check-release-environment000066400000000000000000000012131506653454500234350ustar00rootroot00000000000000#!/usr/bin/env bash errors=() if [ -z "${STAINLESS_API_KEY}" ]; then errors+=("The STAINLESS_API_KEY secret has not been set. Please contact Stainless for an API key & set it in your organization secrets on GitHub.") 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 lenErrors=${#errors[@]} if [[ lenErrors -gt 0 ]]; then echo -e "Found the following errors in the release environment:\n" for error in "${errors[@]}"; do echo -e "- $error\n" done exit 1 fi echo "The environment is ready to push releases!" anthropic-sdk-python-0.69.0/bin/publish-pypi000066400000000000000000000001401506653454500210230ustar00rootroot00000000000000#!/usr/bin/env bash set -eux rm -rf dist mkdir -p dist uv build uv publish --token=$PYPI_TOKEN anthropic-sdk-python-0.69.0/examples/000077500000000000000000000000001506653454500175265ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/examples/.keep000066400000000000000000000003571506653454500204600ustar00rootroot00000000000000File generated from our OpenAPI spec by Stainless. This directory can be used to store example files demonstrating usage of this SDK. It is ignored by Stainless code generation and its content (other than this keep file) won't be touched.anthropic-sdk-python-0.69.0/examples/batch_results.py000066400000000000000000000006171506653454500227460ustar00rootroot00000000000000import sys import time import rich from anthropic import Anthropic client = Anthropic() try: batch_id = sys.argv[1] except IndexError as exc: raise RuntimeError("must specify a message batch ID, `python examples/batch_results.py msgbatch_123`") from exc s = time.monotonic() result_stream = client.messages.batches.results(batch_id) for result in result_stream: rich.print(result) anthropic-sdk-python-0.69.0/examples/bedrock.py000066400000000000000000000024351506653454500215150ustar00rootroot00000000000000#!/usr/bin/env -S poetry run python # Note: you must have installed `anthropic` with the `bedrock` extra # e.g. `pip install -U anthropic[bedrock]` from anthropic import AnthropicBedrock # Note: this assumes you have AWS credentials configured. # # https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html client = AnthropicBedrock() print("------ standard response ------") message = client.messages.create( max_tokens=1024, messages=[ { "role": "user", "content": "Hello!", } ], model="anthropic.claude-sonnet-4-5-20250929-v1:0", ) print(message.model_dump_json(indent=2)) print("------ streamed response ------") with client.messages.stream( max_tokens=1024, messages=[ { "role": "user", "content": "Say hello there!", } ], model="anthropic.claude-sonnet-4-5-20250929-v1:0", ) as stream: for text in stream.text_stream: print(text, end="", flush=True) print() # you can still get the accumulated final message outside of # the context manager, as long as the entire stream was consumed # inside of the context manager accumulated = stream.get_final_message() print("accumulated message: ", accumulated.model_dump_json(indent=2)) anthropic-sdk-python-0.69.0/examples/images.py000066400000000000000000000013451506653454500213500ustar00rootroot00000000000000from pathlib import Path from anthropic import Anthropic client = Anthropic() response = client.messages.create( max_tokens=1024, messages=[ { "role": "user", "content": [ { "type": "text", "text": "Hello!", }, { "type": "image", "source": { "type": "base64", "media_type": "image/png", "data": Path(__file__).parent.joinpath("logo.png"), }, }, ], }, ], model="claude-sonnet-4-5-20250929", ) print(response.model_dump_json(indent=2)) anthropic-sdk-python-0.69.0/examples/logo.png000066400000000000000000000345321506653454500212030ustar00rootroot00000000000000PNG  IHDR Z@!2R pHYs.#.#x?vtEXtSoftwarewww.inkscape.org< IDATx}%E . z9UseW?EC L Qï"$b@I"bF%H2|awos=gf眮g {z:TWە'9P@NCmG7( ZƘ"D*"^{QDĕ15Q=s```Ae1f(l"qVCW%G7]I?o%4l GӦv$㍢h1 c{`%K9|GFFc qqch4-}ZfY:gq(װnZjD.oG9sXs:ǻ0dݚfLq[[4-V^jPzR* ( .DxjMӟHair3| h"qTkKiVmysǯo6[610_Bh4e9؎E;} e11uDĩ9 gϱ=Óp;\@kN4K0"gd9, ++""kH% [>@NiqxXW=DjBW?␛UAʓ)H߫ @)~J | HRMc+oqD[CK826ó6Y+Zb>U*@7 e9|ìcEξ>N S$MG50*Z@ U Q kD5xEq>lQeGI ^}*tQqCe5dFGGD*&/yg]-)< H{a2 VFT/is`lE "/Į`}x++2+)Xu^]m5,J$ts5^q r}jx)y >v-)J>+g0i6.n UN@ξ H{fNLfs^ FeR(e4M>/kqsV+23%)g))|_#b yұ|* Hx""~_+6w [`|:&/jW'љq|s1VS  qO!w0*6IV3Oi42f9-EXD;;ICYQeS~\xJszet?eߞeyn8]8\EQb0ם0LT(z=,P8˄UEV8-yG5"~7b?<=JX'H; BJŚHeEcFį+ʗ)bxcLj87<_rl 0\le:]8>t%uz2z:׫&!)/(ڟokL,p>qgkׅ0IO$a>4;4`uw\%yvה,Yi϶WſBdyh+1e5^ R,_JZG>=Xɍq^'po'EP ^ky~]l=u7iqAfyr&.i $c S".]G\#XYB${f$;BPĕzkF;4fƱ*zvu"F cK B&E?iTPqɐYDes*|Hf%pGޙn#g@_1qKwXfꐲ8&o@)mˊ i ĕzQ.%z"1Y 6w*V~OPx̮Z> @Vh>Z$}TFs^Mo~9>>΍[u Dzϝe$:}:&D|oZ@T8Z-\cQ`*#bٕד6zXx}|1PFi7hC S y a!: s;uttt\TsA /W<Յ, .X]S",Y&",VQgYaO^MOhQŇR)e_cW4 zB>ʾR%I @^WR#xmc3UPr}a 1Gf<+h4QL~k}ttt5%_pr l/|г/}L(㕂DTʯ+Zc䉲ۍ?h#X֓.r?LJuԨ2:ƂO\xeF-D-HF)9p]6B|Dn-͔xFHLz!v**ʅTFAǮ~D.p=Osg$))u}x߬3ISsWMH !)NۅZ.de*U,"klE;&⚥&/ƯS~2g'agh]b@Jmgh[sͺ : ck{/'Up72`܍[bLL @6k-^(_lJ5לB[s3ə:种1hc6cAƘ Pa:==d]22[~ryHJs]h!exkxTitcʀWu2-5Γ}ʱ!Vk]sD|kc6 ?Eekr9@4ĉ> Iq] Gvjx\{؟xSg{qLVv,W9Fη,r-Qg )o;~XYJuN:7nCGʾhȀ WEsB72*^KW(@4_{ Xy\77Go:P6.h$mdddCĞOP|vDJtcn 2HxAQ;~ EX)9xC,2RwrG|fH2ňxwsP қW+tw;;_(1j$l6cxeo_ETM@E4JL5P8xDN(_/5S$@۟<^YW> W*8J(gvlWKGQ.P7nrb $(@<V~(˩畓gS4a2qj &KcGSָ|f}+W\'Ns#?PZ{9,pЕ_Y"(W9X8D? H ]`QU:W9K~lٲ SR^ssw_iP)/^:,r]ʶ\*WF.+eqeYiJ+Sv `<+\P!O;<Hw22`twt2%2\{|ǙvC{K .@z%ᔒt!M=OFf`ߦoib>5gefdɸzdP dmIDAT:P1Sx)S`@Akˇ;I1fk8cH tq </`ED3F+sTM.P"_6@r;Ƙs9J!NJ2=ε¹ slvQ!;AE42>(1f_7/Yu E+eŚXT h49⼆cǿ)v=<*՘~^FG3z@X- S|J5^2:Ř*TFOƵt$8.:x!(L #cv,A| ![prѬ?S t *@0͌' 11g*.;4^ h _Qu~ eMWAp^؛p-id/)(,DTVS?= (t(Z@ҿEN @3=hx$X@4, QzDv;".3 H֡4*TCJ--(X;Y[k (9Aa[bDDJ!~"+Ytt#@ђu9@/MRy1lߔ` TSj_Z@V W,^d=SSo^l|ʧj>86+ACrCqʳɹ|i8Hy;T-+7[S#9?vAďK>~p7/$'QF=Op%e@-IaM/K0@ABSjQP$sLՠBrp޽&sټ"}r=H׻k!~D|L, >LֻV5)Ud:"^в4QAo^J 2BʸtUP?S8?"_C[)3WN;(2z.ѓ3F:_) NWz [KG?rick>wZK]k@DZv@ @)1']2e,mcH]NqR^YxgQҘtTG!~Jc=GND1/TFOƳhѢQ%xh[v?z[޶rllw8:R8__Lb|Wg ~zZ1Rt h&O>qi-+-pRS?U֞e.,V)5z?<<1^4 bs* U oĚZ?43!Qi1) 7 pY@VCas} hRКRbQ$չ8* (զs2O"@c\h >tX?ͥV|֊u>%+|WgG~| 9>@s bYykϕRER|=l x?d Hl0FeяS҃~y5q|J8!O\[ I:4Q ;I$yL! {;_ YnSY.'\VB8MnE , 2:"UFwF5J\Lge48a $kqOE!x漻ٽ\qQ{zG]N*-d HQ|JR?[ЛܿǾL_P)Q+mRrX|X #:RΙJy3c3TPٓ]uuV#bv+!R$P <-l)+k5]يV>Q\/韂hD, "ޯͲ 'e9Tq<3o5u >C6C^dɒ5Z4XXާ1t/W(+@s Xx FĿ}\+7Rي[8|KֈL`PFT`LZw+0R~R?*2vVD|bW]j)eWE{#E< ~1`ޭ]ɢ(IQM> "rsHh.rŏ3ߦ)⻬İщB4DwYx.f[ԏXN!+߰}9dG:3s'EQ3NA<K/ xpm'֏ %J/~e/_`9XIc@)TT/&X@)POVJ[VNOl6w2%t']w ݭFN.") l^8~jqVRʜY9VRj @ƳuK}Y!)drkv⩚ G%]Twx"%RN<Ƙݩ81x x5wX!z#)wLÈxyA1SΗҸ(c}D#W3xZ1#?{\VUq6&yBiW> Ob/ `y<`q`8RFYi~IiyUq{IC/)-sB(/9Fgq1wzqgye ,g(ñ5w,TPY3}\[%Q15as~1*YFGG7 7Jūe9^ 鷩rnH|> H@95ʿg<7ߡD_XC-EӢ2KንS0h%eUշ8nhĦS5R-ej',+R 2!nj1s2 ~lxzA59lnIrDD5o}s||e`u"qܰ"wʾjW@s~ H$n .5ey'%@\| w].U>T}V&xXw_WnX Vb67*V< YW|8H y?R8bѲ<4$gTعʂOމ2RHkqEPÂ6r9֌y QBvyI+8F {B4Jfp=@l:3k $_o@~˵r51S?96:쪰'OPVbT%f{Y'byQސ"VDص 2Yɏejf]3\V8ޓs<Cx#\ZH]n3WHa09羒xM$>Aw)d)ͳ|>hޑߙP< {cǾ I<"= Dowf7xbbYi\;8\16G2ߎr8}Ār)">⸧̍5mE1Gi\VKcXxjsV:eTJN0c&Xc48>#RҼք6d8GƘ v1 e%qwmf;kZNz}v1ƼE?zc82g3z60#.LAoZ˾=!4FyfѤ(xƒ) v?DĻm*XDmRIP܉u:2ZY1\Z\{4P2lmWcץK.,yO⽢(YETsl$ky3<JAhOI.*E@(*f#W's-F xZP3F.ɂlٲ~7PWLnOVAQaӣn P@`GˍԤ]W"IENDB`anthropic-sdk-python-0.69.0/examples/memory/000077500000000000000000000000001506653454500210365ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/examples/memory/basic.py000066400000000000000000000363561506653454500225060ustar00rootroot00000000000000import time import shutil import threading from typing import List, Optional, cast from pathlib import Path from typing_extensions import override from pydantic import TypeAdapter from anthropic import Anthropic from anthropic.lib.tools import BetaAbstractMemoryTool from anthropic.types.beta import ( BetaMessageParam, BetaContentBlockParam, BetaMemoryTool20250818Command, BetaContextManagementConfigParam, BetaMemoryTool20250818ViewCommand, BetaMemoryTool20250818CreateCommand, BetaMemoryTool20250818DeleteCommand, BetaMemoryTool20250818InsertCommand, BetaMemoryTool20250818RenameCommand, BetaMemoryTool20250818StrReplaceCommand, ) MEMORY_SYSTEM_PROMPT = """- ***DO NOT just store the conversation history** - No need to mention your memory tool or what you are writting in it to the user, unless they ask - Store facts about the user and their preferences - Before responding, check memory to adjust technical depth and response style appropriately - Keep memories up-to-date - remove outdated info, add new details as you learn them - Use an xml format like John Doe""" # Context management automatically clears old tool results to stay within token limits # Triggers when input exceeds 20k tokens, clears down to 10k tokens CONTEXT_MANAGEMENT = { "edits": [ { "type": "clear_tool_uses_20250919", # The below parameters are OPTIONAL: # Trigger clearing when threshold is exceeded "trigger": {"type": "input_tokens", "value": 30000}, # Number of tool uses to keep after clearing "keep": {"type": "tool_uses", "value": 3}, # Optional: Clear at least this many tokens "clear_at_least": {"type": "input_tokens", "value": 5000}, # Exclude these tools uses from being cleared "exclude_tools": ["web_search"], } ] } class LocalFilesystemMemoryTool(BetaAbstractMemoryTool): """File-based memory storage implementation for Claude conversations""" def __init__(self, base_path: str = "./memory"): super().__init__() self.base_path = Path(base_path) self.memory_root = self.base_path / "memories" self.memory_root.mkdir(parents=True, exist_ok=True) def _validate_path(self, path: str) -> Path: """Validate and resolve memory paths""" if not path.startswith("/memories"): raise ValueError(f"Path must start with /memories, got: {path}") relative_path = path[len("/memories") :].lstrip("/") full_path = self.memory_root / relative_path if relative_path else self.memory_root try: full_path.resolve().relative_to(self.memory_root.resolve()) except ValueError as e: raise ValueError(f"Path {path} would escape /memories directory") from e return full_path @override def view(self, command: BetaMemoryTool20250818ViewCommand) -> str: full_path = self._validate_path(command.path) if full_path.is_dir(): items: List[str] = [] try: for item in sorted(full_path.iterdir()): if item.name.startswith("."): continue items.append(f"{item.name}/" if item.is_dir() else item.name) return f"Directory: {command.path}" + "\n".join([f"- {item}" for item in items]) except Exception as e: raise RuntimeError(f"Cannot read directory {command.path}: {e}") from e elif full_path.is_file(): try: content = full_path.read_text(encoding="utf-8") lines = content.splitlines() view_range = command.view_range if view_range: start_line = max(1, view_range[0]) - 1 end_line = len(lines) if view_range[1] == -1 else view_range[1] lines = lines[start_line:end_line] start_num = start_line + 1 else: start_num = 1 numbered_lines = [f"{i + start_num:4d}: {line}" for i, line in enumerate(lines)] return "\n".join(numbered_lines) except Exception as e: raise RuntimeError(f"Cannot read file {command.path}: {e}") from e else: raise RuntimeError(f"Path not found: {command.path}") @override def create(self, command: BetaMemoryTool20250818CreateCommand) -> str: full_path = self._validate_path(command.path) full_path.parent.mkdir(parents=True, exist_ok=True) full_path.write_text(command.file_text, encoding="utf-8") return f"File created successfully at {command.path}" @override def str_replace(self, command: BetaMemoryTool20250818StrReplaceCommand) -> str: full_path = self._validate_path(command.path) if not full_path.is_file(): raise FileNotFoundError(f"File not found: {command.path}") content = full_path.read_text(encoding="utf-8") count = content.count(command.old_str) if count == 0: raise ValueError(f"Text not found in {command.path}") elif count > 1: raise ValueError(f"Text appears {count} times in {command.path}. Must be unique.") new_content = content.replace(command.old_str, command.new_str) full_path.write_text(new_content, encoding="utf-8") return f"File {command.path} has been edited" @override def insert(self, command: BetaMemoryTool20250818InsertCommand) -> str: full_path = self._validate_path(command.path) insert_line = command.insert_line insert_text = command.insert_text if not full_path.is_file(): raise FileNotFoundError(f"File not found: {command.path}") lines = full_path.read_text(encoding="utf-8").splitlines() if insert_line < 0 or insert_line > len(lines): raise ValueError(f"Invalid insert_line {insert_line}. Must be 0-{len(lines)}") lines.insert(insert_line, insert_text.rstrip("\n")) full_path.write_text("\n".join(lines) + "\n", encoding="utf-8") return f"Text inserted at line {insert_line} in {command.path}" @override def delete(self, command: BetaMemoryTool20250818DeleteCommand) -> str: full_path = self._validate_path(command.path) if command.path == "/memories": raise ValueError("Cannot delete the /memories directory itself") if full_path.is_file(): full_path.unlink() return f"File deleted: {command.path}" elif full_path.is_dir(): shutil.rmtree(full_path) return f"Directory deleted: {command.path}" else: raise FileNotFoundError(f"Path not found: {command.path}") @override def rename(self, command: BetaMemoryTool20250818RenameCommand) -> str: old_full_path = self._validate_path(command.old_path) new_full_path = self._validate_path(command.new_path) if not old_full_path.exists(): raise FileNotFoundError(f"Source path not found: {command.old_path}") if new_full_path.exists(): raise ValueError(f"Destination already exists: {command.new_path}") new_full_path.parent.mkdir(parents=True, exist_ok=True) old_full_path.rename(new_full_path) return f"Renamed {command.old_path} to {command.new_path}" @override def clear_all_memory(self) -> str: """Override the base implementation to provide file system clearing.""" if self.memory_root.exists(): shutil.rmtree(self.memory_root) self.memory_root.mkdir(parents=True, exist_ok=True) return "All memory cleared" class Spinner: def __init__(self, message: str = "Thinking"): self.message = message self.spinning = False self.thread = None def start(self): self.spinning = True self.thread = threading.Thread(target=self._spin) self.thread.start() def stop(self): self.spinning = False if self.thread: self.thread.join() print("\r" + " " * (len(self.message) + 10) + "\r", end="", flush=True) def _spin(self): chars = "⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏" i = 0 while self.spinning: print(f"\r{self.message} {chars[i % len(chars)]}", end="", flush=True) i += 1 time.sleep(0.1) def conversation_loop(): client = Anthropic() memory = LocalFilesystemMemoryTool() messages: list[BetaMessageParam] = [] # Initialize tracking for debug last_response_id: Optional[str] = None last_usage = None print("🧠 Claude with Memory & Web Search - Interactive Session") print("Commands:") print(" /quit or /exit - Exit the session") print(" /clear - Start fresh conversation") print(" /memory_view - See all memory files") print(" /memory_clear - Delete all memory") print(" /debug - View conversation history and token usage") # Display context management settings print(f"\n🧹 Context Management") print("=" * 60) while True: try: user_input = input("\nYou: ").strip() except (EOFError, KeyboardInterrupt): print("\nGoodbye!") break if user_input.lower() in ["/quit", "/exit"]: print("Goodbye!") break elif user_input.lower() == "/clear": messages = [] print("Conversation cleared!") continue elif user_input.lower() == "/memory_view": result = memory.execute(BetaMemoryTool20250818ViewCommand(command="view", path="/memories")) print("\n📁 Memory contents:") print(result) continue elif user_input.lower() == "/memory_clear": result = memory.clear_all_memory() print(f"🗑️ {result}") continue elif user_input.lower() == "/debug": print("\n🔍 Conversation history:") # Show last response ID if available if last_response_id: print(f"📌 Last response ID: {last_response_id}") # Show token usage if available if last_usage: usage = last_usage input_tokens = usage.get("input_tokens", 0) cached_tokens = usage.get("cache_read_input_tokens", 0) uncached_tokens = input_tokens - cached_tokens print(f"📊 Last API call tokens:") print(f" Total input: {input_tokens:,} tokens") print(f" Cached: {cached_tokens:,} tokens") print(f" Uncached: {uncached_tokens:,} tokens") threshold = CONTEXT_MANAGEMENT["edits"][0]["trigger"]["value"] # type: ignore print(f" Context clearing threshold: {threshold:,} tokens") if input_tokens >= threshold: print(f" 🧹 Context clearing should trigger soon!") elif input_tokens >= threshold * 0.8: # 80% of threshold #type: ignore print(f" ⚠️ Approaching context clearing threshold!") print("=" * 80) for i, message in enumerate(messages): role = message["role"].upper() print(f"\n[{i + 1}] {role}:") print("-" * 40) content = message["content"] if isinstance(content, str): print(content[:500] + "..." if len(content) > 500 else content) elif isinstance(content, list): for block in content: if isinstance(block, dict): if block.get("type") in ["tool_use", "server_tool_use"]: print(f"Tool: {block.get('name', 'unknown')}") elif block.get("type") == "tool_result": print(f"Tool Result: [content]") elif block.get("type") == "text": text = block.get("text", "") print(f"Text: {text[:200]}..." if len(text) > 200 else f"Text: {text}") print("=" * 80) continue elif not user_input: continue messages.append({"role": "user", "content": user_input}) print("\nClaude: ", end="", flush=True) spinner = Spinner("Thinking") spinner.start() # Use tool_runner with memory tool try: runner = client.beta.messages.tool_runner( betas=["context-management-2025-06-27"], model="claude-sonnet-4-20250514", max_tokens=2048, system=MEMORY_SYSTEM_PROMPT, messages=messages, tools=[memory], context_management=cast(BetaContextManagementConfigParam, CONTEXT_MANAGEMENT), ) except Exception: spinner.stop() raise # Process all messages from the runner assistant_content: list[BetaContentBlockParam] = [] for message in runner: spinner.stop() # Store response ID and usage for debug display last_response_id = message.id if hasattr(message, "usage") and message.usage: last_usage = message.usage.model_dump() if hasattr(message.usage, "model_dump") else dict(message.usage) # Check for context management actions if message.context_management: for edit in message.context_management.applied_edits: print(f"\n🧹 [Context Management: {edit.type} applied]") # Process content blocks for content in message.content: if content.type == "text": print(content.text, end="", flush=True) assistant_content.append({"type": "text", "text": content.text}) elif content.type == "tool_use" and content.name == "memory": tool_input = TypeAdapter[BetaMemoryTool20250818Command]( BetaMemoryTool20250818Command ).validate_python(content.input) print(f"\n[Memory tool called: {tool_input.command}]") assistant_content.append( { "type": "tool_use", "id": content.id, "name": content.name, "input": content.input, } ) # Generate tool response automatically tool_response = runner.generate_tool_call_response() if tool_response and tool_response["content"]: # Add tool results to messages messages.append({"role": "user", "content": tool_response["content"]}) for result in tool_response["content"]: if isinstance(result, dict) and result.get("type") == "tool_result": print(f"[Tool result processed]") # Store assistant message if assistant_content: messages.append({"role": "assistant", "content": assistant_content}) print() if __name__ == "__main__": conversation_loop() anthropic-sdk-python-0.69.0/examples/messages.py000066400000000000000000000012461506653454500217120ustar00rootroot00000000000000from anthropic import Anthropic client = Anthropic() response = client.messages.create( max_tokens=1024, messages=[ { "role": "user", "content": "Hello!", } ], model="claude-sonnet-4-5-20250929", ) print(response) response2 = client.messages.create( max_tokens=1024, messages=[ { "role": "user", "content": "Hello!", }, { "role": response.role, "content": response.content, }, { "role": "user", "content": "How are you?", }, ], model="claude-sonnet-4-5-20250929", ) print(response2) anthropic-sdk-python-0.69.0/examples/messages_stream.py000077500000000000000000000017621506653454500232730ustar00rootroot00000000000000#!/usr/bin/env -S rye run python import asyncio from anthropic import AsyncAnthropic client = AsyncAnthropic() async def main() -> None: async with client.messages.stream( max_tokens=1024, messages=[ { "role": "user", "content": "Say hello there!", } ], model="claude-sonnet-4-5-20250929", ) as stream: async for event in stream: if event.type == "text": print(event.text, end="", flush=True) elif event.type == "content_block_stop": print() print("\ncontent block finished accumulating:", event.content_block) print() # you can still get the accumulated final message outside of # the context manager, as long as the entire stream was consumed # inside of the context manager accumulated = await stream.get_final_message() print("accumulated message: ", accumulated.to_json()) asyncio.run(main()) anthropic-sdk-python-0.69.0/examples/text_completions_demo_async.py000066400000000000000000000007101506653454500256770ustar00rootroot00000000000000#!/usr/bin/env -S poetry run python import asyncio import anthropic from anthropic import AsyncAnthropic async def main() -> None: client = AsyncAnthropic() res = await client.completions.create( model="claude-sonnet-4-5-20250929", prompt=f"{anthropic.HUMAN_PROMPT} how does a court case get to the Supreme Court? {anthropic.AI_PROMPT}", max_tokens_to_sample=1000, ) print(res.completion) asyncio.run(main()) anthropic-sdk-python-0.69.0/examples/text_completions_demo_sync.py000066400000000000000000000006251506653454500255430ustar00rootroot00000000000000#!/usr/bin/env -S poetry run python import anthropic from anthropic import Anthropic def main() -> None: client = Anthropic() res = client.completions.create( model="claude-sonnet-4-5-20250929", prompt=f"{anthropic.HUMAN_PROMPT} how does a court case get to the Supreme Court? {anthropic.AI_PROMPT}", max_tokens_to_sample=1000, ) print(res.completion) main() anthropic-sdk-python-0.69.0/examples/text_completions_streaming.py000066400000000000000000000025721506653454500255570ustar00rootroot00000000000000#!/usr/bin/env -S poetry run python import asyncio from anthropic import AI_PROMPT, HUMAN_PROMPT, Anthropic, APIStatusError, AsyncAnthropic client = Anthropic() async_client = AsyncAnthropic() question = """ Hey Claude! How can I recursively list all files in a directory in Python? """ def sync_stream() -> None: stream = client.completions.create( prompt=f"{HUMAN_PROMPT} {question}{AI_PROMPT}", model="claude-sonnet-4-5-20250929", stream=True, max_tokens_to_sample=300, ) for completion in stream: print(completion.completion, end="", flush=True) print() async def async_stream() -> None: stream = await async_client.completions.create( prompt=f"{HUMAN_PROMPT} {question}{AI_PROMPT}", model="claude-sonnet-4-5-20250929", stream=True, max_tokens_to_sample=300, ) async for completion in stream: print(completion.completion, end="", flush=True) print() def stream_error() -> None: try: client.completions.create( prompt=f"{HUMAN_PROMPT} {question}{AI_PROMPT}", model="claude-unknown-model", stream=True, max_tokens_to_sample=300, ) except APIStatusError as err: print(f"Caught API status error with response body: {err.response.text}") sync_stream() asyncio.run(async_stream()) stream_error() anthropic-sdk-python-0.69.0/examples/thinking.py000066400000000000000000000007161506653454500217170ustar00rootroot00000000000000import anthropic client = anthropic.Anthropic() response = client.messages.create( model="claude-sonnet-4-5-20250929", max_tokens=3200, thinking={"type": "enabled", "budget_tokens": 1600}, messages=[{"role": "user", "content": "Create a haiku about Anthropic."}], ) for block in response.content: if block.type == "thinking": print(f"Thinking: {block.thinking}") elif block.type == "text": print(f"Text: {block.text}") anthropic-sdk-python-0.69.0/examples/thinking_stream.py000066400000000000000000000013761506653454500232750ustar00rootroot00000000000000import anthropic client = anthropic.Anthropic() with client.messages.stream( model="claude-sonnet-4-5-20250929", max_tokens=3200, thinking={"type": "enabled", "budget_tokens": 1600}, messages=[{"role": "user", "content": "Create a haiku about Anthropic."}], ) as stream: thinking = "not-started" for event in stream: if event.type == "thinking": if thinking == "not-started": print("Thinking:\n---------") thinking = "started" print(event.thinking, end="", flush=True) elif event.type == "text": if thinking != "finished": print("\n\nText:\n-----") thinking = "finished" print(event.text, end="", flush=True) anthropic-sdk-python-0.69.0/examples/tools.py000066400000000000000000000025661506653454500212510ustar00rootroot00000000000000from __future__ import annotations from anthropic import Anthropic from anthropic.types import ToolParam, MessageParam client = Anthropic() user_message: MessageParam = { "role": "user", "content": "What is the weather in SF?", } tools: list[ToolParam] = [ { "name": "get_weather", "description": "Get the weather for a specific location", "input_schema": { "type": "object", "properties": {"location": {"type": "string"}}, }, } ] message = client.messages.create( model="claude-sonnet-4-5-20250929", max_tokens=1024, messages=[user_message], tools=tools, ) print(f"Initial response: {message.model_dump_json(indent=2)}") assert message.stop_reason == "tool_use" tool = next(c for c in message.content if c.type == "tool_use") response = client.messages.create( model="claude-sonnet-4-5-20250929", max_tokens=1024, messages=[ user_message, {"role": message.role, "content": message.content}, { "role": "user", "content": [ { "type": "tool_result", "tool_use_id": tool.id, "content": [{"type": "text", "text": "The weather is 73f"}], } ], }, ], tools=tools, ) print(f"\nFinal response: {response.model_dump_json(indent=2)}") anthropic-sdk-python-0.69.0/examples/tools_runner.py000066400000000000000000000030001506653454500226220ustar00rootroot00000000000000import json from typing_extensions import Literal import rich from anthropic import Anthropic, beta_tool client = Anthropic() @beta_tool def get_weather(location: str, units: Literal["c", "f"]) -> str: """Lookup the weather for a given city in either celsius or fahrenheit Args: location: The city and state, e.g. San Francisco, CA units: Unit for the output, either 'c' for celsius or 'f' for fahrenheit Returns: A dictionary containing the location, temperature, and weather condition. """ # Simulate a weather API call print(f"Fetching weather for {location} in {units}") # Here you would typically make an API call to a weather service # For demonstration, we return a mock response if units == "c": return json.dumps( { "location": location, "temperature": "20°C", "condition": "Sunny", } ) else: return json.dumps( { "location": location, "temperature": "68°F", "condition": "Sunny", } ) def main() -> None: runner = client.beta.messages.tool_runner( max_tokens=1024, model="claude-3-5-sonnet-latest", # alternatively, you can use `tools=[anthropic.beta_tool(get_weather)]` tools=[get_weather], messages=[{"role": "user", "content": "What is the weather in SF?"}], ) for message in runner: rich.print(message) main() anthropic-sdk-python-0.69.0/examples/tools_stream.py000066400000000000000000000023451506653454500226170ustar00rootroot00000000000000import asyncio from anthropic import AsyncAnthropic client = AsyncAnthropic() async def main() -> None: async with client.messages.stream( max_tokens=1024, model="claude-sonnet-4-5-20250929", tools=[ { "name": "get_weather", "description": "Get the weather at a specific location", "input_schema": { "type": "object", "properties": { "location": {"type": "string", "description": "The city and state, e.g. San Francisco, CA"}, "unit": { "type": "string", "enum": ["celsius", "fahrenheit"], "description": "Unit for the output", }, }, "required": ["location"], }, } ], messages=[{"role": "user", "content": "What is the weather in SF?"}], ) as stream: async for event in stream: if event.type == "input_json": print(f"delta: {repr(event.partial_json)}") print(f"snapshot: {event.snapshot}") print() asyncio.run(main()) anthropic-sdk-python-0.69.0/examples/vertex.py000066400000000000000000000015521506653454500214200ustar00rootroot00000000000000import asyncio from anthropic import AnthropicVertex, AsyncAnthropicVertex def sync_client() -> None: print("------ Sync Vertex ------") client = AnthropicVertex() message = client.messages.create( model="claude-sonnet-4@20250514", max_tokens=100, messages=[ { "role": "user", "content": "Hello!", } ], ) print(message.to_json()) async def async_client() -> None: print("------ Async Vertex ------") client = AsyncAnthropicVertex() message = await client.messages.create( model="claude-sonnet-4@20250514", max_tokens=1024, messages=[ { "role": "user", "content": "Hello!", } ], ) print(message.to_json()) sync_client() asyncio.run(async_client()) anthropic-sdk-python-0.69.0/examples/web_search.py000066400000000000000000000017201506653454500222020ustar00rootroot00000000000000from __future__ import annotations from anthropic import Anthropic client = Anthropic() # Create a message with web search enabled message = client.messages.create( model="claude-sonnet-4-5-20250929", max_tokens=1024, messages=[{"role": "user", "content": "What's the weather in New York?"}], tools=[ { "name": "web_search", "type": "web_search_20250305", } ], ) # Print the full response print("\nFull response:") print(message.model_dump_json(indent=2)) # Extract and print the content print("\nResponse content:") for content_block in message.content: if content_block.type == "text": print(content_block.text) # Print usage information print("\nUsage statistics:") print(f"Input tokens: {message.usage.input_tokens}") print(f"Output tokens: {message.usage.output_tokens}") if message.usage.server_tool_use: print(f"Web search requests: {message.usage.server_tool_use.web_search_requests}") anthropic-sdk-python-0.69.0/examples/web_search_stream.py000066400000000000000000000043071506653454500235610ustar00rootroot00000000000000import asyncio from anthropic import AsyncAnthropic async def main() -> None: client = AsyncAnthropic() print("Claude with Web Search (Streaming)") print("==================================") # Create an async stream with web search enabled async with client.beta.messages.stream( model="claude-sonnet-4-5-20250929", max_tokens=1024, messages=[{"role": "user", "content": "What's the weather in New York?"}], tools=[ { "name": "web_search", "type": "web_search_20250305", } ], ) as stream: # Process streaming events async for chunk in stream: # Print text deltas as they arrive if chunk.type == "content_block_delta" and chunk.delta.type == "text_delta": print(chunk.delta.text, end="", flush=True) # Track when web search is being used elif chunk.type == "content_block_start" and chunk.content_block.type == "web_search_tool_result": print("\n[Web search started...]", end="", flush=True) elif chunk.type == "content_block_stop" and chunk.content_block.type == "web_search_tool_result": print("[Web search completed]", end="\n\n", flush=True) # Get the final complete message message = await stream.get_final_message() print("\n\nFinal usage statistics:") print(f"Input tokens: {message.usage.input_tokens}") print(f"Output tokens: {message.usage.output_tokens}") if message.usage.server_tool_use: print(f"Web search requests: {message.usage.server_tool_use.web_search_requests}") else: print("No web search requests recorded in usage") # Rather than parsing the web search results structure (which varies), # we'll just show the complete message structure for debugging print("\nMessage Content Types:") for i, block in enumerate(message.content): print(f"Content Block {i + 1}: Type = {block.type}") # Show the entire message structure as JSON for debugging print("\nComplete message structure (JSON):") print(message.model_dump_json(indent=2)) if __name__ == "__main__": asyncio.run(main()) anthropic-sdk-python-0.69.0/helpers.md000066400000000000000000000072011506653454500176740ustar00rootroot00000000000000# Message Helpers ## Streaming Responses ```python async with client.messages.stream( max_tokens=1024, messages=[ { "role": "user", "content": "Say hello there!", } ], model="claude-3-5-sonnet-latest", ) as stream: async for text in stream.text_stream: print(text, end="", flush=True) print() ``` `client.messages.stream()` returns a `MessageStreamManager`, which is a context manager that yields a `MessageStream` which is iterable, emits events and accumulates messages. Alternatively, you can use `client.messages.create(..., stream=True)` which returns an iterable of the events in the stream and uses less memory (most notably, it does not accumulate a final message object for you). The stream will be cancelled when the context manager exits but you can also close it prematurely by calling `stream.close()`. See an example of streaming helpers in action in [`examples/messages_stream.py`](examples/messages_stream.py). > [!NOTE] > The synchronous client has the same interface just without `async/await`. ### Lenses #### `.text_stream` Provides an iterator over just the text deltas in the stream: ```py async for text in stream.text_stream: print(text, end="", flush=True) print() ``` ### Events The events listed here are just the event types that the SDK extends, for a full list of the events returned by the API, see [these docs](https://docs.anthropic.com/en/api/messages-streaming#event-types). ```py from anthropic import AsyncAnthropic client = AsyncAnthropic() async with client.messages.stream( max_tokens=1024, messages=[ { "role": "user", "content": "Say hello there!", } ], model="claude-3-5-sonnet-latest", ) as stream: async for event in stream: if event.type == "text": print(event.text, end="", flush=True) elif event.type == 'content_block_stop': print('\n\ncontent block finished accumulating:', event.content_block) print() # you can still get the accumulated final message outside of # the context manager, as long as the entire stream was consumed # inside of the context manager accumulated = await stream.get_final_message() print("accumulated message: ", accumulated.to_json()) ``` #### `text` This event is yielded whenever a text `content_block_delta` event is returned by the API & includes the delta and the accumulated snapshot, e.g. ```py if event.type == "text": event.text # " there" event.snapshot # "Hello, there" ``` #### `input_json` This event is yielded whenever a JSON `content_block_delta` event is returned by the API & includes the delta and the accumulated snapshot, e.g. ```py if event.type == "input_json": event.partial_json # ' there"' event.snapshot # '{"message": "Hello, there"' ``` #### `message_stop` The event is fired when a full Message object has been accumulated. ```py if event.type == "message_stop": event.message # Message ``` #### `content_block_stop` The event is fired when a full ContentBlock object has been accumulated. ```py if event.type == "content_block_stop": event.content_block # ContentBlock ``` ### Methods #### `await .close()` Aborts the request. #### `await .until_done()` Blocks until the stream has been read to completion. #### `await .get_final_message()` Blocks until the stream has been read to completion and returns the accumulated `Message` object. #### `await .get_final_text()` > [!NOTE] > Currently the API will only ever return 1 content block Blocks until the stream has been read to completion and returns all `text` content blocks concatenated together. anthropic-sdk-python-0.69.0/pyproject.toml000066400000000000000000000143721506653454500206330ustar00rootroot00000000000000[project] name = "anthropic" version = "0.69.0" description = "The official Python library for the anthropic API" dynamic = ["readme"] license = "MIT" authors = [ { name = "Anthropic", email = "support@anthropic.com" }, ] dependencies = [ "httpx>=0.25.0, <1", "pydantic>=1.9.0, <3", "typing-extensions>=4.10, <5", "anyio>=3.5.0, <5", "distro>=1.7.0, <2", "sniffio", "jiter>=0.4.0, <1", "docstring-parser>=0.15,<1", ] requires-python = ">= 3.8" classifiers = [ "Typing :: Typed", "Intended Audience :: Developers", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Operating System :: OS Independent", "Operating System :: POSIX", "Operating System :: MacOS", "Operating System :: POSIX :: Linux", "Operating System :: Microsoft :: Windows", "Topic :: Software Development :: Libraries :: Python Modules", "License :: OSI Approved :: MIT License" ] [project.optional-dependencies] aiohttp = ["aiohttp", "httpx_aiohttp>=0.1.8"] vertex = ["google-auth[requests] >=2, <3"] bedrock = ["boto3 >= 1.28.57", "botocore >= 1.31.57"] [project.urls] Homepage = "https://github.com/anthropics/anthropic-sdk-python" Repository = "https://github.com/anthropics/anthropic-sdk-python" [tool.uv] managed = true required-version = ">=0.5.0" conflicts = [ [ { group = "pydantic-v1" }, { group = "pydantic-v2" }, ], ] [dependency-groups] # version pins are in uv.lock dev = [ "pyright==1.1.399", "mypy", "respx", "pytest", "pytest-asyncio", "ruff", "time-machine", "dirty-equals>=0.6.0", "importlib-metadata>=6.7.0", "boto3-stubs >= 1", "rich>=13.7.1", "pytest-xdist>=3.6.1", "inline-snapshot>=0.28.0", "griffe>=1", ] pydantic-v1 = [ "pydantic>=1.9.0,<2", ] pydantic-v2 = [ "pydantic>=2,<3", ] [build-system] requires = ["hatchling==1.26.3", "hatch-fancy-pypi-readme"] build-backend = "hatchling.build" [tool.hatch.build] include = [ "src/*" ] [tool.hatch.build.targets.wheel] packages = ["src/anthropic"] [tool.hatch.build.targets.sdist] # Basically everything except hidden files/directories (such as .github, .devcontainers, .python-version, etc) include = [ "/*.toml", "/*.json", "/*.lock", "/*.md", "/mypy.ini", "/noxfile.py", "bin/*", "examples/*", "src/*", "tests/*", ] [tool.hatch.metadata.hooks.fancy-pypi-readme] content-type = "text/markdown" [[tool.hatch.metadata.hooks.fancy-pypi-readme.fragments]] path = "README.md" [[tool.hatch.metadata.hooks.fancy-pypi-readme.substitutions]] # replace relative links with absolute links pattern = '\[(.+?)\]\(((?!https?://)\S+?)\)' replacement = '[\1](https://github.com/anthropics/anthropic-sdk-python/tree/main/\g<2>)' [tool.pytest.ini_options] testpaths = ["tests"] addopts = "--tb=short -n auto" xfail_strict = true asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "session" filterwarnings = [ "error" ] [tool.inline-snapshot] format-command="ruff format --stdin-filename {filename}" [tool.pyright] # this enables practically every flag given by pyright. # there are a couple of flags that are still disabled by # default in strict mode as they are experimental and niche. typeCheckingMode = "strict" pythonVersion = "3.8" exclude = [ ".git", "_dev", ".venv", ".nox", ] reportImplicitOverride = true reportOverlappingOverload = false reportImportCycles = false reportPrivateUsage = false [tool.mypy] pretty = true show_error_codes = true # Exclude _files.py because mypy isn't smart enough to apply # the correct type narrowing and as this is an internal module # it's fine to just use Pyright. # # We also exclude our `tests` as mypy doesn't always infer # types correctly and Pyright will still catch any type errors. exclude = ['src/anthropic/_files.py', '_dev/.*.py', 'tests/.*', 'examples/mcp_server_weather.py', 'examples/tools_with_mcp.py', 'examples/memory/basic.py'] strict_equality = true implicit_reexport = true check_untyped_defs = true no_implicit_optional = true warn_return_any = true warn_unreachable = true warn_unused_configs = true # Turn these options off as it could cause conflicts # with the Pyright options. warn_unused_ignores = false warn_redundant_casts = false disallow_any_generics = true disallow_untyped_defs = true disallow_untyped_calls = true disallow_subclassing_any = true disallow_incomplete_defs = true disallow_untyped_decorators = true cache_fine_grained = true # By default, mypy reports an error if you assign a value to the result # of a function call that doesn't return anything. We do this in our test # cases: # ``` # result = ... # assert result is None # ``` # Changing this codegen to make mypy happy would increase complexity # and would not be worth it. disable_error_code = "func-returns-value,overload-cannot-match" # https://github.com/python/mypy/issues/12162 [[tool.mypy.overrides]] module = "black.files.*" ignore_errors = true ignore_missing_imports = true [[tool.mypy.overrides]] module = "anthropic.lib.vertex._auth" disallow_untyped_calls = false [tool.ruff] line-length = 120 output-format = "grouped" target-version = "py38" [tool.ruff.format] docstring-code-format = true [tool.ruff.lint] select = [ # isort "I", # bugbear rules "B", # remove unused imports "F401", # bare except statements "E722", # unused arguments "ARG", # print statements "T201", "T203", # misuse of typing.TYPE_CHECKING "TC004", # import rules "TID251", ] ignore = [ # mutable defaults "B006", ] unfixable = [ # disable auto fix for print statements "T201", "T203", ] [tool.ruff.lint.flake8-tidy-imports.banned-api] "functools.lru_cache".msg = "This function does not retain type information for the wrapped function's arguments; The `lru_cache` function from `_utils` should be used instead" [tool.ruff.lint.isort] length-sort = true length-sort-straight = true combine-as-imports = true extra-standard-library = ["typing_extensions"] known-first-party = ["anthropic", "tests"] [tool.ruff.lint.per-file-ignores] "bin/**.py" = ["T201", "T203"] "scripts/**.py" = ["T201", "T203"] "tests/**.py" = ["T201", "T203"] "examples/**.py" = ["T201", "T203"] anthropic-sdk-python-0.69.0/release-please-config.json000066400000000000000000000024551506653454500227430ustar00rootroot00000000000000{ "packages": { ".": {} }, "$schema": "https://raw.githubusercontent.com/stainless-api/release-please/main/schemas/config.json", "include-v-in-tag": true, "include-component-in-tag": false, "versioning": "prerelease", "prerelease": true, "bump-minor-pre-major": true, "bump-patch-for-minor-pre-major": false, "pull-request-header": "Automated Release PR", "pull-request-title-pattern": "release: ${version}", "changelog-sections": [ { "type": "feat", "section": "Features" }, { "type": "fix", "section": "Bug Fixes" }, { "type": "perf", "section": "Performance Improvements" }, { "type": "revert", "section": "Reverts" }, { "type": "chore", "section": "Chores" }, { "type": "docs", "section": "Documentation" }, { "type": "style", "section": "Styles" }, { "type": "refactor", "section": "Refactors" }, { "type": "test", "section": "Tests", "hidden": true }, { "type": "build", "section": "Build System" }, { "type": "ci", "section": "Continuous Integration", "hidden": true } ], "release-type": "python", "extra-files": [ "src/anthropic/_version.py" ] }anthropic-sdk-python-0.69.0/requirements-dev.lock000066400000000000000000000070361506653454500220670ustar00rootroot00000000000000# 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.5.2 ; python_full_version < '3.9' # via # anthropic # httpx anyio==4.8.0 ; python_full_version >= '3.9' # via # anthropic # httpx asttokens==3.0.0 # via inline-snapshot astunparse==1.6.3 ; python_full_version < '3.9' # via griffe boto3-stubs==1.40.31 botocore-stubs==1.38.30 ; python_full_version < '3.9' # via boto3-stubs botocore-stubs==1.40.31 ; python_full_version >= '3.9' # via boto3-stubs certifi==2024.12.14 # via # httpcore # httpx colorama==0.4.6 # via # griffe # pytest dirty-equals==0.9.0 distro==1.9.0 # via anthropic docstring-parser==0.17.0 # via anthropic exceptiongroup==1.2.2 ; python_full_version < '3.11' # via # anyio # pytest execnet==2.1.1 # via pytest-xdist executing==2.2.1 # via inline-snapshot griffe==1.4.0 ; python_full_version < '3.9' griffe==1.13.0 ; python_full_version >= '3.9' h11==0.16.0 # via httpcore httpcore==1.0.9 # via httpx httpx==0.28.1 # via # anthropic # respx idna==3.10 # via # anyio # httpx importlib-metadata==8.5.0 ; python_full_version < '3.9' importlib-metadata==8.6.1 ; python_full_version >= '3.9' iniconfig==2.0.0 # via pytest inline-snapshot==0.29.0 jiter==0.9.1 ; python_full_version < '3.9' # via anthropic jiter==0.11.0 ; python_full_version >= '3.9' # via anthropic markdown-it-py==3.0.0 # via rich mdurl==0.1.2 # via markdown-it-py mypy==1.14.1 mypy-extensions==1.0.0 # via mypy nodeenv==1.9.1 # via pyright packaging==24.2 # via pytest pluggy==1.5.0 # via pytest pydantic==2.10.6 ; python_full_version < '3.9' # via anthropic pydantic==2.11.9 ; python_full_version >= '3.9' # via anthropic pydantic-core==2.27.2 ; python_full_version < '3.9' # via pydantic pydantic-core==2.33.2 ; python_full_version >= '3.9' # via pydantic pygments==2.19.1 # via # pytest # rich pyright==1.1.399 pytest==8.3.5 ; python_full_version < '3.9' # via # inline-snapshot # pytest-asyncio # pytest-xdist pytest==8.4.1 ; python_full_version >= '3.9' # via # inline-snapshot # pytest-asyncio # pytest-xdist pytest-asyncio==0.24.0 pytest-xdist==3.6.1 ; python_full_version < '3.9' pytest-xdist==3.7.0 ; python_full_version >= '3.9' python-dateutil==2.9.0.post0 # via time-machine pytz==2024.2 ; python_full_version < '3.9' # via dirty-equals respx==0.22.0 rich==13.9.4 # via inline-snapshot ruff==0.9.4 six==1.17.0 # via # astunparse # python-dateutil sniffio==1.3.1 # via # anthropic # anyio time-machine==2.15.0 ; python_full_version < '3.9' time-machine==2.16.0 ; python_full_version >= '3.9' tomli==2.2.1 ; python_full_version < '3.11' # via # inline-snapshot # mypy # pytest types-awscrt==0.27.6 # via botocore-stubs types-s3transfer==0.13.1 # via boto3-stubs typing-extensions==4.12.2 # via # annotated-types # anthropic # anyio # boto3-stubs # mypy # pydantic # pydantic-core # pyright # rich # typing-inspection typing-inspection==0.4.1 ; python_full_version >= '3.9' # via pydantic wheel==0.45.1 ; python_full_version < '3.9' # via astunparse zipp==3.20.2 ; python_full_version < '3.9' # via importlib-metadata zipp==3.21.0 ; python_full_version >= '3.9' # via importlib-metadata anthropic-sdk-python-0.69.0/scripts/000077500000000000000000000000001506653454500173775ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/scripts/bootstrap000077500000000000000000000012631506653454500213440ustar00rootroot00000000000000#!/usr/bin/env bash set -e cd "$(dirname "$0")/.." 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 case "$response" in [yY][eE][sS]|[yY]) brew bundle ;; *) ;; esac echo } fi echo "==> Installing Python…" uv python install echo "==> Installing Python dependencies…" uv sync --all-extras 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 anthropic-sdk-python-0.69.0/scripts/detect-breaking-changes000077500000000000000000000010251506653454500237610ustar00rootroot00000000000000#!/usr/bin/env bash set -e cd "$(dirname "$0")/.." echo "==> Detecting breaking changes" TEST_PATHS=( tests/api_resources tests/test_client.py tests/test_response.py tests/test_legacy_response.py ) for PATHSPEC in "${TEST_PATHS[@]}"; do # Try to check out previous versions of the test files # with the current SDK. git checkout "$1" -- "${PATHSPEC}" 2>/dev/null || true done # Instead of running the tests, use the linter to check if an # older test is no longer compatible with the latest SDK. ./scripts/lint anthropic-sdk-python-0.69.0/scripts/detect-breaking-changes.py000066400000000000000000000046721506653454500244200ustar00rootroot00000000000000from __future__ import annotations import sys from typing import Iterator from pathlib import Path import rich import griffe from rich.text import Text from rich.style import Style def public_members(obj: griffe.Object | griffe.Alias) -> dict[str, griffe.Object | griffe.Alias]: if isinstance(obj, griffe.Alias): # ignore imports for now, they're technically part of the public API # but we don't have good preventative measures in place to prevent # changing them return {} return {name: value for name, value in obj.all_members.items() if not name.startswith("_")} def find_breaking_changes( new_obj: griffe.Object | griffe.Alias, old_obj: griffe.Object | griffe.Alias, *, path: list[str], ) -> Iterator[Text | str]: new_members = public_members(new_obj) old_members = public_members(old_obj) for name, old_member in old_members.items(): if isinstance(old_member, griffe.Alias) and len(path) > 2: # ignore imports in `/types/` for now, they're technically part of the public API # but we don't have good preventative measures in place to prevent changing them continue new_member = new_members.get(name) if new_member is None: cls_name = old_member.__class__.__name__ yield Text(f"({cls_name})", style=Style(color="rgb(119, 119, 119)")) yield from [" " for _ in range(10 - len(cls_name))] yield f" {'.'.join(path)}.{name}" yield "\n" continue yield from find_breaking_changes(new_member, old_member, path=[*path, name]) def main() -> None: try: against_ref = sys.argv[1] except IndexError as err: raise RuntimeError("You must specify a base ref to run breaking change detection against") from err package = griffe.load( "anthropic", search_paths=[Path(__file__).parent.parent.joinpath("src")], ) old_package = griffe.load_git( "anthropic", ref=against_ref, search_paths=["src"], ) assert isinstance(package, griffe.Module) assert isinstance(old_package, griffe.Module) output = list(find_breaking_changes(package, old_package, path=["anthropic"])) if output: rich.print(Text("Breaking changes detected!", style=Style(color="rgb(165, 79, 87)"))) rich.print() for text in output: rich.print(text, end="") sys.exit(1) main() anthropic-sdk-python-0.69.0/scripts/format000077500000000000000000000004621506653454500206170ustar00rootroot00000000000000#!/usr/bin/env bash set -e cd "$(dirname "$0")/.." 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 api.md anthropic-sdk-python-0.69.0/scripts/lint000077500000000000000000000003731506653454500202760ustar00rootroot00000000000000#!/usr/bin/env bash set -e cd "$(dirname "$0")/.." echo "==> Running ruff" uv run ruff check . echo "==> Running pyright" uv run pyright echo "==> Running mypy" uv run mypy . echo "==> Making sure it imports" uv run python -c 'import anthropic' anthropic-sdk-python-0.69.0/scripts/mock000077500000000000000000000015471506653454500202650ustar00rootroot00000000000000#!/usr/bin/env bash set -e cd "$(dirname "$0")/.." if [[ -n "$1" && "$1" != '--'* ]]; then URL="$1" shift 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 fi echo "==> Starting mock server with URL ${URL}" # Run prism mock on the given spec if [ "$1" == "--daemon" ]; then npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" &> .prism.log & # Wait for server to come online echo -n "Waiting for server" while ! grep -q "✖ fatal\|Prism is listening" ".prism.log" ; do 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" fi anthropic-sdk-python-0.69.0/scripts/test000077500000000000000000000036241506653454500203110ustar00rootroot00000000000000#!/usr/bin/env bash set -e cd "$(dirname "$0")/.." RED='\033[0;31m' 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 } kill_server_on_port() { pids=$(lsof -t -i tcp:"$1" || echo "") if [ "$pids" != "" ]; then kill "$pids" echo "Stopped $pids." fi } function is_overriding_api_base_url() { [ -n "$TEST_API_BASE_URL" ] } if ! is_overriding_api_base_url && ! prism_is_running ; then # When we exit this script, make sure to kill the background mock server process trap 'kill_server_on_port 4010' EXIT # Start the dev server ./scripts/mock --daemon 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" 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 echo -e " \$ ${YELLOW}npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock path/to/your.openapi.yml${NC}" echo exit 1 else echo -e "${GREEN}✔ Mock prism server is running with your OpenAPI spec${NC}" echo fi export DEFER_PYDANTIC_BUILD=false function run_tests() { echo "==> Running tests with Pydantic v2" uv run --isolated --all-extras pytest "$@" echo "==> Running tests with Pydantic v1" uv run --isolated --all-extras --group=pydantic-v1 pytest "$@" } # 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 3.8" UV_PYTHON=3.8 run_tests "$@" echo "==> Running tests for Python 3.13" UV_PYTHON=3.13 run_tests "$@" fi anthropic-sdk-python-0.69.0/scripts/utils/000077500000000000000000000000001506653454500205375ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/scripts/utils/ruffen-docs.py000066400000000000000000000121401506653454500233220ustar00rootroot00000000000000# fork of https://github.com/asottile/blacken-docs adapted for ruff from __future__ import annotations import re import sys import argparse import textwrap import contextlib import subprocess from typing import Match, Optional, Sequence, Generator, NamedTuple, cast MD_RE = re.compile( r"(?P^(?P *)```\s*python\n)" r"(?P.*?)" r"(?P^(?P=indent)```\s*$)", re.DOTALL | re.MULTILINE, ) MD_PYCON_RE = re.compile( r"(?P^(?P *)```\s*pycon\n)" r"(?P.*?)" r"(?P^(?P=indent)```.*$)", re.DOTALL | re.MULTILINE, ) PYCON_PREFIX = ">>> " PYCON_CONTINUATION_PREFIX = "..." PYCON_CONTINUATION_RE = re.compile( rf"^{re.escape(PYCON_CONTINUATION_PREFIX)}( |$)", ) DEFAULT_LINE_LENGTH = 100 class CodeBlockError(NamedTuple): offset: int exc: Exception def format_str( src: str, ) -> tuple[str, Sequence[CodeBlockError]]: errors: list[CodeBlockError] = [] @contextlib.contextmanager def _collect_error(match: Match[str]) -> Generator[None, None, None]: try: yield except Exception as e: errors.append(CodeBlockError(match.start(), e)) def _md_match(match: Match[str]) -> str: code = textwrap.dedent(match["code"]) with _collect_error(match): code = format_code_block(code) code = textwrap.indent(code, match["indent"]) return f"{match['before']}{code}{match['after']}" def _pycon_match(match: Match[str]) -> str: code = "" fragment = cast(Optional[str], None) def finish_fragment() -> None: nonlocal code nonlocal fragment if fragment is not None: with _collect_error(match): fragment = format_code_block(fragment) fragment_lines = fragment.splitlines() code += f"{PYCON_PREFIX}{fragment_lines[0]}\n" for line in fragment_lines[1:]: # Skip blank lines to handle Black adding a blank above # functions within blocks. A blank line would end the REPL # continuation prompt. # # >>> if True: # ... def f(): # ... pass # ... if line: code += f"{PYCON_CONTINUATION_PREFIX} {line}\n" if fragment_lines[-1].startswith(" "): code += f"{PYCON_CONTINUATION_PREFIX}\n" fragment = None indentation = None for line in match["code"].splitlines(): orig_line, line = line, line.lstrip() if indentation is None and line: indentation = len(orig_line) - len(line) continuation_match = PYCON_CONTINUATION_RE.match(line) if continuation_match and fragment is not None: fragment += line[continuation_match.end() :] + "\n" else: finish_fragment() if line.startswith(PYCON_PREFIX): fragment = line[len(PYCON_PREFIX) :] + "\n" else: code += orig_line[indentation:] + "\n" finish_fragment() return code def _md_pycon_match(match: Match[str]) -> str: code = _pycon_match(match) code = textwrap.indent(code, match["indent"]) return f"{match['before']}{code}{match['after']}" src = MD_RE.sub(_md_match, src) src = MD_PYCON_RE.sub(_md_pycon_match, src) return src, errors def format_code_block(code: str) -> str: return subprocess.check_output( [ sys.executable, "-m", "ruff", "format", "--stdin-filename=script.py", f"--line-length={DEFAULT_LINE_LENGTH}", ], encoding="utf-8", input=code, ) def format_file( filename: str, skip_errors: bool, ) -> int: with open(filename, encoding="UTF-8") as f: contents = f.read() new_contents, errors = format_str(contents) for error in errors: lineno = contents[: error.offset].count("\n") + 1 print(f"{filename}:{lineno}: code block parse error {error.exc}") if errors and not skip_errors: return 1 if contents != new_contents: print(f"{filename}: Rewriting...") with open(filename, "w", encoding="UTF-8") as f: f.write(new_contents) return 0 else: return 0 def main(argv: Sequence[str] | None = None) -> int: parser = argparse.ArgumentParser() parser.add_argument( "-l", "--line-length", type=int, default=DEFAULT_LINE_LENGTH, ) parser.add_argument( "-S", "--skip-string-normalization", action="store_true", ) parser.add_argument("-E", "--skip-errors", action="store_true") parser.add_argument("filenames", nargs="*") args = parser.parse_args(argv) retv = 0 for filename in args.filenames: retv |= format_file(filename, skip_errors=args.skip_errors) return retv if __name__ == "__main__": raise SystemExit(main()) anthropic-sdk-python-0.69.0/scripts/utils/upload-artifact.sh000077500000000000000000000014371506653454500241620ustar00rootroot00000000000000#!/usr/bin/env bash set -exuo pipefail FILENAME=$(basename dist/*.whl) RESPONSE=$(curl -X POST "$URL?filename=$FILENAME" \ -H "Authorization: Bearer $AUTH" \ -H "Content-Type: application/json") SIGNED_URL=$(echo "$RESPONSE" | jq -r '.url') if [[ "$SIGNED_URL" == "null" ]]; then echo -e "\033[31mFailed to get signed URL.\033[0m" exit 1 fi UPLOAD_RESPONSE=$(curl -v -X PUT \ -H "Content-Type: binary/octet-stream" \ --data-binary "@dist/$FILENAME" "$SIGNED_URL" 2>&1) 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/anthropic-python/$SHA/$FILENAME'\033[0m" else echo -e "\033[31mFailed to upload artifact.\033[0m" exit 1 fi anthropic-sdk-python-0.69.0/src/000077500000000000000000000000001506653454500164775ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/000077500000000000000000000000001506653454500204665ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/__init__.py000066400000000000000000000056451506653454500226110ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import typing as _t from . import types from ._types import NOT_GIVEN, Omit, NoneType, NotGiven, Transport, ProxiesTypes, omit, not_given from ._utils import file_from_path from ._client import ( Client, Stream, Timeout, Anthropic, Transport, AsyncClient, AsyncStream, AsyncAnthropic, RequestOptions, ) from ._models import BaseModel from ._version import __title__, __version__ from ._response import APIResponse as APIResponse, AsyncAPIResponse as AsyncAPIResponse from ._constants import ( AI_PROMPT as AI_PROMPT, HUMAN_PROMPT as HUMAN_PROMPT, DEFAULT_TIMEOUT, DEFAULT_MAX_RETRIES, DEFAULT_CONNECTION_LIMITS, ) from ._exceptions import ( APIError, ConflictError, NotFoundError, AnthropicError, APIStatusError, RateLimitError, APITimeoutError, BadRequestError, APIConnectionError, AuthenticationError, InternalServerError, PermissionDeniedError, UnprocessableEntityError, APIResponseValidationError, ) from ._base_client import DefaultHttpxClient, DefaultAioHttpClient, DefaultAsyncHttpxClient from ._utils._logs import setup_logging as _setup_logging __all__ = [ "types", "__version__", "__title__", "NoneType", "Transport", "ProxiesTypes", "NotGiven", "NOT_GIVEN", "not_given", "Omit", "omit", "AnthropicError", "APIError", "APIStatusError", "APITimeoutError", "APIConnectionError", "APIResponseValidationError", "BadRequestError", "AuthenticationError", "PermissionDeniedError", "NotFoundError", "ConflictError", "UnprocessableEntityError", "RateLimitError", "InternalServerError", "Timeout", "RequestOptions", "Client", "AsyncClient", "Stream", "AsyncStream", "Anthropic", "AsyncAnthropic", "file_from_path", "BaseModel", "DEFAULT_TIMEOUT", "DEFAULT_MAX_RETRIES", "DEFAULT_CONNECTION_LIMITS", "DefaultHttpxClient", "DefaultAsyncHttpxClient", "DefaultAioHttpClient", "HUMAN_PROMPT", "AI_PROMPT", "beta_tool", "beta_async_tool", ] if not _t.TYPE_CHECKING: from ._utils._resources_proxy import resources as resources from .lib.tools import beta_tool, beta_async_tool from .lib.vertex import * from .lib.bedrock import * from .lib.streaming import * _setup_logging() # Update the __module__ attribute for exported symbols so that # error messages point to this module instead of the module # it was originally defined in, e.g. # anthropic._exceptions.NotFoundError -> anthropic.NotFoundError __locals = locals() for __name in __all__: if not __name.startswith("__"): try: __locals[__name].__module__ = "anthropic" except (TypeError, AttributeError): # Some of our exported symbols are builtins which we can't set attributes for. pass anthropic-sdk-python-0.69.0/src/anthropic/_base_client.py000066400000000000000000002162211506653454500234530ustar00rootroot00000000000000from __future__ import annotations import sys import json import time import uuid import email import socket import asyncio import inspect import logging import platform import email.utils from types import TracebackType from random import random from typing import ( TYPE_CHECKING, Any, Dict, List, Type, Tuple, Union, Generic, Mapping, TypeVar, Iterable, Iterator, Optional, Generator, AsyncIterator, cast, overload, ) from typing_extensions import Literal, override, get_origin import anyio import httpx import distro import pydantic from httpx import URL, Proxy, HTTPTransport, AsyncHTTPTransport from pydantic import PrivateAttr from . import _exceptions from ._qs import Querystring from ._files import to_httpx_files, async_to_httpx_files from ._types import ( Body, Omit, Query, Headers, Timeout, NotGiven, ResponseT, AnyMapping, PostParser, RequestFiles, HttpxSendArgs, RequestOptions, HttpxRequestFiles, ModelBuilderProtocol, not_given, ) from ._utils import is_dict, is_list, asyncify, is_given, lru_cache, is_mapping from ._compat import PYDANTIC_V1, model_copy, model_dump from ._models import GenericModel, FinalRequestOptions, validate_type, construct_type from ._response import ( APIResponse, BaseAPIResponse, AsyncAPIResponse, extract_response_type, ) from ._constants import ( DEFAULT_TIMEOUT, MAX_RETRY_DELAY, DEFAULT_MAX_RETRIES, INITIAL_RETRY_DELAY, RAW_RESPONSE_HEADER, OVERRIDE_CAST_TO_HEADER, DEFAULT_CONNECTION_LIMITS, ) from ._streaming import Stream, SSEDecoder, AsyncStream, SSEBytesDecoder from ._exceptions import ( APIStatusError, APITimeoutError, APIConnectionError, APIResponseValidationError, ) from ._utils._httpx import get_environment_proxies from ._legacy_response import LegacyAPIResponse log: logging.Logger = logging.getLogger(__name__) # TODO: make base page type vars covariant SyncPageT = TypeVar("SyncPageT", bound="BaseSyncPage[Any]") AsyncPageT = TypeVar("AsyncPageT", bound="BaseAsyncPage[Any]") _T = TypeVar("_T") _T_co = TypeVar("_T_co", covariant=True) _StreamT = TypeVar("_StreamT", bound=Stream[Any]) _AsyncStreamT = TypeVar("_AsyncStreamT", bound=AsyncStream[Any]) if TYPE_CHECKING: from httpx._config import ( DEFAULT_TIMEOUT_CONFIG, # pyright: ignore[reportPrivateImportUsage] ) HTTPX_DEFAULT_TIMEOUT = DEFAULT_TIMEOUT_CONFIG else: try: from httpx._config import DEFAULT_TIMEOUT_CONFIG as HTTPX_DEFAULT_TIMEOUT except ImportError: # taken from https://github.com/encode/httpx/blob/3ba5fe0d7ac70222590e759c31442b1cab263791/httpx/_config.py#L366 HTTPX_DEFAULT_TIMEOUT = Timeout(5.0) class PageInfo: """Stores the necessary information to build the request to retrieve the next page. Either `url` or `params` must be set. """ url: URL | NotGiven params: Query | NotGiven json: Body | NotGiven @overload def __init__( self, *, url: URL, ) -> None: ... @overload def __init__( self, *, params: Query, ) -> None: ... @overload def __init__( self, *, json: Body, ) -> None: ... def __init__( self, *, url: URL | NotGiven = not_given, json: Body | NotGiven = not_given, params: Query | NotGiven = not_given, ) -> None: self.url = url self.json = json self.params = params @override def __repr__(self) -> str: if self.url: return f"{self.__class__.__name__}(url={self.url})" if self.json: return f"{self.__class__.__name__}(json={self.json})" return f"{self.__class__.__name__}(params={self.params})" class BasePage(GenericModel, Generic[_T]): """ Defines the core interface for pagination. Type Args: ModelT: The pydantic model that represents an item in the response. Methods: has_next_page(): Check if there is another page available next_page_info(): Get the necessary information to make a request for the next page """ _options: FinalRequestOptions = PrivateAttr() _model: Type[_T] = PrivateAttr() def has_next_page(self) -> bool: items = self._get_page_items() if not items: return False return self.next_page_info() is not None def next_page_info(self) -> Optional[PageInfo]: ... def _get_page_items(self) -> Iterable[_T]: # type: ignore[empty-body] ... def _params_from_url(self, url: URL) -> httpx.QueryParams: # TODO: do we have to preprocess params here? return httpx.QueryParams(cast(Any, self._options.params)).merge(url.params) def _info_to_options(self, info: PageInfo) -> FinalRequestOptions: options = model_copy(self._options) options._strip_raw_response_header() if not isinstance(info.params, NotGiven): options.params = {**options.params, **info.params} return options if not isinstance(info.url, NotGiven): params = self._params_from_url(info.url) url = info.url.copy_with(params=params) options.params = dict(url.params) options.url = str(url) return options if not isinstance(info.json, NotGiven): if not is_mapping(info.json): raise TypeError("Pagination is only supported with mappings") if not options.json_data: options.json_data = {**info.json} else: if not is_mapping(options.json_data): raise TypeError("Pagination is only supported with mappings") options.json_data = {**options.json_data, **info.json} return options raise ValueError("Unexpected PageInfo state") class BaseSyncPage(BasePage[_T], Generic[_T]): _client: SyncAPIClient = pydantic.PrivateAttr() def _set_private_attributes( self, client: SyncAPIClient, model: Type[_T], options: FinalRequestOptions, ) -> None: if (not PYDANTIC_V1) and getattr(self, "__pydantic_private__", None) is None: self.__pydantic_private__ = {} self._model = model self._client = client self._options = options # Pydantic uses a custom `__iter__` method to support casting BaseModels # to dictionaries. e.g. dict(model). # As we want to support `for item in page`, this is inherently incompatible # with the default pydantic behaviour. It is not possible to support both # use cases at once. Fortunately, this is not a big deal as all other pydantic # methods should continue to work as expected as there is an alternative method # to cast a model to a dictionary, model.dict(), which is used internally # by pydantic. def __iter__(self) -> Iterator[_T]: # type: ignore for page in self.iter_pages(): for item in page._get_page_items(): yield item def iter_pages(self: SyncPageT) -> Iterator[SyncPageT]: page = self while True: yield page if page.has_next_page(): page = page.get_next_page() else: return def get_next_page(self: SyncPageT) -> SyncPageT: info = self.next_page_info() if not info: raise RuntimeError( "No next page expected; please check `.has_next_page()` before calling `.get_next_page()`." ) options = self._info_to_options(info) return self._client._request_api_list(self._model, page=self.__class__, options=options) class AsyncPaginator(Generic[_T, AsyncPageT]): def __init__( self, client: AsyncAPIClient, options: FinalRequestOptions, page_cls: Type[AsyncPageT], model: Type[_T], ) -> None: self._model = model self._client = client self._options = options self._page_cls = page_cls def __await__(self) -> Generator[Any, None, AsyncPageT]: return self._get_page().__await__() async def _get_page(self) -> AsyncPageT: def _parser(resp: AsyncPageT) -> AsyncPageT: resp._set_private_attributes( model=self._model, options=self._options, client=self._client, ) return resp self._options.post_parser = _parser return await self._client.request(self._page_cls, self._options) async def __aiter__(self) -> AsyncIterator[_T]: # https://github.com/microsoft/pyright/issues/3464 page = cast( AsyncPageT, await self, # type: ignore ) async for item in page: yield item class BaseAsyncPage(BasePage[_T], Generic[_T]): _client: AsyncAPIClient = pydantic.PrivateAttr() def _set_private_attributes( self, model: Type[_T], client: AsyncAPIClient, options: FinalRequestOptions, ) -> None: if (not PYDANTIC_V1) and getattr(self, "__pydantic_private__", None) is None: self.__pydantic_private__ = {} self._model = model self._client = client self._options = options async def __aiter__(self) -> AsyncIterator[_T]: async for page in self.iter_pages(): for item in page._get_page_items(): yield item async def iter_pages(self: AsyncPageT) -> AsyncIterator[AsyncPageT]: page = self while True: yield page if page.has_next_page(): page = await page.get_next_page() else: return async def get_next_page(self: AsyncPageT) -> AsyncPageT: info = self.next_page_info() if not info: raise RuntimeError( "No next page expected; please check `.has_next_page()` before calling `.get_next_page()`." ) options = self._info_to_options(info) return await self._client._request_api_list(self._model, page=self.__class__, options=options) _HttpxClientT = TypeVar("_HttpxClientT", bound=Union[httpx.Client, httpx.AsyncClient]) _DefaultStreamT = TypeVar("_DefaultStreamT", bound=Union[Stream[Any], AsyncStream[Any]]) class BaseClient(Generic[_HttpxClientT, _DefaultStreamT]): _client: _HttpxClientT _version: str _base_url: URL max_retries: int timeout: Union[float, Timeout, None] _strict_response_validation: bool _idempotency_header: str | None _default_stream_cls: type[_DefaultStreamT] | None = None def __init__( self, *, version: str, base_url: str | URL, _strict_response_validation: bool, max_retries: int = DEFAULT_MAX_RETRIES, timeout: float | Timeout | None = DEFAULT_TIMEOUT, custom_headers: Mapping[str, str] | None = None, custom_query: Mapping[str, object] | None = None, ) -> None: self._version = version self._base_url = self._enforce_trailing_slash(URL(base_url)) self.max_retries = max_retries self.timeout = timeout self._custom_headers = custom_headers or {} self._custom_query = custom_query or {} self._strict_response_validation = _strict_response_validation self._idempotency_header = None self._platform: Platform | None = None if max_retries is None: # pyright: ignore[reportUnnecessaryComparison] raise TypeError( "max_retries cannot be None. If you want to disable retries, pass `0`; if you want unlimited retries, pass `math.inf` or a very high number; if you want the default behavior, pass `anthropic.DEFAULT_MAX_RETRIES`" ) def _enforce_trailing_slash(self, url: URL) -> URL: if url.raw_path.endswith(b"/"): return url return url.copy_with(raw_path=url.raw_path + b"/") def _make_status_error_from_response( self, response: httpx.Response, ) -> APIStatusError: if response.is_closed and not response.is_stream_consumed: # We can't read the response body as it has been closed # before it was read. This can happen if an event hook # raises a status error. body = None err_msg = f"Error code: {response.status_code}" else: err_text = response.text.strip() body = err_text try: body = json.loads(err_text) err_msg = f"Error code: {response.status_code} - {body}" except Exception: err_msg = err_text or f"Error code: {response.status_code}" return self._make_status_error(err_msg, body=body, response=response) def _make_status_error( self, err_msg: str, *, body: object, response: httpx.Response, ) -> _exceptions.APIStatusError: raise NotImplementedError() def _build_headers(self, options: FinalRequestOptions, *, retries_taken: int = 0) -> httpx.Headers: custom_headers = options.headers or {} headers_dict = _merge_mappings( { "x-stainless-timeout": str(options.timeout.read) if isinstance(options.timeout, Timeout) else str(options.timeout), **self.default_headers, }, custom_headers, ) self._validate_headers(headers_dict, custom_headers) # headers are case-insensitive while dictionaries are not. headers = httpx.Headers(headers_dict) idempotency_header = self._idempotency_header if idempotency_header and options.idempotency_key and idempotency_header not in headers: headers[idempotency_header] = options.idempotency_key # Don't set these headers if they were already set or removed by the caller. We check # `custom_headers`, which can contain `Omit()`, instead of `headers` to account for the removal case. lower_custom_headers = [header.lower() for header in custom_headers] if "x-stainless-retry-count" not in lower_custom_headers: headers["x-stainless-retry-count"] = str(retries_taken) if "x-stainless-read-timeout" not in lower_custom_headers: timeout = self.timeout if isinstance(options.timeout, NotGiven) else options.timeout if isinstance(timeout, Timeout): timeout = timeout.read if timeout is not None: headers["x-stainless-read-timeout"] = str(timeout) return headers def _prepare_url(self, url: str) -> URL: """ Merge a URL argument together with any 'base_url' on the client, to create the URL used for the outgoing request. """ # Copied from httpx's `_merge_url` method. merge_url = URL(url) if merge_url.is_relative_url: merge_raw_path = self.base_url.raw_path + merge_url.raw_path.lstrip(b"/") return self.base_url.copy_with(raw_path=merge_raw_path) return merge_url def _make_sse_decoder(self) -> SSEDecoder | SSEBytesDecoder: return SSEDecoder() def _build_request( self, options: FinalRequestOptions, *, retries_taken: int = 0, ) -> httpx.Request: if log.isEnabledFor(logging.DEBUG): log.debug("Request options: %s", model_dump(options, exclude_unset=True)) kwargs: dict[str, Any] = {} json_data = options.json_data if options.extra_json is not None: if json_data is None: json_data = cast(Body, options.extra_json) elif is_mapping(json_data): json_data = _merge_mappings(json_data, options.extra_json) else: raise RuntimeError(f"Unexpected JSON data type, {type(json_data)}, cannot merge with `extra_body`") headers = self._build_headers(options, retries_taken=retries_taken) params = _merge_mappings(self.default_query, options.params) content_type = headers.get("Content-Type") files = options.files # If the given Content-Type header is multipart/form-data then it # has to be removed so that httpx can generate the header with # additional information for us as it has to be in this form # for the server to be able to correctly parse the request: # multipart/form-data; boundary=---abc-- if content_type is not None and content_type.startswith("multipart/form-data"): if "boundary" not in content_type: # only remove the header if the boundary hasn't been explicitly set # as the caller doesn't want httpx to come up with their own boundary headers.pop("Content-Type") # As we are now sending multipart/form-data instead of application/json # we need to tell httpx to use it, https://www.python-httpx.org/advanced/clients/#multipart-file-encoding if json_data: if not is_dict(json_data): raise TypeError( f"Expected query input to be a dictionary for multipart requests but got {type(json_data)} instead." ) kwargs["data"] = self._serialize_multipartform(json_data) # httpx determines whether or not to send a "multipart/form-data" # request based on the truthiness of the "files" argument. # This gets around that issue by generating a dict value that # evaluates to true. # # https://github.com/encode/httpx/discussions/2399#discussioncomment-3814186 if not files: files = cast(HttpxRequestFiles, ForceMultipartDict()) prepared_url = self._prepare_url(options.url) if "_" in prepared_url.host: # work around https://github.com/encode/httpx/discussions/2880 kwargs["extensions"] = {"sni_hostname": prepared_url.host.replace("_", "-")} is_body_allowed = options.method.lower() != "get" if is_body_allowed: if isinstance(json_data, bytes): kwargs["content"] = json_data else: kwargs["json"] = json_data if is_given(json_data) else None kwargs["files"] = files else: headers.pop("Content-Type", None) kwargs.pop("data", None) # TODO: report this error to httpx return self._client.build_request( # pyright: ignore[reportUnknownMemberType] headers=headers, timeout=self.timeout if isinstance(options.timeout, NotGiven) else options.timeout, method=options.method, url=prepared_url, # the `Query` type that we use is incompatible with qs' # `Params` type as it needs to be typed as `Mapping[str, object]` # so that passing a `TypedDict` doesn't cause an error. # https://github.com/microsoft/pyright/issues/3526#event-6715453066 params=self.qs.stringify(cast(Mapping[str, Any], params)) if params else None, **kwargs, ) def _serialize_multipartform(self, data: Mapping[object, object]) -> dict[str, object]: items = self.qs.stringify_items( # TODO: type ignore is required as stringify_items is well typed but we can't be # well typed without heavy validation. data, # type: ignore array_format="brackets", ) serialized: dict[str, object] = {} for key, value in items: existing = serialized.get(key) if not existing: serialized[key] = value continue # If a value has already been set for this key then that # means we're sending data like `array[]=[1, 2, 3]` and we # need to tell httpx that we want to send multiple values with # the same key which is done by using a list or a tuple. # # Note: 2d arrays should never result in the same key at both # levels so it's safe to assume that if the value is a list, # it was because we changed it to be a list. if is_list(existing): existing.append(value) else: serialized[key] = [existing, value] return serialized def _maybe_override_cast_to(self, cast_to: type[ResponseT], options: FinalRequestOptions) -> type[ResponseT]: if not is_given(options.headers): return cast_to # make a copy of the headers so we don't mutate user-input headers = dict(options.headers) # we internally support defining a temporary header to override the # default `cast_to` type for use with `.with_raw_response` and `.with_streaming_response` # see _response.py for implementation details override_cast_to = headers.pop(OVERRIDE_CAST_TO_HEADER, not_given) if is_given(override_cast_to): options.headers = headers return cast(Type[ResponseT], override_cast_to) return cast_to def _should_stream_response_body(self, request: httpx.Request) -> bool: return request.headers.get(RAW_RESPONSE_HEADER) == "stream" # type: ignore[no-any-return] def _process_response_data( self, *, data: object, cast_to: type[ResponseT], response: httpx.Response, ) -> ResponseT: if data is None: return cast(ResponseT, None) if cast_to is object: return cast(ResponseT, data) try: if inspect.isclass(cast_to) and issubclass(cast_to, ModelBuilderProtocol): return cast(ResponseT, cast_to.build(response=response, data=data)) if self._strict_response_validation: return cast(ResponseT, validate_type(type_=cast_to, value=data)) return cast(ResponseT, construct_type(type_=cast_to, value=data)) except pydantic.ValidationError as err: raise APIResponseValidationError(response=response, body=data) from err @property def qs(self) -> Querystring: return Querystring() @property def custom_auth(self) -> httpx.Auth | None: return None @property def auth_headers(self) -> dict[str, str]: return {} @property def default_headers(self) -> dict[str, str | Omit]: return { "Accept": "application/json", "Content-Type": "application/json", "User-Agent": self.user_agent, **self.platform_headers(), **self.auth_headers, **self._custom_headers, } @property def default_query(self) -> dict[str, object]: return { **self._custom_query, } def _validate_headers( self, headers: Headers, # noqa: ARG002 custom_headers: Headers, # noqa: ARG002 ) -> None: """Validate the given default headers and custom headers. Does nothing by default. """ return @property def user_agent(self) -> str: return f"{self.__class__.__name__}/Python {self._version}" @property def base_url(self) -> URL: return self._base_url @base_url.setter def base_url(self, url: URL | str) -> None: self._base_url = self._enforce_trailing_slash(url if isinstance(url, URL) else URL(url)) def platform_headers(self) -> Dict[str, str]: # the actual implementation is in a separate `lru_cache` decorated # function because adding `lru_cache` to methods will leak memory # https://github.com/python/cpython/issues/88476 return platform_headers(self._version, platform=self._platform) def _calculate_nonstreaming_timeout(self, max_tokens: int, max_nonstreaming_tokens: int | None) -> Timeout: maximum_time = 60 * 60 default_time = 60 * 10 expected_time = maximum_time * max_tokens / 128_000 if expected_time > default_time or (max_nonstreaming_tokens and max_tokens > max_nonstreaming_tokens): raise ValueError( "Streaming is required for operations that may take longer than 10 minutes. " + "See https://github.com/anthropics/anthropic-sdk-python#long-requests for more details", ) return Timeout( default_time, connect=5.0, ) def _parse_retry_after_header(self, response_headers: Optional[httpx.Headers] = None) -> float | None: """Returns a float of the number of seconds (not milliseconds) to wait after retrying, or None if unspecified. About the Retry-After header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After See also https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After#syntax """ if response_headers is None: return None # First, try the non-standard `retry-after-ms` header for milliseconds, # which is more precise than integer-seconds `retry-after` try: retry_ms_header = response_headers.get("retry-after-ms", None) return float(retry_ms_header) / 1000 except (TypeError, ValueError): pass # Next, try parsing `retry-after` header as seconds (allowing nonstandard floats). retry_header = response_headers.get("retry-after") try: # note: the spec indicates that this should only ever be an integer # but if someone sends a float there's no reason for us to not respect it return float(retry_header) except (TypeError, ValueError): pass # Last, try parsing `retry-after` as a date. retry_date_tuple = email.utils.parsedate_tz(retry_header) if retry_date_tuple is None: return None retry_date = email.utils.mktime_tz(retry_date_tuple) return float(retry_date - time.time()) def _calculate_retry_timeout( self, remaining_retries: int, options: FinalRequestOptions, response_headers: Optional[httpx.Headers] = None, ) -> float: max_retries = options.get_max_retries(self.max_retries) # If the API asks us to wait a certain amount of time (and it's a reasonable amount), just do what it says. retry_after = self._parse_retry_after_header(response_headers) if retry_after is not None and 0 < retry_after <= 60: return retry_after # Also cap retry count to 1000 to avoid any potential overflows with `pow` nb_retries = min(max_retries - remaining_retries, 1000) # Apply exponential backoff, but not more than the max. sleep_seconds = min(INITIAL_RETRY_DELAY * pow(2.0, nb_retries), MAX_RETRY_DELAY) # Apply some jitter, plus-or-minus half a second. jitter = 1 - 0.25 * random() timeout = sleep_seconds * jitter return timeout if timeout >= 0 else 0 def _should_retry(self, response: httpx.Response) -> bool: # Note: this is not a standard header should_retry_header = response.headers.get("x-should-retry") # If the server explicitly says whether or not to retry, obey. if should_retry_header == "true": log.debug("Retrying as header `x-should-retry` is set to `true`") return True if should_retry_header == "false": log.debug("Not retrying as header `x-should-retry` is set to `false`") return False # Retry on request timeouts. if response.status_code == 408: log.debug("Retrying due to status code %i", response.status_code) return True # Retry on lock timeouts. if response.status_code == 409: log.debug("Retrying due to status code %i", response.status_code) return True # Retry on rate limits. if response.status_code == 429: log.debug("Retrying due to status code %i", response.status_code) return True # Retry internal errors. if response.status_code >= 500: log.debug("Retrying due to status code %i", response.status_code) return True log.debug("Not retrying") return False def _idempotency_key(self) -> str: return f"stainless-python-retry-{uuid.uuid4()}" class _DefaultHttpxClient(httpx.Client): def __init__(self, **kwargs: Any) -> None: kwargs.setdefault("timeout", DEFAULT_TIMEOUT) kwargs.setdefault("limits", DEFAULT_CONNECTION_LIMITS) kwargs.setdefault("follow_redirects", True) if "transport" not in kwargs: socket_options: List[Tuple[int, int, Union[int, bool]]] = [(socket.SOL_SOCKET, socket.SO_KEEPALIVE, True)] TCP_KEEPINTVL = getattr(socket, "TCP_KEEPINTVL", None) if TCP_KEEPINTVL is not None: socket_options.append((socket.IPPROTO_TCP, TCP_KEEPINTVL, 60)) elif sys.platform == "darwin": TCP_KEEPALIVE = getattr(socket, "TCP_KEEPALIVE", 0x10) socket_options.append((socket.IPPROTO_TCP, TCP_KEEPALIVE, 60)) TCP_KEEPCNT = getattr(socket, "TCP_KEEPCNT", None) if TCP_KEEPCNT is not None: socket_options.append((socket.IPPROTO_TCP, TCP_KEEPCNT, 5)) TCP_KEEPIDLE = getattr(socket, "TCP_KEEPIDLE", None) if TCP_KEEPIDLE is not None: socket_options.append((socket.IPPROTO_TCP, TCP_KEEPIDLE, 60)) proxy_map = {key: None if url is None else Proxy(url=url) for key, url in get_environment_proxies().items()} transport_kwargs = { arg: kwargs[arg] for arg in ("verify", "cert", "trust_env", "http1", "http2", "limits") if arg in kwargs } proxy_mounts = { key: None if proxy is None else HTTPTransport(proxy=proxy, **transport_kwargs) for key, proxy in proxy_map.items() } default_transport = HTTPTransport(**transport_kwargs) # Prioritize the mounts set by the user over the environment variables. proxy_mounts.update(kwargs.get("mounts", {})) kwargs["mounts"] = proxy_mounts # Sets the default transport so that HTTPX won't automatically configure proxies. kwargs["transport"] = kwargs.get("transport", default_transport) super().__init__(**kwargs) if TYPE_CHECKING: DefaultHttpxClient = httpx.Client """An alias to `httpx.Client` that provides the same defaults that this SDK uses internally. This is useful because overriding the `http_client` with your own instance of `httpx.Client` will result in httpx's defaults being used, not ours. """ else: DefaultHttpxClient = _DefaultHttpxClient class SyncHttpxClientWrapper(DefaultHttpxClient): def __del__(self) -> None: if self.is_closed: return try: self.close() except Exception: pass class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]): _client: httpx.Client _default_stream_cls: type[Stream[Any]] | None = None def __init__( self, *, version: str, base_url: str | URL, max_retries: int = DEFAULT_MAX_RETRIES, timeout: float | Timeout | None | NotGiven = not_given, http_client: httpx.Client | None = None, custom_headers: Mapping[str, str] | None = None, custom_query: Mapping[str, object] | None = None, _strict_response_validation: bool, ) -> None: if not is_given(timeout): # if the user passed in a custom http client with a non-default # timeout set then we use that timeout. # # note: there is an edge case here where the user passes in a client # where they've explicitly set the timeout to match the default timeout # as this check is structural, meaning that we'll think they didn't # pass in a timeout and will ignore it if http_client and http_client.timeout != HTTPX_DEFAULT_TIMEOUT: timeout = http_client.timeout else: timeout = DEFAULT_TIMEOUT if http_client is not None and not isinstance(http_client, httpx.Client): # pyright: ignore[reportUnnecessaryIsInstance] raise TypeError( f"Invalid `http_client` argument; Expected an instance of `httpx.Client` but got {type(http_client)}" ) super().__init__( version=version, # cast to a valid type because mypy doesn't understand our type narrowing timeout=cast(Timeout, timeout), base_url=base_url, max_retries=max_retries, custom_query=custom_query, custom_headers=custom_headers, _strict_response_validation=_strict_response_validation, ) self._client = http_client or SyncHttpxClientWrapper( base_url=base_url, # cast to a valid type because mypy doesn't understand our type narrowing timeout=cast(Timeout, timeout), ) def is_closed(self) -> bool: return self._client.is_closed def close(self) -> None: """Close the underlying HTTPX client. The client will *not* be usable after this. """ # If an error is thrown while constructing a client, self._client # may not be present if hasattr(self, "_client"): self._client.close() def __enter__(self: _T) -> _T: return self def __exit__( self, exc_type: type[BaseException] | None, exc: BaseException | None, exc_tb: TracebackType | None, ) -> None: self.close() def _prepare_options( self, options: FinalRequestOptions, # noqa: ARG002 ) -> FinalRequestOptions: """Hook for mutating the given options""" return options def _prepare_request( self, request: httpx.Request, # noqa: ARG002 ) -> None: """This method is used as a callback for mutating the `Request` object after it has been constructed. This is useful for cases where you want to add certain headers based off of the request properties, e.g. `url`, `method` etc. """ return None @overload def request( self, cast_to: Type[ResponseT], options: FinalRequestOptions, *, stream: Literal[True], stream_cls: Type[_StreamT], ) -> _StreamT: ... @overload def request( self, cast_to: Type[ResponseT], options: FinalRequestOptions, *, stream: Literal[False] = False, ) -> ResponseT: ... @overload def request( self, cast_to: Type[ResponseT], options: FinalRequestOptions, *, stream: bool = False, stream_cls: Type[_StreamT] | None = None, ) -> ResponseT | _StreamT: ... def request( self, cast_to: Type[ResponseT], options: FinalRequestOptions, *, stream: bool = False, stream_cls: type[_StreamT] | None = None, ) -> ResponseT | _StreamT: cast_to = self._maybe_override_cast_to(cast_to, options) # create a copy of the options we were given so that if the # options are mutated later & we then retry, the retries are # given the original options input_options = model_copy(options) if input_options.idempotency_key is None and input_options.method.lower() != "get": # ensure the idempotency key is reused between requests input_options.idempotency_key = self._idempotency_key() response: httpx.Response | None = None max_retries = input_options.get_max_retries(self.max_retries) retries_taken = 0 for retries_taken in range(max_retries + 1): options = model_copy(input_options) options = self._prepare_options(options) remaining_retries = max_retries - retries_taken request = self._build_request(options, retries_taken=retries_taken) self._prepare_request(request) kwargs: HttpxSendArgs = {} if self.custom_auth is not None: kwargs["auth"] = self.custom_auth if options.follow_redirects is not None: kwargs["follow_redirects"] = options.follow_redirects log.debug("Sending HTTP Request: %s %s", request.method, request.url) response = None try: response = self._client.send( request, stream=stream or self._should_stream_response_body(request=request), **kwargs, ) except httpx.TimeoutException as err: log.debug("Encountered httpx.TimeoutException", exc_info=True) if remaining_retries > 0: self._sleep_for_retry( retries_taken=retries_taken, max_retries=max_retries, options=input_options, response=None, ) continue log.debug("Raising timeout error") raise APITimeoutError(request=request) from err except Exception as err: log.debug("Encountered Exception", exc_info=True) if remaining_retries > 0: self._sleep_for_retry( retries_taken=retries_taken, max_retries=max_retries, options=input_options, response=None, ) continue log.debug("Raising connection error") raise APIConnectionError(request=request) from err log.debug( 'HTTP Response: %s %s "%i %s" %s', request.method, request.url, response.status_code, response.reason_phrase, response.headers, ) log.debug("request_id: %s", response.headers.get("request-id")) try: response.raise_for_status() except httpx.HTTPStatusError as err: # thrown on 4xx and 5xx status code log.debug("Encountered httpx.HTTPStatusError", exc_info=True) if remaining_retries > 0 and self._should_retry(err.response): err.response.close() self._sleep_for_retry( retries_taken=retries_taken, max_retries=max_retries, options=input_options, response=response, ) continue # If the response is streamed then we need to explicitly read the response # to completion before attempting to access the response text. if not err.response.is_closed: err.response.read() log.debug("Re-raising status error") raise self._make_status_error_from_response(err.response) from None break assert response is not None, "could not resolve response (should never happen)" return self._process_response( cast_to=cast_to, options=options, response=response, stream=stream, stream_cls=stream_cls, retries_taken=retries_taken, ) def _sleep_for_retry( self, *, retries_taken: int, max_retries: int, options: FinalRequestOptions, response: httpx.Response | None ) -> None: remaining_retries = max_retries - retries_taken if remaining_retries == 1: log.debug("1 retry left") else: log.debug("%i retries left", remaining_retries) timeout = self._calculate_retry_timeout(remaining_retries, options, response.headers if response else None) log.info("Retrying request to %s in %f seconds", options.url, timeout) time.sleep(timeout) def _process_response( self, *, cast_to: Type[ResponseT], options: FinalRequestOptions, response: httpx.Response, stream: bool, stream_cls: type[Stream[Any]] | type[AsyncStream[Any]] | None, retries_taken: int = 0, ) -> ResponseT: if response.request.headers.get(RAW_RESPONSE_HEADER) == "true": return cast( ResponseT, LegacyAPIResponse( raw=response, client=self, cast_to=cast_to, stream=stream, stream_cls=stream_cls, options=options, retries_taken=retries_taken, ), ) origin = get_origin(cast_to) or cast_to if ( inspect.isclass(origin) and issubclass(origin, BaseAPIResponse) # we only want to actually return the custom BaseAPIResponse class if we're # returning the raw response, or if we're not streaming SSE, as if we're streaming # SSE then `cast_to` doesn't actively reflect the type we need to parse into and (not stream or bool(response.request.headers.get(RAW_RESPONSE_HEADER))) ): if not issubclass(origin, APIResponse): raise TypeError(f"API Response types must subclass {APIResponse}; Received {origin}") response_cls = cast("type[BaseAPIResponse[Any]]", cast_to) return cast( ResponseT, response_cls( raw=response, client=self, cast_to=extract_response_type(response_cls), stream=stream, stream_cls=stream_cls, options=options, retries_taken=retries_taken, ), ) if cast_to == httpx.Response: return cast(ResponseT, response) api_response = APIResponse( raw=response, client=self, cast_to=cast("type[ResponseT]", cast_to), # pyright: ignore[reportUnnecessaryCast] stream=stream, stream_cls=stream_cls, options=options, retries_taken=retries_taken, ) if bool(response.request.headers.get(RAW_RESPONSE_HEADER)): return cast(ResponseT, api_response) return api_response.parse() def _request_api_list( self, model: Type[object], page: Type[SyncPageT], options: FinalRequestOptions, ) -> SyncPageT: def _parser(resp: SyncPageT) -> SyncPageT: resp._set_private_attributes( client=self, model=model, options=options, ) return resp options.post_parser = _parser return self.request(page, options, stream=False) @overload def get( self, path: str, *, cast_to: Type[ResponseT], options: RequestOptions = {}, stream: Literal[False] = False, ) -> ResponseT: ... @overload def get( self, path: str, *, cast_to: Type[ResponseT], options: RequestOptions = {}, stream: Literal[True], stream_cls: type[_StreamT], ) -> _StreamT: ... @overload def get( self, path: str, *, cast_to: Type[ResponseT], options: RequestOptions = {}, stream: bool, stream_cls: type[_StreamT] | None = None, ) -> ResponseT | _StreamT: ... def get( self, path: str, *, cast_to: Type[ResponseT], options: RequestOptions = {}, stream: bool = False, stream_cls: type[_StreamT] | None = None, ) -> ResponseT | _StreamT: opts = FinalRequestOptions.construct(method="get", url=path, **options) # cast is required because mypy complains about returning Any even though # it understands the type variables return cast(ResponseT, self.request(cast_to, opts, stream=stream, stream_cls=stream_cls)) @overload def post( self, path: str, *, cast_to: Type[ResponseT], body: Body | None = None, options: RequestOptions = {}, files: RequestFiles | None = None, stream: Literal[False] = False, ) -> ResponseT: ... @overload def post( self, path: str, *, cast_to: Type[ResponseT], body: Body | None = None, options: RequestOptions = {}, files: RequestFiles | None = None, stream: Literal[True], stream_cls: type[_StreamT], ) -> _StreamT: ... @overload def post( self, path: str, *, cast_to: Type[ResponseT], body: Body | None = None, options: RequestOptions = {}, files: RequestFiles | None = None, stream: bool, stream_cls: type[_StreamT] | None = None, ) -> ResponseT | _StreamT: ... def post( self, path: str, *, cast_to: Type[ResponseT], body: Body | None = None, options: RequestOptions = {}, files: RequestFiles | None = None, stream: bool = False, stream_cls: type[_StreamT] | None = None, ) -> ResponseT | _StreamT: opts = FinalRequestOptions.construct( method="post", url=path, json_data=body, files=to_httpx_files(files), **options ) return cast(ResponseT, self.request(cast_to, opts, stream=stream, stream_cls=stream_cls)) def patch( self, path: str, *, cast_to: Type[ResponseT], body: Body | None = None, options: RequestOptions = {}, ) -> ResponseT: opts = FinalRequestOptions.construct(method="patch", url=path, json_data=body, **options) return self.request(cast_to, opts) def put( self, path: str, *, cast_to: Type[ResponseT], body: Body | None = None, files: RequestFiles | None = None, options: RequestOptions = {}, ) -> ResponseT: opts = FinalRequestOptions.construct( method="put", url=path, json_data=body, files=to_httpx_files(files), **options ) return self.request(cast_to, opts) def delete( self, path: str, *, cast_to: Type[ResponseT], body: Body | None = None, options: RequestOptions = {}, ) -> ResponseT: opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, **options) return self.request(cast_to, opts) def get_api_list( self, path: str, *, model: Type[object], page: Type[SyncPageT], body: Body | None = None, options: RequestOptions = {}, method: str = "get", ) -> SyncPageT: opts = FinalRequestOptions.construct(method=method, url=path, json_data=body, **options) return self._request_api_list(model, page, opts) class _DefaultAsyncHttpxClient(httpx.AsyncClient): def __init__(self, **kwargs: Any) -> None: kwargs.setdefault("timeout", DEFAULT_TIMEOUT) kwargs.setdefault("limits", DEFAULT_CONNECTION_LIMITS) kwargs.setdefault("follow_redirects", True) if "transport" not in kwargs: socket_options: List[Tuple[int, int, Union[int, bool]]] = [(socket.SOL_SOCKET, socket.SO_KEEPALIVE, True)] TCP_KEEPINTVL = getattr(socket, "TCP_KEEPINTVL", None) if TCP_KEEPINTVL is not None: socket_options.append((socket.IPPROTO_TCP, TCP_KEEPINTVL, 60)) elif sys.platform == "darwin": TCP_KEEPALIVE = getattr(socket, "TCP_KEEPALIVE", 0x10) socket_options.append((socket.IPPROTO_TCP, TCP_KEEPALIVE, 60)) TCP_KEEPCNT = getattr(socket, "TCP_KEEPCNT", None) if TCP_KEEPCNT is not None: socket_options.append((socket.IPPROTO_TCP, TCP_KEEPCNT, 5)) TCP_KEEPIDLE = getattr(socket, "TCP_KEEPIDLE", None) if TCP_KEEPIDLE is not None: socket_options.append((socket.IPPROTO_TCP, TCP_KEEPIDLE, 60)) proxy_map = {key: None if url is None else Proxy(url=url) for key, url in get_environment_proxies().items()} transport_kwargs = { arg: kwargs[arg] for arg in ("verify", "cert", "trust_env", "http1", "http2", "limits") if arg in kwargs } proxy_mounts = { key: None if proxy is None else AsyncHTTPTransport(proxy=proxy, **transport_kwargs) for key, proxy in proxy_map.items() } default_transport = AsyncHTTPTransport(**transport_kwargs) # Prioritize the mounts set by the user over the environment variables. proxy_mounts.update(kwargs.get("mounts", {})) kwargs["mounts"] = proxy_mounts # Sets the default transport so that HTTPX won't automatically configure proxies. kwargs["transport"] = kwargs.get("transport", default_transport) super().__init__(**kwargs) try: import httpx_aiohttp except ImportError: class _DefaultAioHttpClient(httpx.AsyncClient): def __init__(self, **_kwargs: Any) -> None: raise RuntimeError("To use the aiohttp client you must have installed the package with the `aiohttp` extra") else: class _DefaultAioHttpClient(httpx_aiohttp.HttpxAiohttpClient): # type: ignore def __init__(self, **kwargs: Any) -> None: kwargs.setdefault("timeout", DEFAULT_TIMEOUT) kwargs.setdefault("limits", DEFAULT_CONNECTION_LIMITS) kwargs.setdefault("follow_redirects", True) super().__init__(**kwargs) if TYPE_CHECKING: DefaultAsyncHttpxClient = httpx.AsyncClient """An alias to `httpx.AsyncClient` that provides the same defaults that this SDK uses internally. This is useful because overriding the `http_client` with your own instance of `httpx.AsyncClient` will result in httpx's defaults being used, not ours. """ DefaultAioHttpClient = httpx.AsyncClient """An alias to `httpx.AsyncClient` that changes the default HTTP transport to `aiohttp`.""" else: DefaultAsyncHttpxClient = _DefaultAsyncHttpxClient DefaultAioHttpClient = _DefaultAioHttpClient class AsyncHttpxClientWrapper(DefaultAsyncHttpxClient): def __del__(self) -> None: if self.is_closed: return try: # TODO(someday): support non asyncio runtimes here asyncio.get_running_loop().create_task(self.aclose()) except Exception: pass class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]): _client: httpx.AsyncClient _default_stream_cls: type[AsyncStream[Any]] | None = None def __init__( self, *, version: str, base_url: str | URL, _strict_response_validation: bool, max_retries: int = DEFAULT_MAX_RETRIES, timeout: float | Timeout | None | NotGiven = not_given, http_client: httpx.AsyncClient | None = None, custom_headers: Mapping[str, str] | None = None, custom_query: Mapping[str, object] | None = None, ) -> None: if not is_given(timeout): # if the user passed in a custom http client with a non-default # timeout set then we use that timeout. # # note: there is an edge case here where the user passes in a client # where they've explicitly set the timeout to match the default timeout # as this check is structural, meaning that we'll think they didn't # pass in a timeout and will ignore it if http_client and http_client.timeout != HTTPX_DEFAULT_TIMEOUT: timeout = http_client.timeout else: timeout = DEFAULT_TIMEOUT if http_client is not None and not isinstance(http_client, httpx.AsyncClient): # pyright: ignore[reportUnnecessaryIsInstance] raise TypeError( f"Invalid `http_client` argument; Expected an instance of `httpx.AsyncClient` but got {type(http_client)}" ) super().__init__( version=version, base_url=base_url, # cast to a valid type because mypy doesn't understand our type narrowing timeout=cast(Timeout, timeout), max_retries=max_retries, custom_query=custom_query, custom_headers=custom_headers, _strict_response_validation=_strict_response_validation, ) self._client = http_client or AsyncHttpxClientWrapper( base_url=base_url, # cast to a valid type because mypy doesn't understand our type narrowing timeout=cast(Timeout, timeout), ) def is_closed(self) -> bool: return self._client.is_closed async def close(self) -> None: """Close the underlying HTTPX client. The client will *not* be usable after this. """ await self._client.aclose() async def __aenter__(self: _T) -> _T: return self async def __aexit__( self, exc_type: type[BaseException] | None, exc: BaseException | None, exc_tb: TracebackType | None, ) -> None: await self.close() async def _prepare_options( self, options: FinalRequestOptions, # noqa: ARG002 ) -> FinalRequestOptions: """Hook for mutating the given options""" return options async def _prepare_request( self, request: httpx.Request, # noqa: ARG002 ) -> None: """This method is used as a callback for mutating the `Request` object after it has been constructed. This is useful for cases where you want to add certain headers based off of the request properties, e.g. `url`, `method` etc. """ return None @overload async def request( self, cast_to: Type[ResponseT], options: FinalRequestOptions, *, stream: Literal[False] = False, ) -> ResponseT: ... @overload async def request( self, cast_to: Type[ResponseT], options: FinalRequestOptions, *, stream: Literal[True], stream_cls: type[_AsyncStreamT], ) -> _AsyncStreamT: ... @overload async def request( self, cast_to: Type[ResponseT], options: FinalRequestOptions, *, stream: bool, stream_cls: type[_AsyncStreamT] | None = None, ) -> ResponseT | _AsyncStreamT: ... async def request( self, cast_to: Type[ResponseT], options: FinalRequestOptions, *, stream: bool = False, stream_cls: type[_AsyncStreamT] | None = None, ) -> ResponseT | _AsyncStreamT: if self._platform is None: # `get_platform` can make blocking IO calls so we # execute it earlier while we are in an async context self._platform = await asyncify(get_platform)() cast_to = self._maybe_override_cast_to(cast_to, options) # create a copy of the options we were given so that if the # options are mutated later & we then retry, the retries are # given the original options input_options = model_copy(options) if input_options.idempotency_key is None and input_options.method.lower() != "get": # ensure the idempotency key is reused between requests input_options.idempotency_key = self._idempotency_key() response: httpx.Response | None = None max_retries = input_options.get_max_retries(self.max_retries) retries_taken = 0 for retries_taken in range(max_retries + 1): options = model_copy(input_options) options = await self._prepare_options(options) remaining_retries = max_retries - retries_taken request = self._build_request(options, retries_taken=retries_taken) await self._prepare_request(request) kwargs: HttpxSendArgs = {} if self.custom_auth is not None: kwargs["auth"] = self.custom_auth if options.follow_redirects is not None: kwargs["follow_redirects"] = options.follow_redirects log.debug("Sending HTTP Request: %s %s", request.method, request.url) response = None try: response = await self._client.send( request, stream=stream or self._should_stream_response_body(request=request), **kwargs, ) except httpx.TimeoutException as err: log.debug("Encountered httpx.TimeoutException", exc_info=True) if remaining_retries > 0: await self._sleep_for_retry( retries_taken=retries_taken, max_retries=max_retries, options=input_options, response=None, ) continue log.debug("Raising timeout error") raise APITimeoutError(request=request) from err except Exception as err: log.debug("Encountered Exception", exc_info=True) if remaining_retries > 0: await self._sleep_for_retry( retries_taken=retries_taken, max_retries=max_retries, options=input_options, response=None, ) continue log.debug("Raising connection error") raise APIConnectionError(request=request) from err log.debug( 'HTTP Response: %s %s "%i %s" %s', request.method, request.url, response.status_code, response.reason_phrase, response.headers, ) log.debug("request_id: %s", response.headers.get("request-id")) try: response.raise_for_status() except httpx.HTTPStatusError as err: # thrown on 4xx and 5xx status code log.debug("Encountered httpx.HTTPStatusError", exc_info=True) if remaining_retries > 0 and self._should_retry(err.response): await err.response.aclose() await self._sleep_for_retry( retries_taken=retries_taken, max_retries=max_retries, options=input_options, response=response, ) continue # If the response is streamed then we need to explicitly read the response # to completion before attempting to access the response text. if not err.response.is_closed: await err.response.aread() log.debug("Re-raising status error") raise self._make_status_error_from_response(err.response) from None break assert response is not None, "could not resolve response (should never happen)" return await self._process_response( cast_to=cast_to, options=options, response=response, stream=stream, stream_cls=stream_cls, retries_taken=retries_taken, ) async def _sleep_for_retry( self, *, retries_taken: int, max_retries: int, options: FinalRequestOptions, response: httpx.Response | None ) -> None: remaining_retries = max_retries - retries_taken if remaining_retries == 1: log.debug("1 retry left") else: log.debug("%i retries left", remaining_retries) timeout = self._calculate_retry_timeout(remaining_retries, options, response.headers if response else None) log.info("Retrying request to %s in %f seconds", options.url, timeout) await anyio.sleep(timeout) async def _process_response( self, *, cast_to: Type[ResponseT], options: FinalRequestOptions, response: httpx.Response, stream: bool, stream_cls: type[Stream[Any]] | type[AsyncStream[Any]] | None, retries_taken: int = 0, ) -> ResponseT: if response.request.headers.get(RAW_RESPONSE_HEADER) == "true": return cast( ResponseT, LegacyAPIResponse( raw=response, client=self, cast_to=cast_to, stream=stream, stream_cls=stream_cls, options=options, retries_taken=retries_taken, ), ) origin = get_origin(cast_to) or cast_to if ( inspect.isclass(origin) and issubclass(origin, BaseAPIResponse) # we only want to actually return the custom BaseAPIResponse class if we're # returning the raw response, or if we're not streaming SSE, as if we're streaming # SSE then `cast_to` doesn't actively reflect the type we need to parse into and (not stream or bool(response.request.headers.get(RAW_RESPONSE_HEADER))) ): if not issubclass(origin, AsyncAPIResponse): raise TypeError(f"API Response types must subclass {AsyncAPIResponse}; Received {origin}") response_cls = cast("type[BaseAPIResponse[Any]]", cast_to) return cast( "ResponseT", response_cls( raw=response, client=self, cast_to=extract_response_type(response_cls), stream=stream, stream_cls=stream_cls, options=options, retries_taken=retries_taken, ), ) if cast_to == httpx.Response: return cast(ResponseT, response) api_response = AsyncAPIResponse( raw=response, client=self, cast_to=cast("type[ResponseT]", cast_to), # pyright: ignore[reportUnnecessaryCast] stream=stream, stream_cls=stream_cls, options=options, retries_taken=retries_taken, ) if bool(response.request.headers.get(RAW_RESPONSE_HEADER)): return cast(ResponseT, api_response) return await api_response.parse() def _request_api_list( self, model: Type[_T], page: Type[AsyncPageT], options: FinalRequestOptions, ) -> AsyncPaginator[_T, AsyncPageT]: return AsyncPaginator(client=self, options=options, page_cls=page, model=model) @overload async def get( self, path: str, *, cast_to: Type[ResponseT], options: RequestOptions = {}, stream: Literal[False] = False, ) -> ResponseT: ... @overload async def get( self, path: str, *, cast_to: Type[ResponseT], options: RequestOptions = {}, stream: Literal[True], stream_cls: type[_AsyncStreamT], ) -> _AsyncStreamT: ... @overload async def get( self, path: str, *, cast_to: Type[ResponseT], options: RequestOptions = {}, stream: bool, stream_cls: type[_AsyncStreamT] | None = None, ) -> ResponseT | _AsyncStreamT: ... async def get( self, path: str, *, cast_to: Type[ResponseT], options: RequestOptions = {}, stream: bool = False, stream_cls: type[_AsyncStreamT] | None = None, ) -> ResponseT | _AsyncStreamT: opts = FinalRequestOptions.construct(method="get", url=path, **options) return await self.request(cast_to, opts, stream=stream, stream_cls=stream_cls) @overload async def post( self, path: str, *, cast_to: Type[ResponseT], body: Body | None = None, files: RequestFiles | None = None, options: RequestOptions = {}, stream: Literal[False] = False, ) -> ResponseT: ... @overload async def post( self, path: str, *, cast_to: Type[ResponseT], body: Body | None = None, files: RequestFiles | None = None, options: RequestOptions = {}, stream: Literal[True], stream_cls: type[_AsyncStreamT], ) -> _AsyncStreamT: ... @overload async def post( self, path: str, *, cast_to: Type[ResponseT], body: Body | None = None, files: RequestFiles | None = None, options: RequestOptions = {}, stream: bool, stream_cls: type[_AsyncStreamT] | None = None, ) -> ResponseT | _AsyncStreamT: ... async def post( self, path: str, *, cast_to: Type[ResponseT], body: Body | None = None, files: RequestFiles | None = None, options: RequestOptions = {}, stream: bool = False, stream_cls: type[_AsyncStreamT] | None = None, ) -> ResponseT | _AsyncStreamT: opts = FinalRequestOptions.construct( method="post", url=path, json_data=body, files=await async_to_httpx_files(files), **options ) return await self.request(cast_to, opts, stream=stream, stream_cls=stream_cls) async def patch( self, path: str, *, cast_to: Type[ResponseT], body: Body | None = None, options: RequestOptions = {}, ) -> ResponseT: opts = FinalRequestOptions.construct(method="patch", url=path, json_data=body, **options) return await self.request(cast_to, opts) async def put( self, path: str, *, cast_to: Type[ResponseT], body: Body | None = None, files: RequestFiles | None = None, options: RequestOptions = {}, ) -> ResponseT: opts = FinalRequestOptions.construct( method="put", url=path, json_data=body, files=await async_to_httpx_files(files), **options ) return await self.request(cast_to, opts) async def delete( self, path: str, *, cast_to: Type[ResponseT], body: Body | None = None, options: RequestOptions = {}, ) -> ResponseT: opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, **options) return await self.request(cast_to, opts) def get_api_list( self, path: str, *, model: Type[_T], page: Type[AsyncPageT], body: Body | None = None, options: RequestOptions = {}, method: str = "get", ) -> AsyncPaginator[_T, AsyncPageT]: opts = FinalRequestOptions.construct(method=method, url=path, json_data=body, **options) return self._request_api_list(model, page, opts) def make_request_options( *, query: Query | None = None, extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, idempotency_key: str | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, post_parser: PostParser | NotGiven = not_given, ) -> RequestOptions: """Create a dict of type RequestOptions without keys of NotGiven values.""" options: RequestOptions = {} if extra_headers is not None: options["headers"] = extra_headers if extra_body is not None: options["extra_json"] = cast(AnyMapping, extra_body) if query is not None: options["params"] = query if extra_query is not None: options["params"] = {**options.get("params", {}), **extra_query} if not isinstance(timeout, NotGiven): options["timeout"] = timeout if idempotency_key is not None: options["idempotency_key"] = idempotency_key if is_given(post_parser): # internal options["post_parser"] = post_parser # type: ignore return options class ForceMultipartDict(Dict[str, None]): def __bool__(self) -> bool: return True class OtherPlatform: def __init__(self, name: str) -> None: self.name = name @override def __str__(self) -> str: return f"Other:{self.name}" Platform = Union[ OtherPlatform, Literal[ "MacOS", "Linux", "Windows", "FreeBSD", "OpenBSD", "iOS", "Android", "Unknown", ], ] def get_platform() -> Platform: try: system = platform.system().lower() platform_name = platform.platform().lower() except Exception: return "Unknown" if "iphone" in platform_name or "ipad" in platform_name: # Tested using Python3IDE on an iPhone 11 and Pythonista on an iPad 7 # system is Darwin and platform_name is a string like: # - Darwin-21.6.0-iPhone12,1-64bit # - Darwin-21.6.0-iPad7,11-64bit return "iOS" if system == "darwin": return "MacOS" if system == "windows": return "Windows" if "android" in platform_name: # Tested using Pydroid 3 # system is Linux and platform_name is a string like 'Linux-5.10.81-android12-9-00001-geba40aecb3b7-ab8534902-aarch64-with-libc' return "Android" if system == "linux": # https://distro.readthedocs.io/en/latest/#distro.id distro_id = distro.id() if distro_id == "freebsd": return "FreeBSD" if distro_id == "openbsd": return "OpenBSD" return "Linux" if platform_name: return OtherPlatform(platform_name) return "Unknown" @lru_cache(maxsize=None) def platform_headers(version: str, *, platform: Platform | None) -> Dict[str, str]: return { "X-Stainless-Lang": "python", "X-Stainless-Package-Version": version, "X-Stainless-OS": str(platform or get_platform()), "X-Stainless-Arch": str(get_architecture()), "X-Stainless-Runtime": get_python_runtime(), "X-Stainless-Runtime-Version": get_python_version(), } class OtherArch: def __init__(self, name: str) -> None: self.name = name @override def __str__(self) -> str: return f"other:{self.name}" Arch = Union[OtherArch, Literal["x32", "x64", "arm", "arm64", "unknown"]] def get_python_runtime() -> str: try: return platform.python_implementation() except Exception: return "unknown" def get_python_version() -> str: try: return platform.python_version() except Exception: return "unknown" def get_architecture() -> Arch: try: machine = platform.machine().lower() except Exception: return "unknown" if machine in ("arm64", "aarch64"): return "arm64" # TODO: untested if machine == "arm": return "arm" if machine == "x86_64": return "x64" # TODO: untested if sys.maxsize <= 2**32: return "x32" if machine: return OtherArch(machine) return "unknown" def _merge_mappings( obj1: Mapping[_T_co, Union[_T, Omit]], obj2: Mapping[_T_co, Union[_T, Omit]], ) -> Dict[_T_co, _T]: """Merge two mappings of the same type, removing any values that are instances of `Omit`. In cases with duplicate keys the second mapping takes precedence. """ merged = {**obj1, **obj2} return {key: value for key, value in merged.items() if not isinstance(value, Omit)} anthropic-sdk-python-0.69.0/src/anthropic/_client.py000066400000000000000000000544341506653454500224670ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations import os from typing import TYPE_CHECKING, Any, Mapping from typing_extensions import Self, override import httpx from . import _constants, _exceptions from ._qs import Querystring from ._types import ( Omit, Headers, Timeout, NotGiven, Transport, ProxiesTypes, RequestOptions, not_given, ) from ._utils import is_given, get_async_library from ._compat import cached_property from ._version import __version__ from ._streaming import Stream as Stream, AsyncStream as AsyncStream from ._exceptions import APIStatusError from ._base_client import ( DEFAULT_MAX_RETRIES, SyncAPIClient, AsyncAPIClient, ) if TYPE_CHECKING: from .resources import beta, models, messages, completions from .resources.models import Models, AsyncModels from .resources.beta.beta import Beta, AsyncBeta from .resources.completions import Completions, AsyncCompletions from .resources.messages.messages import Messages, AsyncMessages __all__ = [ "Timeout", "Transport", "ProxiesTypes", "RequestOptions", "Anthropic", "AsyncAnthropic", "Client", "AsyncClient", ] class Anthropic(SyncAPIClient): # client options api_key: str | None auth_token: str | None # constants HUMAN_PROMPT = _constants.HUMAN_PROMPT AI_PROMPT = _constants.AI_PROMPT def __init__( self, *, api_key: str | None = None, auth_token: str | None = None, base_url: str | httpx.URL | None = None, timeout: float | Timeout | None | NotGiven = not_given, max_retries: int = DEFAULT_MAX_RETRIES, default_headers: Mapping[str, str] | None = None, default_query: Mapping[str, object] | None = None, # Configure a custom httpx client. # We provide a `DefaultHttpxClient` class that you can pass to retain the default values we use for `limits`, `timeout` & `follow_redirects`. # See the [httpx documentation](https://www.python-httpx.org/api/#client) for more details. http_client: httpx.Client | None = None, # Enable or disable schema validation for data returned by the API. # When enabled an error APIResponseValidationError is raised # if the API responds with invalid data for the expected schema. # # This parameter may be removed or changed in the future. # If you rely on this feature, please open a GitHub issue # outlining your use-case to help us decide if it should be # part of our public interface in the future. _strict_response_validation: bool = False, ) -> None: """Construct a new synchronous Anthropic client instance. This automatically infers the following arguments from their corresponding environment variables if they are not provided: - `api_key` from `ANTHROPIC_API_KEY` - `auth_token` from `ANTHROPIC_AUTH_TOKEN` """ if api_key is None: api_key = os.environ.get("ANTHROPIC_API_KEY") self.api_key = api_key if auth_token is None: auth_token = os.environ.get("ANTHROPIC_AUTH_TOKEN") self.auth_token = auth_token if base_url is None: base_url = os.environ.get("ANTHROPIC_BASE_URL") if base_url is None: base_url = f"https://api.anthropic.com" super().__init__( version=__version__, base_url=base_url, max_retries=max_retries, timeout=timeout, http_client=http_client, custom_headers=default_headers, custom_query=default_query, _strict_response_validation=_strict_response_validation, ) self._default_stream_cls = Stream @cached_property def completions(self) -> Completions: from .resources.completions import Completions return Completions(self) @cached_property def messages(self) -> Messages: from .resources.messages import Messages return Messages(self) @cached_property def models(self) -> Models: from .resources.models import Models return Models(self) @cached_property def beta(self) -> Beta: from .resources.beta import Beta return Beta(self) @cached_property def with_raw_response(self) -> AnthropicWithRawResponse: return AnthropicWithRawResponse(self) @cached_property def with_streaming_response(self) -> AnthropicWithStreamedResponse: return AnthropicWithStreamedResponse(self) @property @override def qs(self) -> Querystring: return Querystring(array_format="comma") @property @override def auth_headers(self) -> dict[str, str]: return {**self._api_key_auth, **self._bearer_auth} @property def _api_key_auth(self) -> dict[str, str]: api_key = self.api_key if api_key is None: return {} return {"X-Api-Key": api_key} @property def _bearer_auth(self) -> dict[str, str]: auth_token = self.auth_token if auth_token is None: return {} return {"Authorization": f"Bearer {auth_token}"} @property @override def default_headers(self) -> dict[str, str | Omit]: return { **super().default_headers, "X-Stainless-Async": "false", "anthropic-version": "2023-06-01", **self._custom_headers, } @override def _validate_headers(self, headers: Headers, custom_headers: Headers) -> None: if self.api_key and headers.get("X-Api-Key"): return if isinstance(custom_headers.get("X-Api-Key"), Omit): return if self.auth_token and headers.get("Authorization"): return if isinstance(custom_headers.get("Authorization"), Omit): return raise TypeError( '"Could not resolve authentication method. Expected either api_key or auth_token to be set. Or for one of the `X-Api-Key` or `Authorization` headers to be explicitly omitted"' ) def copy( self, *, api_key: str | None = None, auth_token: str | None = None, base_url: str | httpx.URL | None = None, timeout: float | Timeout | None | NotGiven = not_given, http_client: httpx.Client | None = None, max_retries: int | NotGiven = not_given, default_headers: Mapping[str, str] | None = None, set_default_headers: Mapping[str, str] | None = None, default_query: Mapping[str, object] | None = None, set_default_query: Mapping[str, object] | None = None, _extra_kwargs: Mapping[str, Any] = {}, ) -> Self: """ Create a new client instance re-using the same options given to the current client with optional overriding. """ if default_headers is not None and set_default_headers is not None: raise ValueError("The `default_headers` and `set_default_headers` arguments are mutually exclusive") if default_query is not None and set_default_query is not None: raise ValueError("The `default_query` and `set_default_query` arguments are mutually exclusive") headers = self._custom_headers if default_headers is not None: headers = {**headers, **default_headers} elif set_default_headers is not None: headers = set_default_headers params = self._custom_query if default_query is not None: params = {**params, **default_query} elif set_default_query is not None: params = set_default_query http_client = http_client or self._client return self.__class__( api_key=api_key or self.api_key, auth_token=auth_token or self.auth_token, base_url=base_url or self.base_url, timeout=self.timeout if isinstance(timeout, NotGiven) else timeout, http_client=http_client, max_retries=max_retries if is_given(max_retries) else self.max_retries, default_headers=headers, default_query=params, **_extra_kwargs, ) # Alias for `copy` for nicer inline usage, e.g. # client.with_options(timeout=10).foo.create(...) with_options = copy @override def _make_status_error( self, err_msg: str, *, body: object, response: httpx.Response, ) -> APIStatusError: if response.status_code == 400: return _exceptions.BadRequestError(err_msg, response=response, body=body) if response.status_code == 401: return _exceptions.AuthenticationError(err_msg, response=response, body=body) if response.status_code == 403: return _exceptions.PermissionDeniedError(err_msg, response=response, body=body) if response.status_code == 404: return _exceptions.NotFoundError(err_msg, response=response, body=body) if response.status_code == 409: return _exceptions.ConflictError(err_msg, response=response, body=body) if response.status_code == 413: return _exceptions.RequestTooLargeError(err_msg, response=response, body=body) if response.status_code == 422: return _exceptions.UnprocessableEntityError(err_msg, response=response, body=body) if response.status_code == 429: return _exceptions.RateLimitError(err_msg, response=response, body=body) if response.status_code == 529: return _exceptions.OverloadedError(err_msg, response=response, body=body) if response.status_code >= 500: return _exceptions.InternalServerError(err_msg, response=response, body=body) return APIStatusError(err_msg, response=response, body=body) class AsyncAnthropic(AsyncAPIClient): # client options api_key: str | None auth_token: str | None # constants HUMAN_PROMPT = _constants.HUMAN_PROMPT AI_PROMPT = _constants.AI_PROMPT def __init__( self, *, api_key: str | None = None, auth_token: str | None = None, base_url: str | httpx.URL | None = None, timeout: float | Timeout | None | NotGiven = not_given, max_retries: int = DEFAULT_MAX_RETRIES, default_headers: Mapping[str, str] | None = None, default_query: Mapping[str, object] | None = None, # Configure a custom httpx client. # We provide a `DefaultAsyncHttpxClient` class that you can pass to retain the default values we use for `limits`, `timeout` & `follow_redirects`. # See the [httpx documentation](https://www.python-httpx.org/api/#asyncclient) for more details. http_client: httpx.AsyncClient | None = None, # Enable or disable schema validation for data returned by the API. # When enabled an error APIResponseValidationError is raised # if the API responds with invalid data for the expected schema. # # This parameter may be removed or changed in the future. # If you rely on this feature, please open a GitHub issue # outlining your use-case to help us decide if it should be # part of our public interface in the future. _strict_response_validation: bool = False, ) -> None: """Construct a new async AsyncAnthropic client instance. This automatically infers the following arguments from their corresponding environment variables if they are not provided: - `api_key` from `ANTHROPIC_API_KEY` - `auth_token` from `ANTHROPIC_AUTH_TOKEN` """ if api_key is None: api_key = os.environ.get("ANTHROPIC_API_KEY") self.api_key = api_key if auth_token is None: auth_token = os.environ.get("ANTHROPIC_AUTH_TOKEN") self.auth_token = auth_token if base_url is None: base_url = os.environ.get("ANTHROPIC_BASE_URL") if base_url is None: base_url = f"https://api.anthropic.com" super().__init__( version=__version__, base_url=base_url, max_retries=max_retries, timeout=timeout, http_client=http_client, custom_headers=default_headers, custom_query=default_query, _strict_response_validation=_strict_response_validation, ) self._default_stream_cls = AsyncStream @cached_property def completions(self) -> AsyncCompletions: from .resources.completions import AsyncCompletions return AsyncCompletions(self) @cached_property def messages(self) -> AsyncMessages: from .resources.messages import AsyncMessages return AsyncMessages(self) @cached_property def models(self) -> AsyncModels: from .resources.models import AsyncModels return AsyncModels(self) @cached_property def beta(self) -> AsyncBeta: from .resources.beta import AsyncBeta return AsyncBeta(self) @cached_property def with_raw_response(self) -> AsyncAnthropicWithRawResponse: return AsyncAnthropicWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncAnthropicWithStreamedResponse: return AsyncAnthropicWithStreamedResponse(self) @property @override def qs(self) -> Querystring: return Querystring(array_format="comma") @property @override def auth_headers(self) -> dict[str, str]: return {**self._api_key_auth, **self._bearer_auth} @property def _api_key_auth(self) -> dict[str, str]: api_key = self.api_key if api_key is None: return {} return {"X-Api-Key": api_key} @property def _bearer_auth(self) -> dict[str, str]: auth_token = self.auth_token if auth_token is None: return {} return {"Authorization": f"Bearer {auth_token}"} @property @override def default_headers(self) -> dict[str, str | Omit]: return { **super().default_headers, "X-Stainless-Async": f"async:{get_async_library()}", "anthropic-version": "2023-06-01", **self._custom_headers, } @override def _validate_headers(self, headers: Headers, custom_headers: Headers) -> None: if self.api_key and headers.get("X-Api-Key"): return if isinstance(custom_headers.get("X-Api-Key"), Omit): return if self.auth_token and headers.get("Authorization"): return if isinstance(custom_headers.get("Authorization"), Omit): return raise TypeError( '"Could not resolve authentication method. Expected either api_key or auth_token to be set. Or for one of the `X-Api-Key` or `Authorization` headers to be explicitly omitted"' ) def copy( self, *, api_key: str | None = None, auth_token: str | None = None, base_url: str | httpx.URL | None = None, timeout: float | Timeout | None | NotGiven = not_given, http_client: httpx.AsyncClient | None = None, max_retries: int | NotGiven = not_given, default_headers: Mapping[str, str] | None = None, set_default_headers: Mapping[str, str] | None = None, default_query: Mapping[str, object] | None = None, set_default_query: Mapping[str, object] | None = None, _extra_kwargs: Mapping[str, Any] = {}, ) -> Self: """ Create a new client instance re-using the same options given to the current client with optional overriding. """ if default_headers is not None and set_default_headers is not None: raise ValueError("The `default_headers` and `set_default_headers` arguments are mutually exclusive") if default_query is not None and set_default_query is not None: raise ValueError("The `default_query` and `set_default_query` arguments are mutually exclusive") headers = self._custom_headers if default_headers is not None: headers = {**headers, **default_headers} elif set_default_headers is not None: headers = set_default_headers params = self._custom_query if default_query is not None: params = {**params, **default_query} elif set_default_query is not None: params = set_default_query http_client = http_client or self._client return self.__class__( api_key=api_key or self.api_key, auth_token=auth_token or self.auth_token, base_url=base_url or self.base_url, timeout=self.timeout if isinstance(timeout, NotGiven) else timeout, http_client=http_client, max_retries=max_retries if is_given(max_retries) else self.max_retries, default_headers=headers, default_query=params, **_extra_kwargs, ) # Alias for `copy` for nicer inline usage, e.g. # client.with_options(timeout=10).foo.create(...) with_options = copy @override def _make_status_error( self, err_msg: str, *, body: object, response: httpx.Response, ) -> APIStatusError: if response.status_code == 400: return _exceptions.BadRequestError(err_msg, response=response, body=body) if response.status_code == 401: return _exceptions.AuthenticationError(err_msg, response=response, body=body) if response.status_code == 403: return _exceptions.PermissionDeniedError(err_msg, response=response, body=body) if response.status_code == 404: return _exceptions.NotFoundError(err_msg, response=response, body=body) if response.status_code == 409: return _exceptions.ConflictError(err_msg, response=response, body=body) if response.status_code == 422: return _exceptions.UnprocessableEntityError(err_msg, response=response, body=body) if response.status_code == 429: return _exceptions.RateLimitError(err_msg, response=response, body=body) if response.status_code >= 500: return _exceptions.InternalServerError(err_msg, response=response, body=body) return APIStatusError(err_msg, response=response, body=body) class AnthropicWithRawResponse: _client: Anthropic def __init__(self, client: Anthropic) -> None: self._client = client @cached_property def completions(self) -> completions.CompletionsWithRawResponse: from .resources.completions import CompletionsWithRawResponse return CompletionsWithRawResponse(self._client.completions) @cached_property def messages(self) -> messages.MessagesWithRawResponse: from .resources.messages import MessagesWithRawResponse return MessagesWithRawResponse(self._client.messages) @cached_property def models(self) -> models.ModelsWithRawResponse: from .resources.models import ModelsWithRawResponse return ModelsWithRawResponse(self._client.models) @cached_property def beta(self) -> beta.BetaWithRawResponse: from .resources.beta import BetaWithRawResponse return BetaWithRawResponse(self._client.beta) class AsyncAnthropicWithRawResponse: _client: AsyncAnthropic def __init__(self, client: AsyncAnthropic) -> None: self._client = client @cached_property def completions(self) -> completions.AsyncCompletionsWithRawResponse: from .resources.completions import AsyncCompletionsWithRawResponse return AsyncCompletionsWithRawResponse(self._client.completions) @cached_property def messages(self) -> messages.AsyncMessagesWithRawResponse: from .resources.messages import AsyncMessagesWithRawResponse return AsyncMessagesWithRawResponse(self._client.messages) @cached_property def models(self) -> models.AsyncModelsWithRawResponse: from .resources.models import AsyncModelsWithRawResponse return AsyncModelsWithRawResponse(self._client.models) @cached_property def beta(self) -> beta.AsyncBetaWithRawResponse: from .resources.beta import AsyncBetaWithRawResponse return AsyncBetaWithRawResponse(self._client.beta) class AnthropicWithStreamedResponse: _client: Anthropic def __init__(self, client: Anthropic) -> None: self._client = client @cached_property def completions(self) -> completions.CompletionsWithStreamingResponse: from .resources.completions import CompletionsWithStreamingResponse return CompletionsWithStreamingResponse(self._client.completions) @cached_property def messages(self) -> messages.MessagesWithStreamingResponse: from .resources.messages import MessagesWithStreamingResponse return MessagesWithStreamingResponse(self._client.messages) @cached_property def models(self) -> models.ModelsWithStreamingResponse: from .resources.models import ModelsWithStreamingResponse return ModelsWithStreamingResponse(self._client.models) @cached_property def beta(self) -> beta.BetaWithStreamingResponse: from .resources.beta import BetaWithStreamingResponse return BetaWithStreamingResponse(self._client.beta) class AsyncAnthropicWithStreamedResponse: _client: AsyncAnthropic def __init__(self, client: AsyncAnthropic) -> None: self._client = client @cached_property def completions(self) -> completions.AsyncCompletionsWithStreamingResponse: from .resources.completions import AsyncCompletionsWithStreamingResponse return AsyncCompletionsWithStreamingResponse(self._client.completions) @cached_property def messages(self) -> messages.AsyncMessagesWithStreamingResponse: from .resources.messages import AsyncMessagesWithStreamingResponse return AsyncMessagesWithStreamingResponse(self._client.messages) @cached_property def models(self) -> models.AsyncModelsWithStreamingResponse: from .resources.models import AsyncModelsWithStreamingResponse return AsyncModelsWithStreamingResponse(self._client.models) @cached_property def beta(self) -> beta.AsyncBetaWithStreamingResponse: from .resources.beta import AsyncBetaWithStreamingResponse return AsyncBetaWithStreamingResponse(self._client.beta) Client = Anthropic AsyncClient = AsyncAnthropic anthropic-sdk-python-0.69.0/src/anthropic/_compat.py000066400000000000000000000146421506653454500224710ustar00rootroot00000000000000from __future__ import annotations from typing import TYPE_CHECKING, Any, Union, Generic, TypeVar, Callable, cast, overload from datetime import date, datetime from typing_extensions import Self, Literal import pydantic from pydantic.fields import FieldInfo from ._types import IncEx, StrBytesIntFloat _T = TypeVar("_T") _ModelT = TypeVar("_ModelT", bound=pydantic.BaseModel) # --------------- Pydantic v2, v3 compatibility --------------- # Pyright incorrectly reports some of our functions as overriding a method when they don't # pyright: reportIncompatibleMethodOverride=false PYDANTIC_V1 = pydantic.VERSION.startswith("1.") if TYPE_CHECKING: def parse_date(value: date | StrBytesIntFloat) -> date: # noqa: ARG001 ... def parse_datetime(value: Union[datetime, StrBytesIntFloat]) -> datetime: # noqa: ARG001 ... def get_args(t: type[Any]) -> tuple[Any, ...]: # noqa: ARG001 ... def is_union(tp: type[Any] | None) -> bool: # noqa: ARG001 ... def get_origin(t: type[Any]) -> type[Any] | None: # noqa: ARG001 ... def is_literal_type(type_: type[Any]) -> bool: # noqa: ARG001 ... def is_typeddict(type_: type[Any]) -> bool: # noqa: ARG001 ... else: # v1 re-exports if PYDANTIC_V1: from pydantic.typing import ( get_args as get_args, is_union as is_union, get_origin as get_origin, is_typeddict as is_typeddict, is_literal_type as is_literal_type, ) from pydantic.datetime_parse import parse_date as parse_date, parse_datetime as parse_datetime else: from ._utils import ( get_args as get_args, is_union as is_union, get_origin as get_origin, parse_date as parse_date, is_typeddict as is_typeddict, parse_datetime as parse_datetime, is_literal_type as is_literal_type, ) # refactored config if TYPE_CHECKING: from pydantic import ConfigDict as ConfigDict else: if PYDANTIC_V1: # TODO: provide an error message here? ConfigDict = None else: from pydantic import ConfigDict as ConfigDict # renamed methods / properties def parse_obj(model: type[_ModelT], value: object) -> _ModelT: if PYDANTIC_V1: return cast(_ModelT, model.parse_obj(value)) # pyright: ignore[reportDeprecated, reportUnnecessaryCast] else: return model.model_validate(value) def field_is_required(field: FieldInfo) -> bool: if PYDANTIC_V1: return field.required # type: ignore return field.is_required() def field_get_default(field: FieldInfo) -> Any: value = field.get_default() if PYDANTIC_V1: return value from pydantic_core import PydanticUndefined if value == PydanticUndefined: return None return value def field_outer_type(field: FieldInfo) -> Any: if PYDANTIC_V1: return field.outer_type_ # type: ignore return field.annotation def get_model_config(model: type[pydantic.BaseModel]) -> Any: if PYDANTIC_V1: return model.__config__ # type: ignore return model.model_config def get_model_fields(model: type[pydantic.BaseModel]) -> dict[str, FieldInfo]: if PYDANTIC_V1: return model.__fields__ # type: ignore return model.model_fields def model_copy(model: _ModelT, *, deep: bool = False) -> _ModelT: if PYDANTIC_V1: return model.copy(deep=deep) # type: ignore return model.model_copy(deep=deep) def model_json(model: pydantic.BaseModel, *, indent: int | None = None) -> str: if PYDANTIC_V1: return model.json(indent=indent) # type: ignore return model.model_dump_json(indent=indent) def model_dump( model: pydantic.BaseModel, *, exclude: IncEx | None = None, exclude_unset: bool = False, exclude_defaults: bool = False, warnings: bool = True, mode: Literal["json", "python"] = "python", ) -> dict[str, Any]: if (not PYDANTIC_V1) or hasattr(model, "model_dump"): return model.model_dump( mode=mode, exclude=exclude, exclude_unset=exclude_unset, exclude_defaults=exclude_defaults, # warnings are not supported in Pydantic v1 warnings=True if PYDANTIC_V1 else warnings, ) return cast( "dict[str, Any]", model.dict( # pyright: ignore[reportDeprecated, reportUnnecessaryCast] exclude=exclude, exclude_unset=exclude_unset, exclude_defaults=exclude_defaults, ), ) def model_parse(model: type[_ModelT], data: Any) -> _ModelT: if PYDANTIC_V1: return model.parse_obj(data) # pyright: ignore[reportDeprecated] return model.model_validate(data) # generic models if TYPE_CHECKING: class GenericModel(pydantic.BaseModel): ... else: if PYDANTIC_V1: import pydantic.generics class GenericModel(pydantic.generics.GenericModel, pydantic.BaseModel): ... else: # there no longer needs to be a distinction in v2 but # we still have to create our own subclass to avoid # inconsistent MRO ordering errors class GenericModel(pydantic.BaseModel): ... # cached properties if TYPE_CHECKING: cached_property = property # we define a separate type (copied from typeshed) # that represents that `cached_property` is `set`able # at runtime, which differs from `@property`. # # this is a separate type as editors likely special case # `@property` and we don't want to cause issues just to have # more helpful internal types. class typed_cached_property(Generic[_T]): func: Callable[[Any], _T] attrname: str | None def __init__(self, func: Callable[[Any], _T]) -> None: ... @overload def __get__(self, instance: None, owner: type[Any] | None = None) -> Self: ... @overload def __get__(self, instance: object, owner: type[Any] | None = None) -> _T: ... def __get__(self, instance: object, owner: type[Any] | None = None) -> _T | Self: raise NotImplementedError() def __set_name__(self, owner: type[Any], name: str) -> None: ... # __set__ is not defined at runtime, but @cached_property is designed to be settable def __set__(self, instance: object, value: _T) -> None: ... else: from functools import cached_property as cached_property typed_cached_property = cached_property anthropic-sdk-python-0.69.0/src/anthropic/_constants.py000066400000000000000000000015651506653454500232220ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import httpx RAW_RESPONSE_HEADER = "X-Stainless-Raw-Response" OVERRIDE_CAST_TO_HEADER = "____stainless_override_cast_to" # default timeout is 10 minutes DEFAULT_TIMEOUT = httpx.Timeout(timeout=10 * 60, connect=5.0) DEFAULT_MAX_RETRIES = 2 DEFAULT_CONNECTION_LIMITS = httpx.Limits(max_connections=1000, max_keepalive_connections=100) INITIAL_RETRY_DELAY = 0.5 MAX_RETRY_DELAY = 8.0 HUMAN_PROMPT = "\n\nHuman:" AI_PROMPT = "\n\nAssistant:" MODEL_NONSTREAMING_TOKENS = { "claude-opus-4-20250514": 8_192, "claude-opus-4-0": 8_192, "claude-4-opus-20250514": 8_192, "anthropic.claude-opus-4-20250514-v1:0": 8_192, "claude-opus-4@20250514": 8_192, "claude-opus-4-1-20250805": 8192, "anthropic.claude-opus-4-1-20250805-v1:0": 8192, "claude-opus-4-1@20250805": 8192, } anthropic-sdk-python-0.69.0/src/anthropic/_decoders/000077500000000000000000000000001506653454500224155ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/_decoders/jsonl.py000066400000000000000000000066661506653454500241320ustar00rootroot00000000000000from __future__ import annotations import json from typing_extensions import Generic, TypeVar, Iterator, AsyncIterator import httpx from .._models import construct_type_unchecked _T = TypeVar("_T") class JSONLDecoder(Generic[_T]): """A decoder for [JSON Lines](https://jsonlines.org) format. This class provides an iterator over a byte-iterator that parses each JSON Line into a given type. """ http_response: httpx.Response """The HTTP response this decoder was constructed from""" def __init__( self, *, raw_iterator: Iterator[bytes], line_type: type[_T], http_response: httpx.Response, ) -> None: super().__init__() self.http_response = http_response self._raw_iterator = raw_iterator self._line_type = line_type self._iterator = self.__decode__() def close(self) -> None: """Close the response body stream. This is called automatically if you consume the entire stream. """ self.http_response.close() def __decode__(self) -> Iterator[_T]: buf = b"" for chunk in self._raw_iterator: for line in chunk.splitlines(keepends=True): buf += line if buf.endswith((b"\r", b"\n", b"\r\n")): yield construct_type_unchecked( value=json.loads(buf), type_=self._line_type, ) buf = b"" # flush if buf: yield construct_type_unchecked( value=json.loads(buf), type_=self._line_type, ) def __next__(self) -> _T: return self._iterator.__next__() def __iter__(self) -> Iterator[_T]: for item in self._iterator: yield item class AsyncJSONLDecoder(Generic[_T]): """A decoder for [JSON Lines](https://jsonlines.org) format. This class provides an async iterator over a byte-iterator that parses each JSON Line into a given type. """ http_response: httpx.Response def __init__( self, *, raw_iterator: AsyncIterator[bytes], line_type: type[_T], http_response: httpx.Response, ) -> None: super().__init__() self.http_response = http_response self._raw_iterator = raw_iterator self._line_type = line_type self._iterator = self.__decode__() async def close(self) -> None: """Close the response body stream. This is called automatically if you consume the entire stream. """ await self.http_response.aclose() async def __decode__(self) -> AsyncIterator[_T]: buf = b"" async for chunk in self._raw_iterator: for line in chunk.splitlines(keepends=True): buf += line if buf.endswith((b"\r", b"\n", b"\r\n")): yield construct_type_unchecked( value=json.loads(buf), type_=self._line_type, ) buf = b"" # flush if buf: yield construct_type_unchecked( value=json.loads(buf), type_=self._line_type, ) async def __anext__(self) -> _T: return await self._iterator.__anext__() async def __aiter__(self) -> AsyncIterator[_T]: async for item in self._iterator: yield item anthropic-sdk-python-0.69.0/src/anthropic/_exceptions.py000066400000000000000000000077511506653454500233720ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal import httpx __all__ = [ "BadRequestError", "AuthenticationError", "PermissionDeniedError", "NotFoundError", "ConflictError", "UnprocessableEntityError", "RateLimitError", "InternalServerError", ] class AnthropicError(Exception): pass class APIError(AnthropicError): message: str request: httpx.Request body: object | None """The API response body. If the API responded with a valid JSON structure then this property will be the decoded result. If it isn't a valid JSON structure then this will be the raw response. If there was no response associated with this error then it will be `None`. """ def __init__(self, message: str, request: httpx.Request, *, body: object | None) -> None: # noqa: ARG002 super().__init__(message) self.request = request self.message = message self.body = body class APIResponseValidationError(APIError): response: httpx.Response status_code: int def __init__(self, response: httpx.Response, body: object | None, *, message: str | None = None) -> None: super().__init__(message or "Data returned by API invalid for expected schema.", response.request, body=body) self.response = response self.status_code = response.status_code class APIStatusError(APIError): """Raised when an API response has a status code of 4xx or 5xx.""" response: httpx.Response status_code: int request_id: str | None def __init__(self, message: str, *, response: httpx.Response, body: object | None) -> None: super().__init__(message, response.request, body=body) self.response = response self.status_code = response.status_code self.request_id = response.headers.get("request-id") class APIConnectionError(APIError): def __init__(self, *, message: str = "Connection error.", request: httpx.Request) -> None: super().__init__(message, request, body=None) class APITimeoutError(APIConnectionError): def __init__(self, request: httpx.Request) -> None: super().__init__( message="Request timed out or interrupted. This could be due to a network timeout, dropped connection, or request cancellation. See https://docs.anthropic.com/en/api/errors#long-requests for more details.", request=request, ) class BadRequestError(APIStatusError): status_code: Literal[400] = 400 # pyright: ignore[reportIncompatibleVariableOverride] class AuthenticationError(APIStatusError): status_code: Literal[401] = 401 # pyright: ignore[reportIncompatibleVariableOverride] class PermissionDeniedError(APIStatusError): status_code: Literal[403] = 403 # pyright: ignore[reportIncompatibleVariableOverride] class NotFoundError(APIStatusError): status_code: Literal[404] = 404 # pyright: ignore[reportIncompatibleVariableOverride] class ConflictError(APIStatusError): status_code: Literal[409] = 409 # pyright: ignore[reportIncompatibleVariableOverride] class RequestTooLargeError(APIStatusError): status_code: Literal[413] = 413 # pyright: ignore[reportIncompatibleVariableOverride] class UnprocessableEntityError(APIStatusError): status_code: Literal[422] = 422 # pyright: ignore[reportIncompatibleVariableOverride] class RateLimitError(APIStatusError): status_code: Literal[429] = 429 # pyright: ignore[reportIncompatibleVariableOverride] class ServiceUnavailableError(APIStatusError): status_code: Literal[503] = 503 # pyright: ignore[reportIncompatibleVariableOverride] class OverloadedError(APIStatusError): status_code: Literal[529] = 529 # pyright: ignore[reportIncompatibleVariableOverride] class DeadlineExceededError(APIStatusError): status_code: Literal[504] = 504 # pyright: ignore[reportIncompatibleVariableOverride] class InternalServerError(APIStatusError): pass anthropic-sdk-python-0.69.0/src/anthropic/_files.py000066400000000000000000000070471506653454500223110ustar00rootroot00000000000000from __future__ import annotations import io import os import pathlib from typing import overload from typing_extensions import TypeGuard import anyio from ._types import ( FileTypes, FileContent, RequestFiles, HttpxFileTypes, Base64FileInput, HttpxFileContent, HttpxRequestFiles, ) from ._utils import is_tuple_t, is_mapping_t, is_sequence_t def is_base64_file_input(obj: object) -> TypeGuard[Base64FileInput]: return isinstance(obj, io.IOBase) or isinstance(obj, os.PathLike) def is_file_content(obj: object) -> TypeGuard[FileContent]: return ( isinstance(obj, bytes) or isinstance(obj, tuple) or isinstance(obj, io.IOBase) or isinstance(obj, os.PathLike) ) def assert_is_file_content(obj: object, *, key: str | None = None) -> None: if not is_file_content(obj): prefix = f"Expected entry at `{key}`" if key is not None else f"Expected file input `{obj!r}`" raise RuntimeError( f"{prefix} to be bytes, an io.IOBase instance, PathLike or a tuple but received {type(obj)} instead. See https://github.com/anthropics/anthropic-sdk-python/tree/main#file-uploads" ) from None @overload def to_httpx_files(files: None) -> None: ... @overload def to_httpx_files(files: RequestFiles) -> HttpxRequestFiles: ... def to_httpx_files(files: RequestFiles | None) -> HttpxRequestFiles | None: if files is None: return None if is_mapping_t(files): files = {key: _transform_file(file) for key, file in files.items()} elif is_sequence_t(files): files = [(key, _transform_file(file)) for key, file in files] else: raise TypeError(f"Unexpected file type input {type(files)}, expected mapping or sequence") return files def _transform_file(file: FileTypes) -> HttpxFileTypes: if is_file_content(file): if isinstance(file, os.PathLike): path = pathlib.Path(file) return (path.name, path.read_bytes()) return file if is_tuple_t(file): return (file[0], read_file_content(file[1]), *file[2:]) raise TypeError(f"Expected file types input to be a FileContent type or to be a tuple") def read_file_content(file: FileContent) -> HttpxFileContent: if isinstance(file, os.PathLike): return pathlib.Path(file).read_bytes() return file @overload async def async_to_httpx_files(files: None) -> None: ... @overload async def async_to_httpx_files(files: RequestFiles) -> HttpxRequestFiles: ... async def async_to_httpx_files(files: RequestFiles | None) -> HttpxRequestFiles | None: if files is None: return None if is_mapping_t(files): files = {key: await _async_transform_file(file) for key, file in files.items()} 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") return files async def _async_transform_file(file: FileTypes) -> HttpxFileTypes: if is_file_content(file): if isinstance(file, os.PathLike): path = anyio.Path(file) return (path.name, await path.read_bytes()) return file if is_tuple_t(file): return (file[0], await async_read_file_content(file[1]), *file[2:]) raise TypeError(f"Expected file types input to be a FileContent type or to be a tuple") async def async_read_file_content(file: FileContent) -> HttpxFileContent: if isinstance(file, os.PathLike): return await anyio.Path(file).read_bytes() return file anthropic-sdk-python-0.69.0/src/anthropic/_legacy_response.py000066400000000000000000000415231506653454500243660ustar00rootroot00000000000000from __future__ import annotations import os import inspect import logging import datetime import functools from typing import ( TYPE_CHECKING, Any, Union, Generic, TypeVar, Callable, Iterator, AsyncIterator, cast, overload, ) from typing_extensions import Awaitable, ParamSpec, override, deprecated, get_origin import anyio import httpx import pydantic from ._types import NoneType from ._utils import is_given, extract_type_arg, is_annotated_type, is_type_alias_type from ._models import BaseModel, is_basemodel, add_request_id from ._constants import RAW_RESPONSE_HEADER from ._streaming import Stream, AsyncStream, is_stream_class_type, extract_stream_chunk_type from ._exceptions import APIResponseValidationError from ._decoders.jsonl import JSONLDecoder, AsyncJSONLDecoder if TYPE_CHECKING: from ._models import FinalRequestOptions from ._base_client import BaseClient P = ParamSpec("P") R = TypeVar("R") _T = TypeVar("_T") _T_co = TypeVar("_T_co", covariant=True) log: logging.Logger = logging.getLogger(__name__) class LegacyAPIResponse(Generic[R]): """This is a legacy class as it will be replaced by `APIResponse` and `AsyncAPIResponse` in the `_response.py` file in the next major release. For the sync client this will mostly be the same with the exception of `content` & `text` will be methods instead of properties. In the async client, all methods will be async. A migration script will be provided & the migration in general should be smooth. """ _cast_to: type[R] _client: BaseClient[Any, Any] _parsed_by_type: dict[type[Any], Any] _stream: bool _stream_cls: type[Stream[Any]] | type[AsyncStream[Any]] | None _options: FinalRequestOptions http_response: httpx.Response retries_taken: int """The number of retries made. If no retries happened this will be `0`""" def __init__( self, *, raw: httpx.Response, cast_to: type[R], client: BaseClient[Any, Any], stream: bool, stream_cls: type[Stream[Any]] | type[AsyncStream[Any]] | None, options: FinalRequestOptions, retries_taken: int = 0, ) -> None: self._cast_to = cast_to self._client = client self._parsed_by_type = {} self._stream = stream self._stream_cls = stream_cls self._options = options self.http_response = raw self.retries_taken = retries_taken @property def request_id(self) -> str | None: return self.http_response.headers.get("request-id") # type: ignore[no-any-return] @overload def parse(self, *, to: type[_T]) -> _T: ... @overload def parse(self) -> R: ... def parse(self, *, to: type[_T] | None = None) -> R | _T: """Returns the rich python representation of this response's data. NOTE: For the async client: this will become a coroutine in the next major version. For lower-level control, see `.read()`, `.json()`, `.iter_bytes()`. You can customise the type that the response is parsed into through the `to` argument, e.g. ```py from anthropic import BaseModel class MyModel(BaseModel): foo: str obj = response.parse(to=MyModel) print(obj.foo) ``` We support parsing: - `BaseModel` - `dict` - `list` - `Union` - `str` - `int` - `float` - `httpx.Response` """ cache_key = to if to is not None else self._cast_to cached = self._parsed_by_type.get(cache_key) if cached is not None: return cached # type: ignore[no-any-return] parsed = self._parse(to=to) if is_given(self._options.post_parser): parsed = self._options.post_parser(parsed) if isinstance(parsed, BaseModel): add_request_id(parsed, self.request_id) self._parsed_by_type[cache_key] = parsed return cast(R, parsed) @property def headers(self) -> httpx.Headers: return self.http_response.headers @property def http_request(self) -> httpx.Request: return self.http_response.request @property def status_code(self) -> int: return self.http_response.status_code @property def url(self) -> httpx.URL: return self.http_response.url @property def method(self) -> str: return self.http_request.method @property def content(self) -> bytes: """Return the binary response content. NOTE: this will be removed in favour of `.read()` in the next major version. """ return self.http_response.content @property def text(self) -> str: """Return the decoded response content. NOTE: this will be turned into a method in the next major version. """ return self.http_response.text @property def http_version(self) -> str: return self.http_response.http_version @property def is_closed(self) -> bool: return self.http_response.is_closed @property def elapsed(self) -> datetime.timedelta: """The time taken for the complete request/response cycle to complete.""" return self.http_response.elapsed def _parse(self, *, to: type[_T] | None = None) -> R | _T: cast_to = to if to is not None else self._cast_to # unwrap `TypeAlias('Name', T)` -> `T` if is_type_alias_type(cast_to): cast_to = cast_to.__value__ # type: ignore[unreachable] # unwrap `Annotated[T, ...]` -> `T` if cast_to and is_annotated_type(cast_to): cast_to = extract_type_arg(cast_to, 0) origin = get_origin(cast_to) or cast_to if inspect.isclass(origin): if issubclass(cast(Any, origin), JSONLDecoder): return cast( R, cast("type[JSONLDecoder[Any]]", cast_to)( raw_iterator=self.http_response.iter_bytes(chunk_size=64), line_type=extract_type_arg(cast_to, 0), http_response=self.http_response, ), ) if issubclass(cast(Any, origin), AsyncJSONLDecoder): return cast( R, cast("type[AsyncJSONLDecoder[Any]]", cast_to)( raw_iterator=self.http_response.aiter_bytes(chunk_size=64), line_type=extract_type_arg(cast_to, 0), http_response=self.http_response, ), ) if self._stream: if to: if not is_stream_class_type(to): raise TypeError(f"Expected custom parse type to be a subclass of {Stream} or {AsyncStream}") return cast( _T, to( cast_to=extract_stream_chunk_type( to, failure_message="Expected custom stream type to be passed with a type argument, e.g. Stream[ChunkType]", ), response=self.http_response, client=cast(Any, self._client), ), ) if self._stream_cls: return cast( R, self._stream_cls( cast_to=extract_stream_chunk_type(self._stream_cls), response=self.http_response, client=cast(Any, self._client), ), ) stream_cls = cast("type[Stream[Any]] | type[AsyncStream[Any]] | None", self._client._default_stream_cls) if stream_cls is None: raise MissingStreamClassError() return cast( R, stream_cls( cast_to=cast_to, response=self.http_response, client=cast(Any, self._client), ), ) if cast_to is NoneType: return cast(R, None) response = self.http_response if cast_to == str: return cast(R, response.text) if cast_to == int: return cast(R, int(response.text)) if cast_to == float: return cast(R, float(response.text)) if cast_to == bool: return cast(R, response.text.lower() == "true") if inspect.isclass(origin) and issubclass(origin, HttpxBinaryResponseContent): return cast(R, cast_to(response)) # type: ignore if origin == LegacyAPIResponse: raise RuntimeError("Unexpected state - cast_to is `APIResponse`") if inspect.isclass( origin # pyright: ignore[reportUnknownArgumentType] ) and issubclass(origin, httpx.Response): # Because of the invariance of our ResponseT TypeVar, users can subclass httpx.Response # and pass that class to our request functions. We cannot change the variance to be either # covariant or contravariant as that makes our usage of ResponseT illegal. We could construct # the response class ourselves but that is something that should be supported directly in httpx # as it would be easy to incorrectly construct the Response object due to the multitude of arguments. if cast_to != httpx.Response: raise ValueError(f"Subclasses of httpx.Response cannot be passed to `cast_to`") return cast(R, response) if ( inspect.isclass( origin # pyright: ignore[reportUnknownArgumentType] ) and not issubclass(origin, BaseModel) and issubclass(origin, pydantic.BaseModel) ): raise TypeError("Pydantic models must subclass our base model type, e.g. `from anthropic import BaseModel`") if ( cast_to is not object and not origin is list and not origin is dict and not origin is Union and not issubclass(origin, BaseModel) ): raise RuntimeError( f"Unsupported type, expected {cast_to} to be a subclass of {BaseModel}, {dict}, {list}, {Union}, {NoneType}, {str} or {httpx.Response}." ) # split is required to handle cases where additional information is included # in the response, e.g. application/json; charset=utf-8 content_type, *_ = response.headers.get("content-type", "*").split(";") if not content_type.endswith("json"): if is_basemodel(cast_to): try: data = response.json() except Exception as exc: log.debug("Could not read JSON from response data due to %s - %s", type(exc), exc) else: return self._client._process_response_data( data=data, cast_to=cast_to, # type: ignore response=response, ) if self._client._strict_response_validation: raise APIResponseValidationError( response=response, message=f"Expected Content-Type response header to be `application/json` but received `{content_type}` instead.", body=response.text, ) # If the API responds with content that isn't JSON then we just return # the (decoded) text without performing any parsing so that you can still # handle the response however you need to. return response.text # type: ignore data = response.json() return self._client._process_response_data( data=data, cast_to=cast_to, # type: ignore response=response, ) @override def __repr__(self) -> str: return f"" class MissingStreamClassError(TypeError): def __init__(self) -> None: super().__init__( "The `stream` argument was set to `True` but the `stream_cls` argument was not given. See `anthropic._streaming` for reference", ) def to_raw_response_wrapper(func: Callable[P, R]) -> Callable[P, LegacyAPIResponse[R]]: """Higher order function that takes one of our bound API methods and wraps it to support returning the raw `APIResponse` object directly. """ @functools.wraps(func) def wrapped(*args: P.args, **kwargs: P.kwargs) -> LegacyAPIResponse[R]: extra_headers: dict[str, str] = {**(cast(Any, kwargs.get("extra_headers")) or {})} extra_headers[RAW_RESPONSE_HEADER] = "true" kwargs["extra_headers"] = extra_headers return cast(LegacyAPIResponse[R], func(*args, **kwargs)) return wrapped def async_to_raw_response_wrapper(func: Callable[P, Awaitable[R]]) -> Callable[P, Awaitable[LegacyAPIResponse[R]]]: """Higher order function that takes one of our bound API methods and wraps it to support returning the raw `APIResponse` object directly. """ @functools.wraps(func) async def wrapped(*args: P.args, **kwargs: P.kwargs) -> LegacyAPIResponse[R]: extra_headers: dict[str, str] = {**(cast(Any, kwargs.get("extra_headers")) or {})} extra_headers[RAW_RESPONSE_HEADER] = "true" kwargs["extra_headers"] = extra_headers return cast(LegacyAPIResponse[R], await func(*args, **kwargs)) return wrapped class HttpxBinaryResponseContent: response: httpx.Response def __init__(self, response: httpx.Response) -> None: self.response = response @property def content(self) -> bytes: return self.response.content @property def text(self) -> str: return self.response.text @property def encoding(self) -> str | None: return self.response.encoding @property def charset_encoding(self) -> str | None: return self.response.charset_encoding def json(self, **kwargs: Any) -> Any: return self.response.json(**kwargs) def read(self) -> bytes: return self.response.read() def iter_bytes(self, chunk_size: int | None = None) -> Iterator[bytes]: return self.response.iter_bytes(chunk_size) def iter_text(self, chunk_size: int | None = None) -> Iterator[str]: return self.response.iter_text(chunk_size) def iter_lines(self) -> Iterator[str]: return self.response.iter_lines() def iter_raw(self, chunk_size: int | None = None) -> Iterator[bytes]: return self.response.iter_raw(chunk_size) def write_to_file( self, file: str | os.PathLike[str], ) -> None: """Write the output to the given file. Accepts a filename or any path-like object, e.g. pathlib.Path Note: if you want to stream the data to the file instead of writing all at once then you should use `.with_streaming_response` when making the API request, e.g. `client.with_streaming_response.foo().stream_to_file('my_filename.txt')` """ with open(file, mode="wb") as f: for data in self.response.iter_bytes(): f.write(data) @deprecated( "Due to a bug, this method doesn't actually stream the response content, `.with_streaming_response.method()` should be used instead" ) def stream_to_file( self, file: str | os.PathLike[str], *, chunk_size: int | None = None, ) -> None: with open(file, mode="wb") as f: for data in self.response.iter_bytes(chunk_size): f.write(data) def close(self) -> None: return self.response.close() async def aread(self) -> bytes: return await self.response.aread() async def aiter_bytes(self, chunk_size: int | None = None) -> AsyncIterator[bytes]: return self.response.aiter_bytes(chunk_size) async def aiter_text(self, chunk_size: int | None = None) -> AsyncIterator[str]: return self.response.aiter_text(chunk_size) async def aiter_lines(self) -> AsyncIterator[str]: return self.response.aiter_lines() async def aiter_raw(self, chunk_size: int | None = None) -> AsyncIterator[bytes]: return self.response.aiter_raw(chunk_size) @deprecated( "Due to a bug, this method doesn't actually stream the response content, `.with_streaming_response.method()` should be used instead" ) async def astream_to_file( self, file: str | os.PathLike[str], *, chunk_size: int | None = None, ) -> None: path = anyio.Path(file) async with await path.open(mode="wb") as f: async for data in self.response.aiter_bytes(chunk_size): await f.write(data) async def aclose(self) -> None: return await self.response.aclose() anthropic-sdk-python-0.69.0/src/anthropic/_models.py000066400000000000000000000763251506653454500224770ustar00rootroot00000000000000from __future__ import annotations import os import inspect from typing import TYPE_CHECKING, Any, Type, Union, Generic, TypeVar, Callable, Optional, cast from datetime import date, datetime from typing_extensions import ( List, Unpack, Literal, ClassVar, Protocol, Required, ParamSpec, TypedDict, TypeGuard, final, override, runtime_checkable, ) import pydantic from pydantic.fields import FieldInfo from ._types import ( Body, IncEx, Query, ModelT, Headers, Timeout, NotGiven, AnyMapping, HttpxRequestFiles, ) from ._utils import ( PropertyInfo, is_list, is_given, json_safe, lru_cache, is_mapping, parse_date, coerce_boolean, parse_datetime, strip_not_given, extract_type_arg, is_annotated_type, is_type_alias_type, strip_annotated_type, ) from ._compat import ( PYDANTIC_V1, ConfigDict, GenericModel as BaseGenericModel, get_args, is_union, parse_obj, get_origin, is_literal_type, get_model_config, get_model_fields, field_get_default, ) from ._constants import RAW_RESPONSE_HEADER if TYPE_CHECKING: from pydantic_core.core_schema import ModelField, ModelSchema, LiteralSchema, ModelFieldsSchema __all__ = ["BaseModel", "GenericModel"] _T = TypeVar("_T") _BaseModelT = TypeVar("_BaseModelT", bound="BaseModel") P = ParamSpec("P") @runtime_checkable class _ConfigProtocol(Protocol): allow_population_by_field_name: bool class BaseModel(pydantic.BaseModel): if PYDANTIC_V1: @property @override def model_fields_set(self) -> set[str]: # a forwards-compat shim for pydantic v2 return self.__fields_set__ # type: ignore class Config(pydantic.BaseConfig): # pyright: ignore[reportDeprecated] extra: Any = pydantic.Extra.allow # type: ignore else: model_config: ClassVar[ConfigDict] = ConfigDict( extra="allow", defer_build=coerce_boolean(os.environ.get("DEFER_PYDANTIC_BUILD", "true")) ) if TYPE_CHECKING: _request_id: Optional[str] = None """The ID of the request, returned via the `request-id` header. Useful for debugging requests and reporting issues to Anthropic. This will **only** be set for the top-level response object, it will not be defined for nested objects. For example: ```py message = await client.messages.create(...) message._request_id # req_xxx message.usage._request_id # raises `AttributeError` ``` Note: unlike other properties that use an `_` prefix, this property *is* public. Unless documented otherwise, all other `_` prefix properties, methods and modules are *private*. """ def to_dict( self, *, mode: Literal["json", "python"] = "python", use_api_names: bool = True, exclude_unset: bool = True, exclude_defaults: bool = False, exclude_none: bool = False, warnings: bool = True, ) -> dict[str, object]: """Recursively generate a dictionary representation of the model, optionally specifying which fields to include or exclude. By default, fields that were not set by the API will not be included, and keys will match the API response, *not* the property names from the model. For example, if the API responds with `"fooBar": true` but we've defined a `foo_bar: bool` property, the output will use the `"fooBar"` key (unless `use_api_names=False` is passed). Args: mode: If mode is 'json', the dictionary will only contain JSON serializable types. e.g. `datetime` will be turned into a string, `"2024-3-22T18:11:19.117000Z"`. If mode is 'python', the dictionary may contain any Python objects. e.g. `datetime(2024, 3, 22)` use_api_names: Whether to use the key that the API responded with or the property name. Defaults to `True`. exclude_unset: Whether to exclude fields that have not been explicitly set. exclude_defaults: Whether to exclude fields that are set to their default value from the output. exclude_none: Whether to exclude fields that have a value of `None` from the output. warnings: Whether to log warnings when invalid fields are encountered. This is only supported in Pydantic v2. """ return self.model_dump( mode=mode, by_alias=use_api_names, exclude_unset=exclude_unset, exclude_defaults=exclude_defaults, exclude_none=exclude_none, warnings=warnings, ) def to_json( self, *, indent: int | None = 2, use_api_names: bool = True, exclude_unset: bool = True, exclude_defaults: bool = False, exclude_none: bool = False, warnings: bool = True, ) -> str: """Generates a JSON string representing this model as it would be received from or sent to the API (but with indentation). By default, fields that were not set by the API will not be included, and keys will match the API response, *not* the property names from the model. For example, if the API responds with `"fooBar": true` but we've defined a `foo_bar: bool` property, the output will use the `"fooBar"` key (unless `use_api_names=False` is passed). Args: indent: Indentation to use in the JSON output. If `None` is passed, the output will be compact. Defaults to `2` use_api_names: Whether to use the key that the API responded with or the property name. Defaults to `True`. exclude_unset: Whether to exclude fields that have not been explicitly set. exclude_defaults: Whether to exclude fields that have the default value. exclude_none: Whether to exclude fields that have a value of `None`. warnings: Whether to show any warnings that occurred during serialization. This is only supported in Pydantic v2. """ return self.model_dump_json( indent=indent, by_alias=use_api_names, exclude_unset=exclude_unset, exclude_defaults=exclude_defaults, exclude_none=exclude_none, warnings=warnings, ) @override def __str__(self) -> str: # mypy complains about an invalid self arg return f"{self.__repr_name__()}({self.__repr_str__(', ')})" # type: ignore[misc] # Override the 'construct' method in a way that supports recursive parsing without validation. # Based on https://github.com/samuelcolvin/pydantic/issues/1168#issuecomment-817742836. @classmethod @override def construct( # pyright: ignore[reportIncompatibleMethodOverride] __cls: Type[ModelT], _fields_set: set[str] | None = None, **values: object, ) -> ModelT: m = __cls.__new__(__cls) fields_values: dict[str, object] = {} config = get_model_config(__cls) populate_by_name = ( config.allow_population_by_field_name if isinstance(config, _ConfigProtocol) else config.get("populate_by_name") ) if _fields_set is None: _fields_set = set() model_fields = get_model_fields(__cls) for name, field in model_fields.items(): key = field.alias if key is None or (key not in values and populate_by_name): key = name if key in values: fields_values[name] = _construct_field(value=values[key], field=field, key=key) _fields_set.add(name) else: fields_values[name] = field_get_default(field) extra_field_type = _get_extra_fields_type(__cls) _extra = {} for key, value in values.items(): if key not in model_fields: parsed = construct_type(value=value, type_=extra_field_type) if extra_field_type is not None else value if PYDANTIC_V1: _fields_set.add(key) fields_values[key] = parsed else: _extra[key] = parsed object.__setattr__(m, "__dict__", fields_values) if PYDANTIC_V1: # init_private_attributes() does not exist in v2 m._init_private_attributes() # type: ignore # copied from Pydantic v1's `construct()` method object.__setattr__(m, "__fields_set__", _fields_set) else: # these properties are copied from Pydantic's `model_construct()` method object.__setattr__(m, "__pydantic_private__", None) object.__setattr__(m, "__pydantic_extra__", _extra) object.__setattr__(m, "__pydantic_fields_set__", _fields_set) return m if not TYPE_CHECKING: # type checkers incorrectly complain about this assignment # because the type signatures are technically different # although not in practice model_construct = construct if PYDANTIC_V1: # we define aliases for some of the new pydantic v2 methods so # that we can just document these methods without having to specify # a specific pydantic version as some users may not know which # pydantic version they are currently using @override def model_dump( self, *, mode: Literal["json", "python"] | str = "python", include: IncEx | None = None, exclude: IncEx | None = None, by_alias: bool | None = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, round_trip: bool = False, warnings: bool | Literal["none", "warn", "error"] = True, context: dict[str, Any] | None = None, serialize_as_any: bool = False, fallback: Callable[[Any], Any] | None = None, ) -> dict[str, Any]: """Usage docs: https://docs.pydantic.dev/2.4/concepts/serialization/#modelmodel_dump Generate a dictionary representation of the model, optionally specifying which fields to include or exclude. Args: mode: The mode in which `to_python` should run. If mode is 'json', the dictionary will only contain JSON serializable types. If mode is 'python', the dictionary may contain any Python objects. include: A list of fields to include in the output. exclude: A list of fields to exclude from the output. by_alias: Whether to use the field's alias in the dictionary key if defined. exclude_unset: Whether to exclude fields that are unset or None from the output. exclude_defaults: Whether to exclude fields that are set to their default value from the output. exclude_none: Whether to exclude fields that have a value of `None` from the output. round_trip: Whether to enable serialization and deserialization round-trip support. warnings: Whether to log warnings when invalid fields are encountered. Returns: A dictionary representation of the model. """ if mode not in {"json", "python"}: raise ValueError("mode must be either 'json' or 'python'") if round_trip != False: raise ValueError("round_trip is only supported in Pydantic v2") if warnings != True: raise ValueError("warnings is only supported in Pydantic v2") if context is not None: raise ValueError("context is only supported in Pydantic v2") if serialize_as_any != False: raise ValueError("serialize_as_any is only supported in Pydantic v2") if fallback is not None: raise ValueError("fallback is only supported in Pydantic v2") dumped = super().dict( # pyright: ignore[reportDeprecated] include=include, exclude=exclude, by_alias=by_alias if by_alias is not None else False, exclude_unset=exclude_unset, exclude_defaults=exclude_defaults, exclude_none=exclude_none, ) return cast("dict[str, Any]", json_safe(dumped)) if mode == "json" else dumped @override def model_dump_json( self, *, indent: int | None = None, include: IncEx | None = None, exclude: IncEx | None = None, by_alias: bool | None = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, round_trip: bool = False, warnings: bool | Literal["none", "warn", "error"] = True, context: dict[str, Any] | None = None, fallback: Callable[[Any], Any] | None = None, serialize_as_any: bool = False, ) -> str: """Usage docs: https://docs.pydantic.dev/2.4/concepts/serialization/#modelmodel_dump_json Generates a JSON representation of the model using Pydantic's `to_json` method. Args: indent: Indentation to use in the JSON output. If None is passed, the output will be compact. include: Field(s) to include in the JSON output. Can take either a string or set of strings. exclude: Field(s) to exclude from the JSON output. Can take either a string or set of strings. by_alias: Whether to serialize using field aliases. exclude_unset: Whether to exclude fields that have not been explicitly set. exclude_defaults: Whether to exclude fields that have the default value. exclude_none: Whether to exclude fields that have a value of `None`. round_trip: Whether to use serialization/deserialization between JSON and class instance. warnings: Whether to show any warnings that occurred during serialization. Returns: A JSON string representation of the model. """ if round_trip != False: raise ValueError("round_trip is only supported in Pydantic v2") if warnings != True: raise ValueError("warnings is only supported in Pydantic v2") if context is not None: raise ValueError("context is only supported in Pydantic v2") if serialize_as_any != False: raise ValueError("serialize_as_any is only supported in Pydantic v2") if fallback is not None: raise ValueError("fallback is only supported in Pydantic v2") return super().json( # type: ignore[reportDeprecated] indent=indent, include=include, exclude=exclude, by_alias=by_alias if by_alias is not None else False, exclude_unset=exclude_unset, exclude_defaults=exclude_defaults, exclude_none=exclude_none, ) def _construct_field(value: object, field: FieldInfo, key: str) -> object: if value is None: return field_get_default(field) if PYDANTIC_V1: type_ = cast(type, field.outer_type_) # type: ignore else: type_ = field.annotation # type: ignore if type_ is None: raise RuntimeError(f"Unexpected field type is None for {key}") return construct_type(value=value, type_=type_, metadata=getattr(field, "metadata", None)) def _get_extra_fields_type(cls: type[pydantic.BaseModel]) -> type | None: if PYDANTIC_V1: # TODO return None schema = cls.__pydantic_core_schema__ if schema["type"] == "model": fields = schema["schema"] if fields["type"] == "model-fields": extras = fields.get("extras_schema") if extras and "cls" in extras: # mypy can't narrow the type return extras["cls"] # type: ignore[no-any-return] return None def is_basemodel(type_: type) -> bool: """Returns whether or not the given type is either a `BaseModel` or a union of `BaseModel`""" if is_union(type_): for variant in get_args(type_): if is_basemodel(variant): return True return False return is_basemodel_type(type_) def is_basemodel_type(type_: type) -> TypeGuard[type[BaseModel] | type[GenericModel]]: origin = get_origin(type_) or type_ if not inspect.isclass(origin): return False return issubclass(origin, BaseModel) or issubclass(origin, GenericModel) def build( base_model_cls: Callable[P, _BaseModelT], *args: P.args, **kwargs: P.kwargs, ) -> _BaseModelT: """Construct a BaseModel class without validation. This is useful for cases where you need to instantiate a `BaseModel` from an API response as this provides type-safe params which isn't supported by helpers like `construct_type()`. ```py build(MyModel, my_field_a="foo", my_field_b=123) ``` """ if args: raise TypeError( "Received positional arguments which are not supported; Keyword arguments must be used instead", ) return cast(_BaseModelT, construct_type(type_=base_model_cls, value=kwargs)) def construct_type_unchecked(*, value: object, type_: type[_T]) -> _T: """Loose coercion to the expected type with construction of nested values. Note: the returned value from this function is not guaranteed to match the given type. """ return cast(_T, construct_type(value=value, type_=type_)) def construct_type(*, value: object, type_: object, metadata: Optional[List[Any]] = None) -> object: """Loose coercion to the expected type with construction of nested values. If the given value does not match the expected type then it is returned as-is. """ # store a reference to the original type we were given before we extract any inner # types so that we can properly resolve forward references in `TypeAliasType` annotations original_type = None # we allow `object` as the input type because otherwise, passing things like # `Literal['value']` will be reported as a type error by type checkers type_ = cast("type[object]", type_) if is_type_alias_type(type_): original_type = type_ # type: ignore[unreachable] type_ = type_.__value__ # type: ignore[unreachable] # unwrap `Annotated[T, ...]` -> `T` if metadata is not None and len(metadata) > 0: meta: tuple[Any, ...] = tuple(metadata) elif is_annotated_type(type_): meta = get_args(type_)[1:] type_ = extract_type_arg(type_, 0) else: meta = tuple() # we need to use the origin class for any types that are subscripted generics # e.g. Dict[str, object] origin = get_origin(type_) or type_ args = get_args(type_) if is_union(origin): try: return validate_type(type_=cast("type[object]", original_type or type_), value=value) except Exception: pass # if the type is a discriminated union then we want to construct the right variant # in the union, even if the data doesn't match exactly, otherwise we'd break code # that relies on the constructed class types, e.g. # # class FooType: # kind: Literal['foo'] # value: str # # class BarType: # kind: Literal['bar'] # value: int # # without this block, if the data we get is something like `{'kind': 'bar', 'value': 'foo'}` then # we'd end up constructing `FooType` when it should be `BarType`. discriminator = _build_discriminated_union_meta(union=type_, meta_annotations=meta) if discriminator and is_mapping(value): variant_value = value.get(discriminator.field_alias_from or discriminator.field_name) if variant_value and isinstance(variant_value, str): variant_type = discriminator.mapping.get(variant_value) if variant_type: return construct_type(type_=variant_type, value=value) # if the data is not valid, use the first variant that doesn't fail while deserializing for variant in args: try: return construct_type(value=value, type_=variant) except Exception: continue raise RuntimeError(f"Could not convert data into a valid instance of {type_}") if origin == dict: if not is_mapping(value): return value _, items_type = get_args(type_) # Dict[_, items_type] return {key: construct_type(value=item, type_=items_type) for key, item in value.items()} if ( not is_literal_type(type_) and inspect.isclass(origin) and (issubclass(origin, BaseModel) or issubclass(origin, GenericModel)) ): if is_list(value): return [cast(Any, type_).construct(**entry) if is_mapping(entry) else entry for entry in value] if is_mapping(value): if issubclass(type_, BaseModel): return type_.construct(**value) # type: ignore[arg-type] return cast(Any, type_).construct(**value) if origin == list: if not is_list(value): return value inner_type = args[0] # List[inner_type] return [construct_type(value=entry, type_=inner_type) for entry in value] if origin == float: if isinstance(value, int): coerced = float(value) if coerced != value: return value return coerced return value if type_ == datetime: try: return parse_datetime(value) # type: ignore except Exception: return value if type_ == date: try: return parse_date(value) # type: ignore except Exception: return value return value @runtime_checkable class CachedDiscriminatorType(Protocol): __discriminator__: DiscriminatorDetails class DiscriminatorDetails: field_name: str """The name of the discriminator field in the variant class, e.g. ```py class Foo(BaseModel): type: Literal['foo'] ``` Will result in field_name='type' """ field_alias_from: str | None """The name of the discriminator field in the API response, e.g. ```py class Foo(BaseModel): type: Literal['foo'] = Field(alias='type_from_api') ``` Will result in field_alias_from='type_from_api' """ mapping: dict[str, type] """Mapping of discriminator value to variant type, e.g. {'foo': FooVariant, 'bar': BarVariant} """ def __init__( self, *, mapping: dict[str, type], discriminator_field: str, discriminator_alias: str | None, ) -> None: self.mapping = mapping self.field_name = discriminator_field self.field_alias_from = discriminator_alias def _build_discriminated_union_meta(*, union: type, meta_annotations: tuple[Any, ...]) -> DiscriminatorDetails | None: if isinstance(union, CachedDiscriminatorType): return union.__discriminator__ discriminator_field_name: str | None = None for annotation in meta_annotations: if isinstance(annotation, PropertyInfo) and annotation.discriminator is not None: discriminator_field_name = annotation.discriminator break if not discriminator_field_name: return None mapping: dict[str, type] = {} discriminator_alias: str | None = None for variant in get_args(union): variant = strip_annotated_type(variant) if is_basemodel_type(variant): if PYDANTIC_V1: field_info = cast("dict[str, FieldInfo]", variant.__fields__).get(discriminator_field_name) # pyright: ignore[reportDeprecated, reportUnnecessaryCast] if not field_info: continue # Note: if one variant defines an alias then they all should discriminator_alias = field_info.alias if (annotation := getattr(field_info, "annotation", None)) and is_literal_type(annotation): for entry in get_args(annotation): if isinstance(entry, str): mapping[entry] = variant else: field = _extract_field_schema_pv2(variant, discriminator_field_name) if not field: continue # Note: if one variant defines an alias then they all should discriminator_alias = field.get("serialization_alias") field_schema = field["schema"] if field_schema["type"] == "literal": for entry in cast("LiteralSchema", field_schema)["expected"]: if isinstance(entry, str): mapping[entry] = variant if not mapping: return None details = DiscriminatorDetails( mapping=mapping, discriminator_field=discriminator_field_name, discriminator_alias=discriminator_alias, ) cast(CachedDiscriminatorType, union).__discriminator__ = details return details def _extract_field_schema_pv2(model: type[BaseModel], field_name: str) -> ModelField | None: schema = model.__pydantic_core_schema__ if schema["type"] == "definitions": schema = schema["schema"] if schema["type"] != "model": return None schema = cast("ModelSchema", schema) fields_schema = schema["schema"] if fields_schema["type"] != "model-fields": return None fields_schema = cast("ModelFieldsSchema", fields_schema) field = fields_schema["fields"].get(field_name) if not field: return None return cast("ModelField", field) # pyright: ignore[reportUnnecessaryCast] def validate_type(*, type_: type[_T], value: object) -> _T: """Strict validation that the given value matches the expected type""" if inspect.isclass(type_) and issubclass(type_, pydantic.BaseModel): return cast(_T, parse_obj(type_, value)) return cast(_T, _validate_non_model_type(type_=type_, value=value)) def set_pydantic_config(typ: Any, config: pydantic.ConfigDict) -> None: """Add a pydantic config for the given type. Note: this is a no-op on Pydantic v1. """ setattr(typ, "__pydantic_config__", config) # noqa: B010 def add_request_id(obj: BaseModel, request_id: str | None) -> None: obj._request_id = request_id # in Pydantic v1, using setattr like we do above causes the attribute # to be included when serializing the model which we don't want in this # case so we need to explicitly exclude it if PYDANTIC_V1: try: exclude_fields = obj.__exclude_fields__ # type: ignore except AttributeError: cast(Any, obj).__exclude_fields__ = {"_request_id", "__exclude_fields__"} else: cast(Any, obj).__exclude_fields__ = {*(exclude_fields or {}), "_request_id", "__exclude_fields__"} # our use of subclassing here causes weirdness for type checkers, # so we just pretend that we don't subclass if TYPE_CHECKING: GenericModel = BaseModel else: class GenericModel(BaseGenericModel, BaseModel): pass if not PYDANTIC_V1: from pydantic import TypeAdapter as _TypeAdapter _CachedTypeAdapter = cast("TypeAdapter[object]", lru_cache(maxsize=None)(_TypeAdapter)) if TYPE_CHECKING: from pydantic import TypeAdapter else: TypeAdapter = _CachedTypeAdapter def _validate_non_model_type(*, type_: type[_T], value: object) -> _T: return TypeAdapter(type_).validate_python(value) elif not TYPE_CHECKING: # TODO: condition is weird class RootModel(GenericModel, Generic[_T]): """Used as a placeholder to easily convert runtime types to a Pydantic format to provide validation. For example: ```py validated = RootModel[int](__root__="5").__root__ # validated: 5 ``` """ __root__: _T def _validate_non_model_type(*, type_: type[_T], value: object) -> _T: model = _create_pydantic_model(type_).validate(value) return cast(_T, model.__root__) def _create_pydantic_model(type_: _T) -> Type[RootModel[_T]]: return RootModel[type_] # type: ignore def TypeAdapter(*_args: Any, **_kwargs: Any) -> Any: raise RuntimeError("attempted to use TypeAdapter in pydantic v1") class FinalRequestOptionsInput(TypedDict, total=False): method: Required[str] url: Required[str] params: Query headers: Headers max_retries: int timeout: float | Timeout | None files: HttpxRequestFiles | None idempotency_key: str json_data: Body extra_json: AnyMapping follow_redirects: bool @final class FinalRequestOptions(pydantic.BaseModel): method: str url: str params: Query = {} headers: Union[Headers, NotGiven] = NotGiven() max_retries: Union[int, NotGiven] = NotGiven() timeout: Union[float, Timeout, None, NotGiven] = NotGiven() files: Union[HttpxRequestFiles, None] = None idempotency_key: Union[str, None] = None post_parser: Union[Callable[[Any], Any], NotGiven] = NotGiven() follow_redirects: Union[bool, 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 extra_json: Union[AnyMapping, None] = None if PYDANTIC_V1: class Config(pydantic.BaseConfig): # pyright: ignore[reportDeprecated] arbitrary_types_allowed: bool = True else: model_config: ClassVar[ConfigDict] = ConfigDict(arbitrary_types_allowed=True) def get_max_retries(self, max_retries: int) -> int: if isinstance(self.max_retries, NotGiven): return max_retries return self.max_retries def _strip_raw_response_header(self) -> None: if not is_given(self.headers): return if self.headers.get(RAW_RESPONSE_HEADER): self.headers = {**self.headers} self.headers.pop(RAW_RESPONSE_HEADER) # override the `construct` method so that we can run custom transformations. # this is necessary as we don't want to do any actual runtime type checking # (which means we can't use validators) but we do want to ensure that `NotGiven` # values are not present # # type ignore required because we're adding explicit types to `**values` @classmethod def construct( # type: ignore cls, _fields_set: set[str] | None = None, **values: Unpack[FinalRequestOptionsInput], ) -> FinalRequestOptions: kwargs: dict[str, Any] = { # we unconditionally call `strip_not_given` on any value # as it will just ignore any non-mapping types key: strip_not_given(value) for key, value in values.items() } if PYDANTIC_V1: return cast(FinalRequestOptions, super().construct(_fields_set, **kwargs)) # pyright: ignore[reportDeprecated] return super().model_construct(_fields_set, **kwargs) if not TYPE_CHECKING: # type checkers incorrectly complain about this assignment model_construct = construct anthropic-sdk-python-0.69.0/src/anthropic/_qs.py000066400000000000000000000113341506653454500216240ustar00rootroot00000000000000from __future__ import annotations from typing import Any, List, Tuple, Union, Mapping, TypeVar from urllib.parse import parse_qs, urlencode from typing_extensions import Literal, get_args from ._types import NotGiven, 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 Data = Union[PrimitiveData, List[Any], Tuple[Any], "Mapping[str, Any]"] Params = Mapping[str, Data] class Querystring: array_format: ArrayFormat nested_format: NestedFormat def __init__( self, *, array_format: ArrayFormat = "repeat", nested_format: NestedFormat = "brackets", ) -> None: self.array_format = array_format self.nested_format = nested_format def parse(self, query: str) -> Mapping[str, object]: # Note: custom format syntax is not supported yet return parse_qs(query) def stringify( self, params: Params, *, array_format: ArrayFormat | NotGiven = not_given, nested_format: NestedFormat | NotGiven = not_given, ) -> str: return urlencode( self.stringify_items( params, array_format=array_format, nested_format=nested_format, ) ) def stringify_items( self, params: Params, *, array_format: ArrayFormat | NotGiven = not_given, nested_format: NestedFormat | NotGiven = not_given, ) -> list[tuple[str, str]]: opts = Options( qs=self, array_format=array_format, nested_format=nested_format, ) return flatten([self._stringify_item(key, value, opts) for key, value in params.items()]) def _stringify_item( self, key: str, value: Data, opts: Options, ) -> list[tuple[str, str]]: if isinstance(value, Mapping): items: list[tuple[str, str]] = [] nested_format = opts.nested_format for subkey, subvalue in value.items(): items.extend( self._stringify_item( # TODO: error if unknown format f"{key}.{subkey}" if nested_format == "dots" else f"{key}[{subkey}]", subvalue, opts, ) ) return items if isinstance(value, (list, tuple)): array_format = opts.array_format if array_format == "comma": return [ ( key, ",".join(self._primitive_value_to_str(item) for item in value if item is not None), ), ] elif array_format == "repeat": items = [] for item in value: items.extend(self._stringify_item(key, item, opts)) return items elif array_format == "indices": raise NotImplementedError("The array indices format is not supported yet") elif array_format == "brackets": items = [] key = key + "[]" for item in value: items.extend(self._stringify_item(key, item, opts)) return items else: raise NotImplementedError( f"Unknown array_format value: {array_format}, choose from {', '.join(get_args(ArrayFormat))}" ) serialised = self._primitive_value_to_str(value) if not serialised: return [] return [(key, serialised)] def _primitive_value_to_str(self, value: PrimitiveData) -> str: # copied from httpx if value is True: return "true" elif value is False: return "false" elif value is None: return "" return str(value) _qs = Querystring() parse = _qs.parse stringify = _qs.stringify stringify_items = _qs.stringify_items class Options: array_format: ArrayFormat nested_format: NestedFormat def __init__( self, qs: Querystring = _qs, *, array_format: ArrayFormat | NotGiven = not_given, nested_format: NestedFormat | NotGiven = not_given, ) -> None: self.array_format = qs.array_format if isinstance(array_format, NotGiven) else array_format self.nested_format = qs.nested_format if isinstance(nested_format, NotGiven) else nested_format anthropic-sdk-python-0.69.0/src/anthropic/_resource.py000066400000000000000000000020701506653454500230250ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations import time import anyio from ._base_client import SyncAPIClient, AsyncAPIClient class SyncAPIResource: _client: SyncAPIClient def __init__(self, client: SyncAPIClient) -> None: self._client = client self._get = client.get self._post = client.post self._patch = client.patch self._put = client.put self._delete = client.delete self._get_api_list = client.get_api_list def _sleep(self, seconds: float) -> None: time.sleep(seconds) class AsyncAPIResource: _client: AsyncAPIClient def __init__(self, client: AsyncAPIClient) -> None: self._client = client self._get = client.get self._post = client.post self._patch = client.patch self._put = client.put self._delete = client.delete self._get_api_list = client.get_api_list async def _sleep(self, seconds: float) -> None: await anyio.sleep(seconds) anthropic-sdk-python-0.69.0/src/anthropic/_response.py000066400000000000000000000735161506653454500230510ustar00rootroot00000000000000from __future__ import annotations import os import inspect import logging import datetime import functools from types import TracebackType from typing import ( TYPE_CHECKING, Any, Union, Generic, TypeVar, Callable, Iterator, AsyncIterator, cast, overload, ) from typing_extensions import Awaitable, ParamSpec, override, get_origin import anyio import httpx import pydantic from ._types import NoneType from ._utils import is_given, extract_type_arg, is_annotated_type, is_type_alias_type, extract_type_var_from_base from ._models import BaseModel, is_basemodel, add_request_id from ._constants import RAW_RESPONSE_HEADER, OVERRIDE_CAST_TO_HEADER from ._streaming import Stream, AsyncStream, is_stream_class_type, extract_stream_chunk_type from ._exceptions import AnthropicError, APIResponseValidationError from ._decoders.jsonl import JSONLDecoder, AsyncJSONLDecoder if TYPE_CHECKING: from ._models import FinalRequestOptions from ._base_client import BaseClient P = ParamSpec("P") R = TypeVar("R") _T = TypeVar("_T") _APIResponseT = TypeVar("_APIResponseT", bound="APIResponse[Any]") _AsyncAPIResponseT = TypeVar("_AsyncAPIResponseT", bound="AsyncAPIResponse[Any]") log: logging.Logger = logging.getLogger(__name__) class BaseAPIResponse(Generic[R]): _cast_to: type[R] _client: BaseClient[Any, Any] _parsed_by_type: dict[type[Any], Any] _is_sse_stream: bool _stream_cls: type[Stream[Any]] | type[AsyncStream[Any]] | None _options: FinalRequestOptions http_response: httpx.Response retries_taken: int """The number of retries made. If no retries happened this will be `0`""" def __init__( self, *, raw: httpx.Response, cast_to: type[R], client: BaseClient[Any, Any], stream: bool, stream_cls: type[Stream[Any]] | type[AsyncStream[Any]] | None, options: FinalRequestOptions, retries_taken: int = 0, ) -> None: self._cast_to = cast_to self._client = client self._parsed_by_type = {} self._is_sse_stream = stream self._stream_cls = stream_cls self._options = options self.http_response = raw self.retries_taken = retries_taken @property def headers(self) -> httpx.Headers: return self.http_response.headers @property def http_request(self) -> httpx.Request: """Returns the httpx Request instance associated with the current response.""" return self.http_response.request @property def status_code(self) -> int: return self.http_response.status_code @property def url(self) -> httpx.URL: """Returns the URL for which the request was made.""" return self.http_response.url @property def method(self) -> str: return self.http_request.method @property def http_version(self) -> str: return self.http_response.http_version @property def elapsed(self) -> datetime.timedelta: """The time taken for the complete request/response cycle to complete.""" return self.http_response.elapsed @property def is_closed(self) -> bool: """Whether or not the response body has been closed. If this is False then there is response data that has not been read yet. You must either fully consume the response body or call `.close()` before discarding the response to prevent resource leaks. """ return self.http_response.is_closed @override def __repr__(self) -> str: return ( f"<{self.__class__.__name__} [{self.status_code} {self.http_response.reason_phrase}] type={self._cast_to}>" ) def _parse(self, *, to: type[_T] | None = None) -> R | _T: cast_to = to if to is not None else self._cast_to # unwrap `TypeAlias('Name', T)` -> `T` if is_type_alias_type(cast_to): cast_to = cast_to.__value__ # type: ignore[unreachable] # unwrap `Annotated[T, ...]` -> `T` if cast_to and is_annotated_type(cast_to): cast_to = extract_type_arg(cast_to, 0) origin = get_origin(cast_to) or cast_to if inspect.isclass(origin): if issubclass(cast(Any, origin), JSONLDecoder): return cast( R, cast("type[JSONLDecoder[Any]]", cast_to)( raw_iterator=self.http_response.iter_bytes(chunk_size=64), line_type=extract_type_arg(cast_to, 0), http_response=self.http_response, ), ) if issubclass(cast(Any, origin), AsyncJSONLDecoder): return cast( R, cast("type[AsyncJSONLDecoder[Any]]", cast_to)( raw_iterator=self.http_response.aiter_bytes(chunk_size=64), line_type=extract_type_arg(cast_to, 0), http_response=self.http_response, ), ) if self._is_sse_stream: if to: if not is_stream_class_type(to): raise TypeError(f"Expected custom parse type to be a subclass of {Stream} or {AsyncStream}") return cast( _T, to( cast_to=extract_stream_chunk_type( to, failure_message="Expected custom stream type to be passed with a type argument, e.g. Stream[ChunkType]", ), response=self.http_response, client=cast(Any, self._client), ), ) if self._stream_cls: return cast( R, self._stream_cls( cast_to=extract_stream_chunk_type(self._stream_cls), response=self.http_response, client=cast(Any, self._client), ), ) stream_cls = cast("type[Stream[Any]] | type[AsyncStream[Any]] | None", self._client._default_stream_cls) if stream_cls is None: raise MissingStreamClassError() return cast( R, stream_cls( cast_to=cast_to, response=self.http_response, client=cast(Any, self._client), ), ) if cast_to is NoneType: return cast(R, None) response = self.http_response if cast_to == str: return cast(R, response.text) if cast_to == bytes: return cast(R, response.content) if cast_to == int: return cast(R, int(response.text)) if cast_to == float: return cast(R, float(response.text)) if cast_to == bool: return cast(R, response.text.lower() == "true") # handle the legacy binary response case if inspect.isclass(cast_to) and cast_to.__name__ == "HttpxBinaryResponseContent": return cast(R, cast_to(response)) # type: ignore if origin == APIResponse: raise RuntimeError("Unexpected state - cast_to is `APIResponse`") if inspect.isclass( origin # pyright: ignore[reportUnknownArgumentType] ) and issubclass(origin, httpx.Response): # Because of the invariance of our ResponseT TypeVar, users can subclass httpx.Response # and pass that class to our request functions. We cannot change the variance to be either # covariant or contravariant as that makes our usage of ResponseT illegal. We could construct # the response class ourselves but that is something that should be supported directly in httpx # as it would be easy to incorrectly construct the Response object due to the multitude of arguments. if cast_to != httpx.Response: raise ValueError(f"Subclasses of httpx.Response cannot be passed to `cast_to`") return cast(R, response) if ( inspect.isclass( origin # pyright: ignore[reportUnknownArgumentType] ) and not issubclass(origin, BaseModel) and issubclass(origin, pydantic.BaseModel) ): raise TypeError("Pydantic models must subclass our base model type, e.g. `from anthropic import BaseModel`") if ( cast_to is not object and not origin is list and not origin is dict and not origin is Union and not issubclass(origin, BaseModel) ): raise RuntimeError( f"Unsupported type, expected {cast_to} to be a subclass of {BaseModel}, {dict}, {list}, {Union}, {NoneType}, {str} or {httpx.Response}." ) # split is required to handle cases where additional information is included # in the response, e.g. application/json; charset=utf-8 content_type, *_ = response.headers.get("content-type", "*").split(";") if not content_type.endswith("json"): if is_basemodel(cast_to): try: data = response.json() except Exception as exc: log.debug("Could not read JSON from response data due to %s - %s", type(exc), exc) else: return self._client._process_response_data( data=data, cast_to=cast_to, # type: ignore response=response, ) if self._client._strict_response_validation: raise APIResponseValidationError( response=response, message=f"Expected Content-Type response header to be `application/json` but received `{content_type}` instead.", body=response.text, ) # If the API responds with content that isn't JSON then we just return # the (decoded) text without performing any parsing so that you can still # handle the response however you need to. return response.text # type: ignore data = response.json() return self._client._process_response_data( data=data, cast_to=cast_to, # type: ignore response=response, ) class APIResponse(BaseAPIResponse[R]): @property def request_id(self) -> str | None: return self.http_response.headers.get("request-id") # type: ignore[no-any-return] @overload def parse(self, *, to: type[_T]) -> _T: ... @overload def parse(self) -> R: ... def parse(self, *, to: type[_T] | None = None) -> R | _T: """Returns the rich python representation of this response's data. For lower-level control, see `.read()`, `.json()`, `.iter_bytes()`. You can customise the type that the response is parsed into through the `to` argument, e.g. ```py from anthropic import BaseModel class MyModel(BaseModel): foo: str obj = response.parse(to=MyModel) print(obj.foo) ``` We support parsing: - `BaseModel` - `dict` - `list` - `Union` - `str` - `int` - `float` - `httpx.Response` """ cache_key = to if to is not None else self._cast_to cached = self._parsed_by_type.get(cache_key) if cached is not None: return cached # type: ignore[no-any-return] if not self._is_sse_stream: self.read() parsed = self._parse(to=to) if is_given(self._options.post_parser): parsed = self._options.post_parser(parsed) if isinstance(parsed, BaseModel): add_request_id(parsed, self.request_id) self._parsed_by_type[cache_key] = parsed return cast(R, parsed) def read(self) -> bytes: """Read and return the binary response content.""" try: return self.http_response.read() except httpx.StreamConsumed as exc: # The default error raised by httpx isn't very # helpful in our case so we re-raise it with # a different error message. raise StreamAlreadyConsumed() from exc def text(self) -> str: """Read and decode the response content into a string.""" self.read() return self.http_response.text def json(self) -> object: """Read and decode the JSON response content.""" self.read() return self.http_response.json() def close(self) -> None: """Close the response and release the connection. Automatically called if the response body is read to completion. """ self.http_response.close() def iter_bytes(self, chunk_size: int | None = None) -> Iterator[bytes]: """ A byte-iterator over the decoded response content. This automatically handles gzip, deflate and brotli encoded responses. """ for chunk in self.http_response.iter_bytes(chunk_size): yield chunk def iter_text(self, chunk_size: int | None = None) -> Iterator[str]: """A str-iterator over the decoded response content that handles both gzip, deflate, etc but also detects the content's string encoding. """ for chunk in self.http_response.iter_text(chunk_size): yield chunk def iter_lines(self) -> Iterator[str]: """Like `iter_text()` but will only yield chunks for each line""" for chunk in self.http_response.iter_lines(): yield chunk class AsyncAPIResponse(BaseAPIResponse[R]): @property def request_id(self) -> str | None: return self.http_response.headers.get("request-id") # type: ignore[no-any-return] @overload async def parse(self, *, to: type[_T]) -> _T: ... @overload async def parse(self) -> R: ... async def parse(self, *, to: type[_T] | None = None) -> R | _T: """Returns the rich python representation of this response's data. For lower-level control, see `.read()`, `.json()`, `.iter_bytes()`. You can customise the type that the response is parsed into through the `to` argument, e.g. ```py from anthropic import BaseModel class MyModel(BaseModel): foo: str obj = response.parse(to=MyModel) print(obj.foo) ``` We support parsing: - `BaseModel` - `dict` - `list` - `Union` - `str` - `httpx.Response` """ cache_key = to if to is not None else self._cast_to cached = self._parsed_by_type.get(cache_key) if cached is not None: return cached # type: ignore[no-any-return] if not self._is_sse_stream: await self.read() parsed = self._parse(to=to) if is_given(self._options.post_parser): parsed = self._options.post_parser(parsed) if isinstance(parsed, BaseModel): add_request_id(parsed, self.request_id) self._parsed_by_type[cache_key] = parsed return cast(R, parsed) async def read(self) -> bytes: """Read and return the binary response content.""" try: return await self.http_response.aread() except httpx.StreamConsumed as exc: # the default error raised by httpx isn't very # helpful in our case so we re-raise it with # a different error message raise StreamAlreadyConsumed() from exc async def text(self) -> str: """Read and decode the response content into a string.""" await self.read() return self.http_response.text async def json(self) -> object: """Read and decode the JSON response content.""" await self.read() return self.http_response.json() async def close(self) -> None: """Close the response and release the connection. Automatically called if the response body is read to completion. """ await self.http_response.aclose() async def iter_bytes(self, chunk_size: int | None = None) -> AsyncIterator[bytes]: """ A byte-iterator over the decoded response content. This automatically handles gzip, deflate and brotli encoded responses. """ async for chunk in self.http_response.aiter_bytes(chunk_size): yield chunk async def iter_text(self, chunk_size: int | None = None) -> AsyncIterator[str]: """A str-iterator over the decoded response content that handles both gzip, deflate, etc but also detects the content's string encoding. """ async for chunk in self.http_response.aiter_text(chunk_size): yield chunk async def iter_lines(self) -> AsyncIterator[str]: """Like `iter_text()` but will only yield chunks for each line""" async for chunk in self.http_response.aiter_lines(): yield chunk class BinaryAPIResponse(APIResponse[bytes]): """Subclass of APIResponse providing helpers for dealing with binary data. Note: If you want to stream the response data instead of eagerly reading it all at once then you should use `.with_streaming_response` when making the API request, e.g. `.with_streaming_response.get_binary_response()` """ def write_to_file( self, file: str | os.PathLike[str], ) -> None: """Write the output to the given file. Accepts a filename or any path-like object, e.g. pathlib.Path Note: if you want to stream the data to the file instead of writing all at once then you should use `.with_streaming_response` when making the API request, e.g. `.with_streaming_response.get_binary_response()` """ with open(file, mode="wb") as f: for data in self.iter_bytes(): f.write(data) class AsyncBinaryAPIResponse(AsyncAPIResponse[bytes]): """Subclass of APIResponse providing helpers for dealing with binary data. Note: If you want to stream the response data instead of eagerly reading it all at once then you should use `.with_streaming_response` when making the API request, e.g. `.with_streaming_response.get_binary_response()` """ async def write_to_file( self, file: str | os.PathLike[str], ) -> None: """Write the output to the given file. Accepts a filename or any path-like object, e.g. pathlib.Path Note: if you want to stream the data to the file instead of writing all at once then you should use `.with_streaming_response` when making the API request, e.g. `.with_streaming_response.get_binary_response()` """ path = anyio.Path(file) async with await path.open(mode="wb") as f: async for data in self.iter_bytes(): await f.write(data) class StreamedBinaryAPIResponse(APIResponse[bytes]): def stream_to_file( self, file: str | os.PathLike[str], *, chunk_size: int | None = None, ) -> None: """Streams the output to the given file. Accepts a filename or any path-like object, e.g. pathlib.Path """ with open(file, mode="wb") as f: for data in self.iter_bytes(chunk_size): f.write(data) class AsyncStreamedBinaryAPIResponse(AsyncAPIResponse[bytes]): async def stream_to_file( self, file: str | os.PathLike[str], *, chunk_size: int | None = None, ) -> None: """Streams the output to the given file. Accepts a filename or any path-like object, e.g. pathlib.Path """ path = anyio.Path(file) async with await path.open(mode="wb") as f: async for data in self.iter_bytes(chunk_size): await f.write(data) class MissingStreamClassError(TypeError): def __init__(self) -> None: super().__init__( "The `stream` argument was set to `True` but the `stream_cls` argument was not given. See `anthropic._streaming` for reference", ) class StreamAlreadyConsumed(AnthropicError): """ Attempted to read or stream content, but the content has already been streamed. This can happen if you use a method like `.iter_lines()` and then attempt to read th entire response body afterwards, e.g. ```py response = await client.post(...) async for line in response.iter_lines(): ... # do something with `line` content = await response.read() # ^ error ``` If you want this behaviour you'll need to either manually accumulate the response content or call `await response.read()` before iterating over the stream. """ def __init__(self) -> None: message = ( "Attempted to read or stream some content, but the content has " "already been streamed. " "This could be due to attempting to stream the response " "content more than once." "\n\n" "You can fix this by manually accumulating the response content while streaming " "or by calling `.read()` before starting to stream." ) super().__init__(message) class ResponseContextManager(Generic[_APIResponseT]): """Context manager for ensuring that a request is not made until it is entered and that the response will always be closed when the context manager exits """ def __init__(self, request_func: Callable[[], _APIResponseT]) -> None: self._request_func = request_func self.__response: _APIResponseT | None = None def __enter__(self) -> _APIResponseT: self.__response = self._request_func() return self.__response def __exit__( self, exc_type: type[BaseException] | None, exc: BaseException | None, exc_tb: TracebackType | None, ) -> None: if self.__response is not None: self.__response.close() class AsyncResponseContextManager(Generic[_AsyncAPIResponseT]): """Context manager for ensuring that a request is not made until it is entered and that the response will always be closed when the context manager exits """ def __init__(self, api_request: Awaitable[_AsyncAPIResponseT]) -> None: self._api_request = api_request self.__response: _AsyncAPIResponseT | None = None async def __aenter__(self) -> _AsyncAPIResponseT: self.__response = await self._api_request return self.__response async def __aexit__( self, exc_type: type[BaseException] | None, exc: BaseException | None, exc_tb: TracebackType | None, ) -> None: if self.__response is not None: await self.__response.close() def to_streamed_response_wrapper(func: Callable[P, R]) -> Callable[P, ResponseContextManager[APIResponse[R]]]: """Higher order function that takes one of our bound API methods and wraps it to support streaming and returning the raw `APIResponse` object directly. """ @functools.wraps(func) def wrapped(*args: P.args, **kwargs: P.kwargs) -> ResponseContextManager[APIResponse[R]]: extra_headers: dict[str, str] = {**(cast(Any, kwargs.get("extra_headers")) or {})} extra_headers[RAW_RESPONSE_HEADER] = "stream" kwargs["extra_headers"] = extra_headers make_request = functools.partial(func, *args, **kwargs) return ResponseContextManager(cast(Callable[[], APIResponse[R]], make_request)) return wrapped def async_to_streamed_response_wrapper( func: Callable[P, Awaitable[R]], ) -> Callable[P, AsyncResponseContextManager[AsyncAPIResponse[R]]]: """Higher order function that takes one of our bound API methods and wraps it to support streaming and returning the raw `APIResponse` object directly. """ @functools.wraps(func) def wrapped(*args: P.args, **kwargs: P.kwargs) -> AsyncResponseContextManager[AsyncAPIResponse[R]]: extra_headers: dict[str, str] = {**(cast(Any, kwargs.get("extra_headers")) or {})} extra_headers[RAW_RESPONSE_HEADER] = "stream" kwargs["extra_headers"] = extra_headers make_request = func(*args, **kwargs) return AsyncResponseContextManager(cast(Awaitable[AsyncAPIResponse[R]], make_request)) return wrapped def to_custom_streamed_response_wrapper( func: Callable[P, object], response_cls: type[_APIResponseT], ) -> Callable[P, ResponseContextManager[_APIResponseT]]: """Higher order function that takes one of our bound API methods and an `APIResponse` class and wraps the method to support streaming and returning the given response class directly. Note: the given `response_cls` *must* be concrete, e.g. `class BinaryAPIResponse(APIResponse[bytes])` """ @functools.wraps(func) def wrapped(*args: P.args, **kwargs: P.kwargs) -> ResponseContextManager[_APIResponseT]: extra_headers: dict[str, Any] = {**(cast(Any, kwargs.get("extra_headers")) or {})} extra_headers[RAW_RESPONSE_HEADER] = "stream" extra_headers[OVERRIDE_CAST_TO_HEADER] = response_cls kwargs["extra_headers"] = extra_headers make_request = functools.partial(func, *args, **kwargs) return ResponseContextManager(cast(Callable[[], _APIResponseT], make_request)) return wrapped def async_to_custom_streamed_response_wrapper( func: Callable[P, Awaitable[object]], response_cls: type[_AsyncAPIResponseT], ) -> Callable[P, AsyncResponseContextManager[_AsyncAPIResponseT]]: """Higher order function that takes one of our bound API methods and an `APIResponse` class and wraps the method to support streaming and returning the given response class directly. Note: the given `response_cls` *must* be concrete, e.g. `class BinaryAPIResponse(APIResponse[bytes])` """ @functools.wraps(func) def wrapped(*args: P.args, **kwargs: P.kwargs) -> AsyncResponseContextManager[_AsyncAPIResponseT]: extra_headers: dict[str, Any] = {**(cast(Any, kwargs.get("extra_headers")) or {})} extra_headers[RAW_RESPONSE_HEADER] = "stream" extra_headers[OVERRIDE_CAST_TO_HEADER] = response_cls kwargs["extra_headers"] = extra_headers make_request = func(*args, **kwargs) return AsyncResponseContextManager(cast(Awaitable[_AsyncAPIResponseT], make_request)) return wrapped def to_raw_response_wrapper(func: Callable[P, R]) -> Callable[P, APIResponse[R]]: """Higher order function that takes one of our bound API methods and wraps it to support returning the raw `APIResponse` object directly. """ @functools.wraps(func) def wrapped(*args: P.args, **kwargs: P.kwargs) -> APIResponse[R]: extra_headers: dict[str, str] = {**(cast(Any, kwargs.get("extra_headers")) or {})} extra_headers[RAW_RESPONSE_HEADER] = "raw" kwargs["extra_headers"] = extra_headers return cast(APIResponse[R], func(*args, **kwargs)) return wrapped def async_to_raw_response_wrapper(func: Callable[P, Awaitable[R]]) -> Callable[P, Awaitable[AsyncAPIResponse[R]]]: """Higher order function that takes one of our bound API methods and wraps it to support returning the raw `APIResponse` object directly. """ @functools.wraps(func) async def wrapped(*args: P.args, **kwargs: P.kwargs) -> AsyncAPIResponse[R]: extra_headers: dict[str, str] = {**(cast(Any, kwargs.get("extra_headers")) or {})} extra_headers[RAW_RESPONSE_HEADER] = "raw" kwargs["extra_headers"] = extra_headers return cast(AsyncAPIResponse[R], await func(*args, **kwargs)) return wrapped def to_custom_raw_response_wrapper( func: Callable[P, object], response_cls: type[_APIResponseT], ) -> Callable[P, _APIResponseT]: """Higher order function that takes one of our bound API methods and an `APIResponse` class and wraps the method to support returning the given response class directly. Note: the given `response_cls` *must* be concrete, e.g. `class BinaryAPIResponse(APIResponse[bytes])` """ @functools.wraps(func) def wrapped(*args: P.args, **kwargs: P.kwargs) -> _APIResponseT: extra_headers: dict[str, Any] = {**(cast(Any, kwargs.get("extra_headers")) or {})} extra_headers[RAW_RESPONSE_HEADER] = "raw" extra_headers[OVERRIDE_CAST_TO_HEADER] = response_cls kwargs["extra_headers"] = extra_headers return cast(_APIResponseT, func(*args, **kwargs)) return wrapped def async_to_custom_raw_response_wrapper( func: Callable[P, Awaitable[object]], response_cls: type[_AsyncAPIResponseT], ) -> Callable[P, Awaitable[_AsyncAPIResponseT]]: """Higher order function that takes one of our bound API methods and an `APIResponse` class and wraps the method to support returning the given response class directly. Note: the given `response_cls` *must* be concrete, e.g. `class BinaryAPIResponse(APIResponse[bytes])` """ @functools.wraps(func) def wrapped(*args: P.args, **kwargs: P.kwargs) -> Awaitable[_AsyncAPIResponseT]: extra_headers: dict[str, Any] = {**(cast(Any, kwargs.get("extra_headers")) or {})} extra_headers[RAW_RESPONSE_HEADER] = "raw" extra_headers[OVERRIDE_CAST_TO_HEADER] = response_cls kwargs["extra_headers"] = extra_headers return cast(Awaitable[_AsyncAPIResponseT], func(*args, **kwargs)) return wrapped def extract_response_type(typ: type[BaseAPIResponse[Any]]) -> type: """Given a type like `APIResponse[T]`, returns the generic type variable `T`. This also handles the case where a concrete subclass is given, e.g. ```py class MyResponse(APIResponse[bytes]): ... extract_response_type(MyResponse) -> bytes ``` """ return extract_type_var_from_base( typ, generic_bases=cast("tuple[type, ...]", (BaseAPIResponse, APIResponse, AsyncAPIResponse)), index=0, ) anthropic-sdk-python-0.69.0/src/anthropic/_streaming.py000066400000000000000000000333071506653454500231760ustar00rootroot00000000000000# Note: initially copied from https://github.com/florimondmanca/httpx-sse/blob/master/src/httpx_sse/_decoders.py from __future__ import annotations import abc import json import inspect import warnings from types import TracebackType from typing import TYPE_CHECKING, Any, Generic, TypeVar, Iterator, AsyncIterator, cast from typing_extensions import Self, Protocol, TypeGuard, override, get_origin, runtime_checkable import httpx from ._utils import is_dict, extract_type_var_from_base if TYPE_CHECKING: from ._client import Anthropic, AsyncAnthropic _T = TypeVar("_T") class _SyncStreamMeta(abc.ABCMeta): @override def __instancecheck__(self, instance: Any) -> bool: # we override the `isinstance()` check for `Stream` # as a previous version of the `MessageStream` class # inherited from `Stream` & without this workaround, # changing it to not inherit would be a breaking change. from .lib.streaming import MessageStream if isinstance(instance, MessageStream): warnings.warn( "Using `isinstance()` to check if a `MessageStream` object is an instance of `Stream` is deprecated & will be removed in the next major version", DeprecationWarning, stacklevel=2, ) return True return False class Stream(Generic[_T], metaclass=_SyncStreamMeta): """Provides the core interface to iterate over a synchronous stream response.""" response: httpx.Response _decoder: SSEBytesDecoder def __init__( self, *, cast_to: type[_T], response: httpx.Response, client: Anthropic, ) -> None: self.response = response self._cast_to = cast_to self._client = client self._decoder = client._make_sse_decoder() self._iterator = self.__stream__() def __next__(self) -> _T: return self._iterator.__next__() def __iter__(self) -> Iterator[_T]: for item in self._iterator: yield item def _iter_events(self) -> Iterator[ServerSentEvent]: yield from self._decoder.iter_bytes(self.response.iter_bytes()) def __stream__(self) -> Iterator[_T]: cast_to = cast(Any, self._cast_to) response = self.response process_data = self._client._process_response_data iterator = self._iter_events() for sse in iterator: if sse.event == "completion": yield process_data(data=sse.json(), cast_to=cast_to, response=response) if ( sse.event == "message_start" or sse.event == "message_delta" or sse.event == "message_stop" or sse.event == "content_block_start" or sse.event == "content_block_delta" or sse.event == "content_block_stop" ): data = sse.json() if is_dict(data) and "type" not in data: data["type"] = sse.event yield process_data(data=data, cast_to=cast_to, response=response) if sse.event == "ping": continue if sse.event == "error": body = sse.data try: body = sse.json() err_msg = f"{body}" except Exception: err_msg = sse.data or f"Error code: {response.status_code}" raise self._client._make_status_error( err_msg, body=body, response=self.response, ) # Ensure the entire stream is consumed for _sse in iterator: ... def __enter__(self) -> Self: return self def __exit__( self, exc_type: type[BaseException] | None, exc: BaseException | None, exc_tb: TracebackType | None, ) -> None: self.close() def close(self) -> None: """ Close the response and release the connection. Automatically called if the response body is read to completion. """ self.response.close() class _AsyncStreamMeta(abc.ABCMeta): @override def __instancecheck__(self, instance: Any) -> bool: # we override the `isinstance()` check for `AsyncStream` # as a previous version of the `AsyncMessageStream` class # inherited from `AsyncStream` & without this workaround, # changing it to not inherit would be a breaking change. from .lib.streaming import AsyncMessageStream if isinstance(instance, AsyncMessageStream): warnings.warn( "Using `isinstance()` to check if a `AsyncMessageStream` object is an instance of `AsyncStream` is deprecated & will be removed in the next major version", DeprecationWarning, stacklevel=2, ) return True return False class AsyncStream(Generic[_T], metaclass=_AsyncStreamMeta): """Provides the core interface to iterate over an asynchronous stream response.""" response: httpx.Response _decoder: SSEDecoder | SSEBytesDecoder def __init__( self, *, cast_to: type[_T], response: httpx.Response, client: AsyncAnthropic, ) -> None: self.response = response self._cast_to = cast_to self._client = client self._decoder = client._make_sse_decoder() self._iterator = self.__stream__() async def __anext__(self) -> _T: return await self._iterator.__anext__() async def __aiter__(self) -> AsyncIterator[_T]: async for item in self._iterator: yield item async def _iter_events(self) -> AsyncIterator[ServerSentEvent]: async for sse in self._decoder.aiter_bytes(self.response.aiter_bytes()): yield sse async def __stream__(self) -> AsyncIterator[_T]: cast_to = cast(Any, self._cast_to) response = self.response process_data = self._client._process_response_data iterator = self._iter_events() async for sse in iterator: if sse.event == "completion": yield process_data(data=sse.json(), cast_to=cast_to, response=response) if ( sse.event == "message_start" or sse.event == "message_delta" or sse.event == "message_stop" or sse.event == "content_block_start" or sse.event == "content_block_delta" or sse.event == "content_block_stop" ): data = sse.json() if is_dict(data) and "type" not in data: data["type"] = sse.event yield process_data(data=data, cast_to=cast_to, response=response) if sse.event == "ping": continue if sse.event == "error": body = sse.data try: body = sse.json() err_msg = f"{body}" except Exception: err_msg = sse.data or f"Error code: {response.status_code}" raise self._client._make_status_error( err_msg, body=body, response=self.response, ) # Ensure the entire stream is consumed async for _sse in iterator: ... async def __aenter__(self) -> Self: return self async def __aexit__( self, exc_type: type[BaseException] | None, exc: BaseException | None, exc_tb: TracebackType | None, ) -> None: await self.close() async def close(self) -> None: """ Close the response and release the connection. Automatically called if the response body is read to completion. """ await self.response.aclose() class ServerSentEvent: def __init__( self, *, event: str | None = None, data: str | None = None, id: str | None = None, retry: int | None = None, ) -> None: if data is None: data = "" self._id = id self._data = data self._event = event or None self._retry = retry @property def event(self) -> str | None: return self._event @property def id(self) -> str | None: return self._id @property def retry(self) -> int | None: return self._retry @property def data(self) -> str: return self._data def json(self) -> Any: return json.loads(self.data) @override def __repr__(self) -> str: return f"ServerSentEvent(event={self.event}, data={self.data}, id={self.id}, retry={self.retry})" class SSEDecoder: _data: list[str] _event: str | None _retry: int | None _last_event_id: str | None def __init__(self) -> None: self._event = None self._data = [] self._last_event_id = None self._retry = None def iter_bytes(self, iterator: Iterator[bytes]) -> Iterator[ServerSentEvent]: """Given an iterator that yields raw binary data, iterate over it & yield every event encountered""" for chunk in self._iter_chunks(iterator): # Split before decoding so splitlines() only uses \r and \n for raw_line in chunk.splitlines(): line = raw_line.decode("utf-8") sse = self.decode(line) if sse: yield sse def _iter_chunks(self, iterator: Iterator[bytes]) -> Iterator[bytes]: """Given an iterator that yields raw binary data, iterate over it and yield individual SSE chunks""" data = b"" for chunk in iterator: for line in chunk.splitlines(keepends=True): data += line if data.endswith((b"\r\r", b"\n\n", b"\r\n\r\n")): yield data data = b"" if data: yield data async def aiter_bytes(self, iterator: AsyncIterator[bytes]) -> AsyncIterator[ServerSentEvent]: """Given an iterator that yields raw binary data, iterate over it & yield every event encountered""" async for chunk in self._aiter_chunks(iterator): # Split before decoding so splitlines() only uses \r and \n for raw_line in chunk.splitlines(): line = raw_line.decode("utf-8") sse = self.decode(line) if sse: yield sse async def _aiter_chunks(self, iterator: AsyncIterator[bytes]) -> AsyncIterator[bytes]: """Given an iterator that yields raw binary data, iterate over it and yield individual SSE chunks""" data = b"" async for chunk in iterator: for line in chunk.splitlines(keepends=True): data += line if data.endswith((b"\r\r", b"\n\n", b"\r\n\r\n")): yield data data = b"" if data: yield data def decode(self, line: str) -> ServerSentEvent | None: # See: https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation # noqa: E501 if not line: if not self._event and not self._data and not self._last_event_id and self._retry is None: return None sse = ServerSentEvent( event=self._event, data="\n".join(self._data), id=self._last_event_id, retry=self._retry, ) # NOTE: as per the SSE spec, do not reset last_event_id. self._event = None self._data = [] self._retry = None return sse if line.startswith(":"): return None fieldname, _, value = line.partition(":") if value.startswith(" "): value = value[1:] if fieldname == "event": self._event = value elif fieldname == "data": self._data.append(value) elif fieldname == "id": if "\0" in value: pass else: self._last_event_id = value elif fieldname == "retry": try: self._retry = int(value) except (TypeError, ValueError): pass else: pass # Field is ignored. return None @runtime_checkable class SSEBytesDecoder(Protocol): def iter_bytes(self, iterator: Iterator[bytes]) -> Iterator[ServerSentEvent]: """Given an iterator that yields raw binary data, iterate over it & yield every event encountered""" ... def aiter_bytes(self, iterator: AsyncIterator[bytes]) -> AsyncIterator[ServerSentEvent]: """Given an async iterator that yields raw binary data, iterate over it & yield every event encountered""" ... def is_stream_class_type(typ: type) -> TypeGuard[type[Stream[object]] | type[AsyncStream[object]]]: """TypeGuard for determining whether or not the given type is a subclass of `Stream` / `AsyncStream`""" origin = get_origin(typ) or typ return inspect.isclass(origin) and issubclass(origin, (Stream, AsyncStream)) def extract_stream_chunk_type( stream_cls: type, *, failure_message: str | None = None, ) -> type: """Given a type like `Stream[T]`, returns the generic type variable `T`. This also handles the case where a concrete subclass is given, e.g. ```py class MyStream(Stream[bytes]): ... extract_stream_chunk_type(MyStream) -> bytes ``` """ from ._base_client import Stream, AsyncStream return extract_type_var_from_base( stream_cls, index=0, generic_bases=cast("tuple[type, ...]", (Stream, AsyncStream)), failure_message=failure_message, ) anthropic-sdk-python-0.69.0/src/anthropic/_types.py000066400000000000000000000162521506653454500223510ustar00rootroot00000000000000from __future__ import annotations from os import PathLike from typing import ( IO, TYPE_CHECKING, Any, Dict, List, Type, Tuple, Union, Mapping, TypeVar, Callable, Iterator, Optional, Sequence, ) from typing_extensions import ( Set, Literal, Protocol, TypeAlias, TypedDict, SupportsIndex, overload, override, runtime_checkable, ) import httpx import pydantic from httpx import URL, Proxy, Timeout, Response, BaseTransport, AsyncBaseTransport if TYPE_CHECKING: from ._models import BaseModel from ._response import APIResponse, AsyncAPIResponse from ._legacy_response import HttpxBinaryResponseContent Transport = BaseTransport AsyncTransport = AsyncBaseTransport Query = Mapping[str, object] Body = object AnyMapping = Mapping[str, object] ModelT = TypeVar("ModelT", bound=pydantic.BaseModel) _T = TypeVar("_T") # Approximates httpx internal ProxiesTypes and RequestFiles types # while adding support for `PathLike` instances ProxiesDict = Dict["str | URL", Union[None, str, URL, Proxy]] ProxiesTypes = Union[str, Proxy, ProxiesDict] if TYPE_CHECKING: Base64FileInput = Union[IO[bytes], PathLike[str]] FileContent = Union[IO[bytes], bytes, PathLike[str]] else: Base64FileInput = Union[IO[bytes], PathLike] FileContent = Union[IO[bytes], bytes, PathLike] # PathLike is not subscriptable in Python 3.8. FileTypes = Union[ # file (or bytes) FileContent, # (filename, file (or bytes)) Tuple[Optional[str], FileContent], # (filename, file (or bytes), content_type) Tuple[Optional[str], FileContent, Optional[str]], # (filename, file (or bytes), content_type, headers) Tuple[Optional[str], FileContent, Optional[str], Mapping[str, str]], ] RequestFiles = Union[Mapping[str, FileTypes], Sequence[Tuple[str, FileTypes]]] # duplicate of the above but without our custom file support HttpxFileContent = Union[IO[bytes], bytes] HttpxFileTypes = Union[ # file (or bytes) HttpxFileContent, # (filename, file (or bytes)) Tuple[Optional[str], HttpxFileContent], # (filename, file (or bytes), content_type) Tuple[Optional[str], HttpxFileContent, Optional[str]], # (filename, file (or bytes), content_type, headers) Tuple[Optional[str], HttpxFileContent, Optional[str], Mapping[str, str]], ] HttpxRequestFiles = Union[Mapping[str, HttpxFileTypes], Sequence[Tuple[str, HttpxFileTypes]]] # Workaround to support (cast_to: Type[ResponseT]) -> ResponseT # where ResponseT includes `None`. In order to support directly # passing `None`, overloads would have to be defined for every # method that uses `ResponseT` which would lead to an unacceptable # amount of code duplication and make it unreadable. See _base_client.py # for example usage. # # This unfortunately means that you will either have # to import this type and pass it explicitly: # # from anthropic import NoneType # client.get('/foo', cast_to=NoneType) # # or build it yourself: # # client.get('/foo', cast_to=type(None)) if TYPE_CHECKING: NoneType: Type[None] else: NoneType = type(None) class RequestOptions(TypedDict, total=False): headers: Headers max_retries: int timeout: float | Timeout | None params: Query extra_json: AnyMapping idempotency_key: str follow_redirects: bool # Sentinel class used until PEP 0661 is accepted class NotGiven: """ For parameters with a meaningful None value, we need to distinguish between the user explicitly passing None, and the user not passing the parameter at all. User code shouldn't need to use not_given directly. For example: ```py def create(timeout: Timeout | None | NotGiven = not_given): ... create(timeout=1) # 1s timeout create(timeout=None) # No timeout create() # Default timeout behavior ``` """ def __bool__(self) -> Literal[False]: return False @override def __repr__(self) -> str: return "NOT_GIVEN" not_given = NotGiven() # for backwards compatibility: NOT_GIVEN = NotGiven() class Omit: """ To explicitly omit something from being sent in a request, use `omit`. ```py # as the default `Content-Type` header is `application/json` that will be sent client.post("/upload/files", files={"file": b"my raw file content"}) # you can't explicitly override the header as it has to be dynamically generated # to look something like: 'multipart/form-data; boundary=0d8382fcf5f8c3be01ca2e11002d2983' client.post(..., headers={"Content-Type": "multipart/form-data"}) # instead you can remove the default `application/json` header by passing omit client.post(..., headers={"Content-Type": omit}) ``` """ def __bool__(self) -> Literal[False]: return False omit = Omit() @runtime_checkable class ModelBuilderProtocol(Protocol): @classmethod def build( cls: type[_T], *, response: Response, data: object, ) -> _T: ... Headers = Mapping[str, Union[str, Omit]] class HeadersLikeProtocol(Protocol): def get(self, __key: str) -> str | None: ... HeadersLike = Union[Headers, HeadersLikeProtocol] ResponseT = TypeVar( "ResponseT", bound=Union[ object, str, None, "BaseModel", List[Any], Dict[str, Any], Response, ModelBuilderProtocol, "APIResponse[Any]", "AsyncAPIResponse[Any]", "HttpxBinaryResponseContent", ], ) StrBytesIntFloat = Union[str, bytes, int, float] # Note: copied from Pydantic # https://github.com/pydantic/pydantic/blob/6f31f8f68ef011f84357330186f603ff295312fd/pydantic/main.py#L79 IncEx: TypeAlias = Union[Set[int], Set[str], Mapping[int, Union["IncEx", bool]], Mapping[str, Union["IncEx", bool]]] PostParser = Callable[[Any], Any] @runtime_checkable class InheritsGeneric(Protocol): """Represents a type that has inherited from `Generic` The `__orig_bases__` property can be used to determine the resolved type variable for a given base class. """ __orig_bases__: tuple[_GenericAlias] class _GenericAlias(Protocol): __origin__: type[object] class HttpxSendArgs(TypedDict, total=False): auth: httpx.Auth follow_redirects: bool _T_co = TypeVar("_T_co", covariant=True) 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 class SequenceNotStr(Protocol[_T_co]): @overload def __getitem__(self, index: SupportsIndex, /) -> _T_co: ... @overload 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 # deserializing our custom sequence type SequenceNotStr = Sequence anthropic-sdk-python-0.69.0/src/anthropic/_utils/000077500000000000000000000000001506653454500217655ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/_utils/__init__.py000066400000000000000000000044011506653454500240750ustar00rootroot00000000000000from ._sync import asyncify as asyncify from ._proxy import LazyProxy as LazyProxy from ._utils import ( flatten as flatten, is_dict as is_dict, is_list as is_list, is_given as is_given, is_tuple as is_tuple, json_safe as json_safe, lru_cache as lru_cache, is_mapping as is_mapping, is_tuple_t as is_tuple_t, is_iterable as is_iterable, is_sequence as is_sequence, coerce_float as coerce_float, is_mapping_t as is_mapping_t, removeprefix as removeprefix, removesuffix as removesuffix, extract_files as extract_files, is_sequence_t as is_sequence_t, required_args as required_args, coerce_boolean as coerce_boolean, 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, maybe_coerce_boolean as maybe_coerce_boolean, maybe_coerce_integer as maybe_coerce_integer, ) from ._compat import ( get_args as get_args, is_union as is_union, get_origin as get_origin, is_typeddict as is_typeddict, is_literal_type as is_literal_type, ) from ._typing import ( is_list_type as is_list_type, is_union_type as is_union_type, extract_type_arg as extract_type_arg, is_iterable_type as is_iterable_type, is_required_type as is_required_type, is_sequence_type as is_sequence_type, is_annotated_type as is_annotated_type, is_type_alias_type as is_type_alias_type, strip_annotated_type as strip_annotated_type, extract_type_var_from_base as extract_type_var_from_base, ) from ._streams import consume_sync_iterator as consume_sync_iterator, consume_async_iterator as consume_async_iterator from ._transform import ( PropertyInfo as PropertyInfo, transform as transform, async_transform as async_transform, maybe_transform as maybe_transform, async_maybe_transform as async_maybe_transform, ) from ._reflection import ( function_has_argument as function_has_argument, assert_signatures_in_sync as assert_signatures_in_sync, ) from ._datetime_parse import parse_date as parse_date, parse_datetime as parse_datetime anthropic-sdk-python-0.69.0/src/anthropic/_utils/_compat.py000066400000000000000000000022531506653454500237630ustar00rootroot00000000000000from __future__ import annotations import sys import typing_extensions from typing import Any, Type, Union, Literal, Optional from datetime import date, datetime from typing_extensions import get_args as _get_args, get_origin as _get_origin from .._types import StrBytesIntFloat from ._datetime_parse import parse_date as _parse_date, parse_datetime as _parse_datetime _LITERAL_TYPES = {Literal, typing_extensions.Literal} def get_args(tp: type[Any]) -> tuple[Any, ...]: return _get_args(tp) def get_origin(tp: type[Any]) -> type[Any] | None: return _get_origin(tp) def is_union(tp: Optional[Type[Any]]) -> bool: if sys.version_info < (3, 10): return tp is Union # type: ignore[comparison-overlap] else: import types return tp is Union or tp is types.UnionType def is_typeddict(tp: Type[Any]) -> bool: return typing_extensions.is_typeddict(tp) def is_literal_type(tp: Type[Any]) -> bool: return get_origin(tp) in _LITERAL_TYPES def parse_date(value: Union[date, StrBytesIntFloat]) -> date: return _parse_date(value) def parse_datetime(value: Union[datetime, StrBytesIntFloat]) -> datetime: return _parse_datetime(value) anthropic-sdk-python-0.69.0/src/anthropic/_utils/_datetime_parse.py000066400000000000000000000101541506653454500254650ustar00rootroot00000000000000""" This file contains code from https://github.com/pydantic/pydantic/blob/main/pydantic/v1/datetime_parse.py without the Pydantic v1 specific errors. """ from __future__ import annotations import re from typing import Dict, Union, Optional from datetime import date, datetime, timezone, timedelta from .._types import StrBytesIntFloat date_expr = r"(?P\d{4})-(?P\d{1,2})-(?P\d{1,2})" time_expr = ( r"(?P\d{1,2}):(?P\d{1,2})" r"(?::(?P\d{1,2})(?:\.(?P\d{1,6})\d{0,6})?)?" r"(?PZ|[+-]\d{2}(?::?\d{2})?)?$" ) date_re = re.compile(f"{date_expr}$") datetime_re = re.compile(f"{date_expr}[T ]{time_expr}") EPOCH = datetime(1970, 1, 1) # if greater than this, the number is in ms, if less than or equal it's in seconds # (in seconds this is 11th October 2603, in ms it's 20th August 1970) MS_WATERSHED = int(2e10) # slightly more than datetime.max in ns - (datetime.max - EPOCH).total_seconds() * 1e9 MAX_NUMBER = int(3e20) def _get_numeric(value: StrBytesIntFloat, native_expected_type: str) -> Union[None, int, float]: if isinstance(value, (int, float)): return value try: return float(value) except ValueError: return None except TypeError: raise TypeError(f"invalid type; expected {native_expected_type}, string, bytes, int or float") from None def _from_unix_seconds(seconds: Union[int, float]) -> datetime: if seconds > MAX_NUMBER: return datetime.max elif seconds < -MAX_NUMBER: return datetime.min while abs(seconds) > MS_WATERSHED: seconds /= 1000 dt = EPOCH + timedelta(seconds=seconds) return dt.replace(tzinfo=timezone.utc) def _parse_timezone(value: Optional[str]) -> Union[None, int, timezone]: if value == "Z": return timezone.utc elif value is not None: offset_mins = int(value[-2:]) if len(value) > 3 else 0 offset = 60 * int(value[1:3]) + offset_mins if value[0] == "-": offset = -offset return timezone(timedelta(minutes=offset)) else: return None def parse_datetime(value: Union[datetime, StrBytesIntFloat]) -> datetime: """ Parse a datetime/int/float/string and return a datetime.datetime. This function supports time zone offsets. When the input contains one, the output uses a timezone with a fixed offset from UTC. Raise ValueError if the input is well formatted but not a valid datetime. Raise ValueError if the input isn't well formatted. """ if isinstance(value, datetime): return value number = _get_numeric(value, "datetime") if number is not None: return _from_unix_seconds(number) if isinstance(value, bytes): value = value.decode() assert not isinstance(value, (float, int)) match = datetime_re.match(value) if match is None: raise ValueError("invalid datetime format") kw = match.groupdict() if kw["microsecond"]: kw["microsecond"] = kw["microsecond"].ljust(6, "0") tzinfo = _parse_timezone(kw.pop("tzinfo")) kw_: Dict[str, Union[None, int, timezone]] = {k: int(v) for k, v in kw.items() if v is not None} kw_["tzinfo"] = tzinfo return datetime(**kw_) # type: ignore def parse_date(value: Union[date, StrBytesIntFloat]) -> date: """ Parse a date/int/float/string and return a datetime.date. Raise ValueError if the input is well formatted but not a valid date. Raise ValueError if the input isn't well formatted. """ if isinstance(value, date): if isinstance(value, datetime): return value.date() else: return value number = _get_numeric(value, "date") if number is not None: return _from_unix_seconds(number).date() if isinstance(value, bytes): value = value.decode() assert not isinstance(value, (float, int)) match = date_re.match(value) if match is None: raise ValueError("invalid date format") kw = {k: int(v) for k, v in match.groupdict().items()} try: return date(**kw) except ValueError: raise ValueError("invalid date format") from None anthropic-sdk-python-0.69.0/src/anthropic/_utils/_httpx.py000066400000000000000000000040561506653454500236520ustar00rootroot00000000000000""" This file includes code adapted from HTTPX's utility module (https://github.com/encode/httpx/blob/336204f0121a9aefdebac5cacd81f912bafe8057/httpx/_utils.py). We implement custom proxy handling to support configurations like `socket_options`, which are not currently configurable through the HTTPX client. For more context, see: https://github.com/encode/httpx/discussions/3514 """ from __future__ import annotations import ipaddress from typing import Mapping from urllib.request import getproxies def is_ipv4_hostname(hostname: str) -> bool: try: ipaddress.IPv4Address(hostname.split("/")[0]) except Exception: return False return True def is_ipv6_hostname(hostname: str) -> bool: try: ipaddress.IPv6Address(hostname.split("/")[0]) except Exception: return False return True def get_environment_proxies() -> Mapping[str, str | None]: """ Gets the proxy mappings based on environment variables. We use our own logic to parse these variables, as HTTPX doesn’t allow full configuration of the underlying transport when proxies are set via environment variables. """ proxy_info = getproxies() mounts: dict[str, str | None] = {} for scheme in ("http", "https", "all"): if proxy_info.get(scheme): hostname = proxy_info[scheme] mounts[f"{scheme}://"] = hostname if "://" in hostname else f"http://{hostname}" no_proxy_hosts = [host.strip() for host in proxy_info.get("no", "").split(",")] for hostname in no_proxy_hosts: if hostname == "*": return {} elif hostname: if "://" in hostname: mounts[hostname] = None elif is_ipv4_hostname(hostname): mounts[f"all://{hostname}"] = None elif is_ipv6_hostname(hostname): mounts[f"all://[{hostname}]"] = None elif hostname.lower() == "localhost": mounts[f"all://{hostname}"] = None else: mounts[f"all://*{hostname}"] = None return mounts anthropic-sdk-python-0.69.0/src/anthropic/_utils/_logs.py000066400000000000000000000014171506653454500234450ustar00rootroot00000000000000import os import logging logger: logging.Logger = logging.getLogger("anthropic") httpx_logger: logging.Logger = logging.getLogger("httpx") def _basic_config() -> None: # e.g. [2023-10-05 14:12:26 - anthropic._base_client:818 - DEBUG] HTTP Request: POST http://127.0.0.1:4010/foo/bar "200 OK" logging.basicConfig( format="[%(asctime)s - %(name)s:%(lineno)d - %(levelname)s] %(message)s", datefmt="%Y-%m-%d %H:%M:%S", ) def setup_logging() -> None: env = os.environ.get("ANTHROPIC_LOG") if env == "debug": _basic_config() logger.setLevel(logging.DEBUG) httpx_logger.setLevel(logging.DEBUG) elif env == "info": _basic_config() logger.setLevel(logging.INFO) httpx_logger.setLevel(logging.INFO) anthropic-sdk-python-0.69.0/src/anthropic/_utils/_proxy.py000066400000000000000000000036671506653454500236730ustar00rootroot00000000000000from __future__ import annotations from abc import ABC, abstractmethod from typing import Generic, TypeVar, Iterable, cast from typing_extensions import override T = TypeVar("T") class LazyProxy(Generic[T], ABC): """Implements data methods to pretend that an instance is another instance. This includes forwarding attribute access and other methods. """ # Note: we have to special case proxies that themselves return proxies # to support using a proxy as a catch-all for any random access, e.g. `proxy.foo.bar.baz` def __getattr__(self, attr: str) -> object: proxied = self.__get_proxied__() if isinstance(proxied, LazyProxy): return proxied # pyright: ignore return getattr(proxied, attr) @override def __repr__(self) -> str: proxied = self.__get_proxied__() if isinstance(proxied, LazyProxy): return proxied.__class__.__name__ return repr(self.__get_proxied__()) @override def __str__(self) -> str: proxied = self.__get_proxied__() if isinstance(proxied, LazyProxy): return proxied.__class__.__name__ return str(proxied) @override def __dir__(self) -> Iterable[str]: proxied = self.__get_proxied__() if isinstance(proxied, LazyProxy): return [] return proxied.__dir__() @property # type: ignore @override def __class__(self) -> type: # pyright: ignore try: proxied = self.__get_proxied__() except Exception: return type(self) if issubclass(type(proxied), LazyProxy): return type(proxied) return proxied.__class__ def __get_proxied__(self) -> T: return self.__load__() def __as_proxied__(self) -> T: """Helper method that returns the current proxy, typed as the loaded object""" return cast(T, self) @abstractmethod def __load__(self) -> T: ... anthropic-sdk-python-0.69.0/src/anthropic/_utils/_reflection.py000066400000000000000000000025241506653454500246330ustar00rootroot00000000000000from __future__ import annotations import inspect from typing import Any, Callable def function_has_argument(func: Callable[..., Any], arg_name: str) -> bool: """Returns whether or not the given function has a specific parameter""" sig = inspect.signature(func) return arg_name in sig.parameters def assert_signatures_in_sync( source_func: Callable[..., Any], check_func: Callable[..., Any], *, exclude_params: set[str] = set(), ) -> None: """Ensure that the signature of the second function matches the first.""" check_sig = inspect.signature(check_func) source_sig = inspect.signature(source_func) errors: list[str] = [] for name, source_param in source_sig.parameters.items(): if name in exclude_params: continue custom_param = check_sig.parameters.get(name) if not custom_param: errors.append(f"the `{name}` param is missing") continue if custom_param.annotation != source_param.annotation: errors.append( f"types for the `{name}` param are do not match; source={repr(source_param.annotation)} checking={repr(custom_param.annotation)}" ) continue if errors: raise AssertionError(f"{len(errors)} errors encountered when comparing signatures:\n\n" + "\n\n".join(errors)) anthropic-sdk-python-0.69.0/src/anthropic/_utils/_resources_proxy.py000066400000000000000000000011341506653454500257500ustar00rootroot00000000000000from __future__ import annotations from typing import Any from typing_extensions import override from ._proxy import LazyProxy class ResourcesProxy(LazyProxy[Any]): """A proxy for the `anthropic.resources` module. This is used so that we can lazily import `anthropic.resources` only when needed *and* so that users can just import `anthropic` and reference `anthropic.resources` """ @override def __load__(self) -> Any: import importlib mod = importlib.import_module("anthropic.resources") return mod resources = ResourcesProxy().__as_proxied__() anthropic-sdk-python-0.69.0/src/anthropic/_utils/_streams.py000066400000000000000000000004411506653454500241530ustar00rootroot00000000000000from typing import Any from typing_extensions import Iterator, AsyncIterator def consume_sync_iterator(iterator: Iterator[Any]) -> None: for _ in iterator: ... async def consume_async_iterator(iterator: AsyncIterator[Any]) -> None: async for _ in iterator: ... anthropic-sdk-python-0.69.0/src/anthropic/_utils/_sync.py000066400000000000000000000054561506653454500234640ustar00rootroot00000000000000from __future__ import annotations import sys import asyncio import functools import contextvars from typing import Any, TypeVar, Callable, Awaitable from typing_extensions import ParamSpec import anyio import sniffio import anyio.to_thread T_Retval = TypeVar("T_Retval") T_ParamSpec = ParamSpec("T_ParamSpec") if sys.version_info >= (3, 9): _asyncio_to_thread = asyncio.to_thread else: # backport of https://docs.python.org/3/library/asyncio-task.html#asyncio.to_thread # for Python 3.8 support async def _asyncio_to_thread( func: Callable[T_ParamSpec, T_Retval], /, *args: T_ParamSpec.args, **kwargs: T_ParamSpec.kwargs ) -> Any: """Asynchronously run function *func* in a separate thread. Any *args and **kwargs supplied for this function are directly passed to *func*. Also, the current :class:`contextvars.Context` is propagated, allowing context variables from the main thread to be accessed in the separate thread. Returns a coroutine that can be awaited to get the eventual result of *func*. """ loop = asyncio.events.get_running_loop() ctx = contextvars.copy_context() func_call = functools.partial(ctx.run, func, *args, **kwargs) return await loop.run_in_executor(None, func_call) async def to_thread( func: Callable[T_ParamSpec, T_Retval], /, *args: T_ParamSpec.args, **kwargs: T_ParamSpec.kwargs ) -> T_Retval: if sniffio.current_async_library() == "asyncio": return await _asyncio_to_thread(func, *args, **kwargs) return await anyio.to_thread.run_sync( functools.partial(func, *args, **kwargs), ) # inspired by `asyncer`, https://github.com/tiangolo/asyncer def asyncify(function: Callable[T_ParamSpec, T_Retval]) -> Callable[T_ParamSpec, Awaitable[T_Retval]]: """ Take a blocking function and create an async one that receives the same positional and keyword arguments. For python version 3.9 and above, it uses asyncio.to_thread to run the function in a separate thread. For python version 3.8, it uses locally defined copy of the asyncio.to_thread function which was introduced in python 3.9. Usage: ```python def blocking_func(arg1, arg2, kwarg1=None): # blocking code return result result = asyncify(blocking_function)(arg1, arg2, kwarg1=value1) ``` ## Arguments `function`: a blocking regular callable (e.g. a function) ## Return An async function that takes the same positional and keyword arguments as the original one, that when called runs the same original function in a thread worker and returns the result. """ async def wrapper(*args: T_ParamSpec.args, **kwargs: T_ParamSpec.kwargs) -> T_Retval: return await to_thread(function, *args, **kwargs) return wrapper anthropic-sdk-python-0.69.0/src/anthropic/_utils/_transform.py000066400000000000000000000371171506653454500245220ustar00rootroot00000000000000from __future__ import annotations import io import base64 import pathlib from typing import Any, Mapping, TypeVar, cast from datetime import date, datetime from typing_extensions import Literal, get_args, override, get_type_hints as _get_type_hints import anyio import pydantic from ._utils import ( is_list, is_given, lru_cache, is_mapping, is_iterable, is_sequence, ) from .._files import is_base64_file_input from ._compat import get_origin, is_typeddict from ._typing import ( is_list_type, is_union_type, extract_type_arg, is_iterable_type, is_required_type, is_sequence_type, is_annotated_type, strip_annotated_type, ) _T = TypeVar("_T") # TODO: support for drilling globals() and locals() # TODO: ensure works correctly with forward references in all cases PropertyFormat = Literal["iso8601", "base64", "custom"] class PropertyInfo: """Metadata class to be used in Annotated types to provide information about a given type. For example: class MyParams(TypedDict): account_holder_name: Annotated[str, PropertyInfo(alias='accountHolderName')] This means that {'account_holder_name': 'Robert'} will be transformed to {'accountHolderName': 'Robert'} before being sent to the API. """ alias: str | None format: PropertyFormat | None format_template: str | None discriminator: str | None def __init__( self, *, alias: str | None = None, format: PropertyFormat | None = None, format_template: str | None = None, discriminator: str | None = None, ) -> None: self.alias = alias self.format = format self.format_template = format_template self.discriminator = discriminator @override def __repr__(self) -> str: return f"{self.__class__.__name__}(alias='{self.alias}', format={self.format}, format_template='{self.format_template}', discriminator='{self.discriminator}')" def maybe_transform( data: object, expected_type: object, ) -> Any | None: """Wrapper over `transform()` that allows `None` to be passed. See `transform()` for more details. """ if data is None: return None return transform(data, expected_type) # Wrapper over _transform_recursive providing fake types def transform( data: _T, expected_type: object, ) -> _T: """Transform dictionaries based off of type information from the given type, for example: ```py class Params(TypedDict, total=False): card_id: Required[Annotated[str, PropertyInfo(alias="cardID")]] transformed = transform({"card_id": ""}, Params) # {'cardID': ''} ``` Any keys / data that does not have type information given will be included as is. It should be noted that the transformations that this function does are not represented in the type system. """ transformed = _transform_recursive(data, annotation=cast(type, expected_type)) return cast(_T, transformed) @lru_cache(maxsize=8096) def _get_annotated_type(type_: type) -> type | None: """If the given type is an `Annotated` type then it is returned, if not `None` is returned. This also unwraps the type when applicable, e.g. `Required[Annotated[T, ...]]` """ if is_required_type(type_): # Unwrap `Required[Annotated[T, ...]]` to `Annotated[T, ...]` type_ = get_args(type_)[0] if is_annotated_type(type_): return type_ return None def _maybe_transform_key(key: str, type_: type) -> str: """Transform the given `data` based on the annotations provided in `type_`. Note: this function only looks at `Annotated` types that contain `PropertyInfo` metadata. """ annotated_type = _get_annotated_type(type_) if annotated_type is None: # no `Annotated` definition for this type, no transformation needed return key # ignore the first argument as it is the actual type annotations = get_args(annotated_type)[1:] for annotation in annotations: if isinstance(annotation, PropertyInfo) and annotation.alias is not None: return annotation.alias return key def _no_transform_needed(annotation: type) -> bool: return annotation == float or annotation == int def _transform_recursive( data: object, *, annotation: type, inner_type: type | None = None, ) -> object: """Transform the given data against the expected type. Args: annotation: The direct type annotation given to the particular piece of data. This may or may not be wrapped in metadata types, e.g. `Required[T]`, `Annotated[T, ...]` etc inner_type: If applicable, this is the "inside" type. This is useful in certain cases where the outside type is a container type such as `List[T]`. In that case `inner_type` should be set to `T` so that each entry in the list can be transformed using the metadata from the container type. Defaults to the same value as the `annotation` argument. """ from .._compat import model_dump if inner_type is None: inner_type = annotation stripped_type = strip_annotated_type(inner_type) origin = get_origin(stripped_type) or stripped_type if is_typeddict(stripped_type) and is_mapping(data): return _transform_typeddict(data, stripped_type) if origin == dict and is_mapping(data): items_type = get_args(stripped_type)[1] return {key: _transform_recursive(value, annotation=items_type) for key, value in data.items()} if ( # List[T] (is_list_type(stripped_type) and is_list(data)) # Iterable[T] or (is_iterable_type(stripped_type) and is_iterable(data) and not isinstance(data, str)) # Sequence[T] or (is_sequence_type(stripped_type) and is_sequence(data) and not isinstance(data, str)) ): # dicts are technically iterable, but it is an iterable on the keys of the dict and is not usually # intended as an iterable, so we don't transform it. if isinstance(data, dict): return cast(object, data) inner_type = extract_type_arg(stripped_type, 0) if _no_transform_needed(inner_type): # for some types there is no need to transform anything, so we can get a small # perf boost from skipping that work. # # but we still need to convert to a list to ensure the data is json-serializable if is_list(data): return data return list(data) return [_transform_recursive(d, annotation=annotation, inner_type=inner_type) for d in data] if is_union_type(stripped_type): # For union types we run the transformation against all subtypes to ensure that everything is transformed. # # TODO: there may be edge cases where the same normalized field name will transform to two different names # in different subtypes. for subtype in get_args(stripped_type): data = _transform_recursive(data, annotation=annotation, inner_type=subtype) return data if isinstance(data, pydantic.BaseModel): return model_dump(data, exclude_unset=True, mode="json") annotated_type = _get_annotated_type(annotation) if annotated_type is None: return data # ignore the first argument as it is the actual type annotations = get_args(annotated_type)[1:] for annotation in annotations: if isinstance(annotation, PropertyInfo) and annotation.format is not None: return _format_data(data, annotation.format, annotation.format_template) return data def _format_data(data: object, format_: PropertyFormat, format_template: str | None) -> object: if isinstance(data, (date, datetime)): if format_ == "iso8601": return data.isoformat() if format_ == "custom" and format_template is not None: return data.strftime(format_template) if format_ == "base64" and is_base64_file_input(data): binary: str | bytes | None = None if isinstance(data, pathlib.Path): binary = data.read_bytes() elif isinstance(data, io.IOBase): binary = data.read() if isinstance(binary, str): # type: ignore[unreachable] binary = binary.encode() if not isinstance(binary, bytes): raise RuntimeError(f"Could not read bytes from {data}; Received {type(binary)}") return base64.b64encode(binary).decode("ascii") return data def _transform_typeddict( data: Mapping[str, object], expected_type: type, ) -> Mapping[str, object]: result: dict[str, object] = {} annotations = get_type_hints(expected_type, include_extras=True) for key, value in data.items(): if not is_given(value): # we don't need to include omitted values here as they'll # be stripped out before the request is sent anyway continue type_ = annotations.get(key) if type_ is None: # we do not have a type annotation for this field, leave it as is result[key] = value else: result[_maybe_transform_key(key, type_)] = _transform_recursive(value, annotation=type_) return result async def async_maybe_transform( data: object, expected_type: object, ) -> Any | None: """Wrapper over `async_transform()` that allows `None` to be passed. See `async_transform()` for more details. """ if data is None: return None return await async_transform(data, expected_type) async def async_transform( data: _T, expected_type: object, ) -> _T: """Transform dictionaries based off of type information from the given type, for example: ```py class Params(TypedDict, total=False): card_id: Required[Annotated[str, PropertyInfo(alias="cardID")]] transformed = transform({"card_id": ""}, Params) # {'cardID': ''} ``` Any keys / data that does not have type information given will be included as is. It should be noted that the transformations that this function does are not represented in the type system. """ transformed = await _async_transform_recursive(data, annotation=cast(type, expected_type)) return cast(_T, transformed) async def _async_transform_recursive( data: object, *, annotation: type, inner_type: type | None = None, ) -> object: """Transform the given data against the expected type. Args: annotation: The direct type annotation given to the particular piece of data. This may or may not be wrapped in metadata types, e.g. `Required[T]`, `Annotated[T, ...]` etc inner_type: If applicable, this is the "inside" type. This is useful in certain cases where the outside type is a container type such as `List[T]`. In that case `inner_type` should be set to `T` so that each entry in the list can be transformed using the metadata from the container type. Defaults to the same value as the `annotation` argument. """ from .._compat import model_dump if inner_type is None: inner_type = annotation stripped_type = strip_annotated_type(inner_type) origin = get_origin(stripped_type) or stripped_type if is_typeddict(stripped_type) and is_mapping(data): return await _async_transform_typeddict(data, stripped_type) if origin == dict and is_mapping(data): items_type = get_args(stripped_type)[1] return {key: _transform_recursive(value, annotation=items_type) for key, value in data.items()} if ( # List[T] (is_list_type(stripped_type) and is_list(data)) # Iterable[T] or (is_iterable_type(stripped_type) and is_iterable(data) and not isinstance(data, str)) # Sequence[T] or (is_sequence_type(stripped_type) and is_sequence(data) and not isinstance(data, str)) ): # dicts are technically iterable, but it is an iterable on the keys of the dict and is not usually # intended as an iterable, so we don't transform it. if isinstance(data, dict): return cast(object, data) inner_type = extract_type_arg(stripped_type, 0) if _no_transform_needed(inner_type): # for some types there is no need to transform anything, so we can get a small # perf boost from skipping that work. # # but we still need to convert to a list to ensure the data is json-serializable if is_list(data): return data return list(data) return [await _async_transform_recursive(d, annotation=annotation, inner_type=inner_type) for d in data] if is_union_type(stripped_type): # For union types we run the transformation against all subtypes to ensure that everything is transformed. # # TODO: there may be edge cases where the same normalized field name will transform to two different names # in different subtypes. for subtype in get_args(stripped_type): data = await _async_transform_recursive(data, annotation=annotation, inner_type=subtype) return data if isinstance(data, pydantic.BaseModel): return model_dump(data, exclude_unset=True, mode="json") annotated_type = _get_annotated_type(annotation) if annotated_type is None: return data # ignore the first argument as it is the actual type annotations = get_args(annotated_type)[1:] for annotation in annotations: if isinstance(annotation, PropertyInfo) and annotation.format is not None: return await _async_format_data(data, annotation.format, annotation.format_template) return data async def _async_format_data(data: object, format_: PropertyFormat, format_template: str | None) -> object: if isinstance(data, (date, datetime)): if format_ == "iso8601": return data.isoformat() if format_ == "custom" and format_template is not None: return data.strftime(format_template) if format_ == "base64" and is_base64_file_input(data): binary: str | bytes | None = None if isinstance(data, pathlib.Path): binary = await anyio.Path(data).read_bytes() elif isinstance(data, io.IOBase): binary = data.read() if isinstance(binary, str): # type: ignore[unreachable] binary = binary.encode() if not isinstance(binary, bytes): raise RuntimeError(f"Could not read bytes from {data}; Received {type(binary)}") return base64.b64encode(binary).decode("ascii") return data async def _async_transform_typeddict( data: Mapping[str, object], expected_type: type, ) -> Mapping[str, object]: result: dict[str, object] = {} annotations = get_type_hints(expected_type, include_extras=True) for key, value in data.items(): if not is_given(value): # we don't need to include omitted values here as they'll # be stripped out before the request is sent anyway continue type_ = annotations.get(key) if type_ is None: # we do not have a type annotation for this field, leave it as is result[key] = value else: result[_maybe_transform_key(key, type_)] = await _async_transform_recursive(value, annotation=type_) return result @lru_cache(maxsize=8096) def get_type_hints( obj: Any, globalns: dict[str, Any] | None = None, localns: Mapping[str, Any] | None = None, include_extras: bool = False, ) -> dict[str, Any]: return _get_type_hints(obj, globalns=globalns, localns=localns, include_extras=include_extras) anthropic-sdk-python-0.69.0/src/anthropic/_utils/_typing.py000066400000000000000000000112621506653454500240120ustar00rootroot00000000000000from __future__ import annotations import sys import typing import typing_extensions from typing import Any, TypeVar, Iterable, cast from collections import abc as _c_abc from typing_extensions import ( TypeIs, Required, Annotated, get_args, get_origin, ) from ._utils import lru_cache from .._types import InheritsGeneric from ._compat import is_union as _is_union def is_annotated_type(typ: type) -> bool: return get_origin(typ) == Annotated def is_list_type(typ: type) -> bool: return (get_origin(typ) or typ) == list def is_sequence_type(typ: type) -> bool: origin = get_origin(typ) or typ return origin == typing_extensions.Sequence or origin == typing.Sequence or origin == _c_abc.Sequence def is_iterable_type(typ: type) -> bool: """If the given type is `typing.Iterable[T]`""" origin = get_origin(typ) or typ return origin == Iterable or origin == _c_abc.Iterable def is_union_type(typ: type) -> bool: return _is_union(get_origin(typ)) def is_required_type(typ: type) -> bool: return get_origin(typ) == Required def is_typevar(typ: type) -> bool: # type ignore is required because type checkers # think this expression will always return False return type(typ) == TypeVar # type: ignore _TYPE_ALIAS_TYPES: tuple[type[typing_extensions.TypeAliasType], ...] = (typing_extensions.TypeAliasType,) if sys.version_info >= (3, 12): _TYPE_ALIAS_TYPES = (*_TYPE_ALIAS_TYPES, typing.TypeAliasType) def is_type_alias_type(tp: Any, /) -> TypeIs[typing_extensions.TypeAliasType]: """Return whether the provided argument is an instance of `TypeAliasType`. ```python type Int = int is_type_alias_type(Int) # > True Str = TypeAliasType("Str", str) is_type_alias_type(Str) # > True ``` """ return isinstance(tp, _TYPE_ALIAS_TYPES) # Extracts T from Annotated[T, ...] or from Required[Annotated[T, ...]] @lru_cache(maxsize=8096) def strip_annotated_type(typ: type) -> type: if is_required_type(typ) or is_annotated_type(typ): return strip_annotated_type(cast(type, get_args(typ)[0])) return typ def extract_type_arg(typ: type, index: int) -> type: args = get_args(typ) try: return cast(type, args[index]) except IndexError as err: raise RuntimeError(f"Expected type {typ} to have a type argument at index {index} but it did not") from err def extract_type_var_from_base( typ: type, *, generic_bases: tuple[type, ...], index: int, failure_message: str | None = None, ) -> type: """Given a type like `Foo[T]`, returns the generic type variable `T`. This also handles the case where a concrete subclass is given, e.g. ```py class MyResponse(Foo[bytes]): ... extract_type_var(MyResponse, bases=(Foo,), index=0) -> bytes ``` And where a generic subclass is given: ```py _T = TypeVar('_T') class MyResponse(Foo[_T]): ... extract_type_var(MyResponse[bytes], bases=(Foo,), index=0) -> bytes ``` """ cls = cast(object, get_origin(typ) or typ) if cls in generic_bases: # pyright: ignore[reportUnnecessaryContains] # we're given the class directly return extract_type_arg(typ, index) # if a subclass is given # --- # this is needed as __orig_bases__ is not present in the typeshed stubs # because it is intended to be for internal use only, however there does # not seem to be a way to resolve generic TypeVars for inherited subclasses # without using it. if isinstance(cls, InheritsGeneric): target_base_class: Any | None = None for base in cls.__orig_bases__: if base.__origin__ in generic_bases: target_base_class = base break if target_base_class is None: raise RuntimeError( "Could not find the generic base class;\n" "This should never happen;\n" f"Does {cls} inherit from one of {generic_bases} ?" ) extracted = extract_type_arg(target_base_class, index) if is_typevar(extracted): # If the extracted type argument is itself a type variable # then that means the subclass itself is generic, so we have # to resolve the type argument from the class itself, not # the base class. # # Note: if there is more than 1 type argument, the subclass could # change the ordering of the type arguments, this is not currently # supported. return extract_type_arg(typ, index) return extracted raise RuntimeError(failure_message or f"Could not resolve inner type variable at index {index} for {typ}") anthropic-sdk-python-0.69.0/src/anthropic/_utils/_utils.py000066400000000000000000000277351506653454500236540ustar00rootroot00000000000000from __future__ import annotations import os import re import inspect import functools from typing import ( Any, Tuple, Mapping, TypeVar, Callable, Iterable, Sequence, cast, overload, ) from pathlib import Path from datetime import date, datetime from typing_extensions import TypeGuard import sniffio from .._types import Omit, NotGiven, FileTypes, HeadersLike _T = TypeVar("_T") _TupleT = TypeVar("_TupleT", bound=Tuple[object, ...]) _MappingT = TypeVar("_MappingT", bound=Mapping[str, object]) _SequenceT = TypeVar("_SequenceT", bound=Sequence[object]) CallableT = TypeVar("CallableT", bound=Callable[..., Any]) def flatten(t: Iterable[Iterable[_T]]) -> list[_T]: return [item for sublist in t for item in sublist] def extract_files( # TODO: this needs to take Dict but variance issues..... # create protocol type ? query: Mapping[str, object], *, paths: Sequence[Sequence[str]], ) -> list[tuple[str, FileTypes]]: """Recursively extract files from the given dictionary based on specified paths. A path may look like this ['foo', 'files', '', 'data']. 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)) return files def _extract_items( obj: object, path: Sequence[str], *, index: int, flattened_key: str | None, ) -> list[tuple[str, FileTypes]]: try: key = path[index] except IndexError: if not is_given(obj): # no value was provided - we can safely ignore return [] # cyclical import from .._files import assert_is_file_content # We have exhausted the path, return the entry we found. assert flattened_key is not None 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))) return files assert_is_file_content(obj, key=flattened_key) return [(flattened_key, cast(FileTypes, obj))] 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: item = obj.pop(key) else: item = obj[key] except KeyError: # Key was not present in the dictionary, this is not indicative of an error # as the given path may not point to a required field. We also do not want # to enforce required fields as the API may differ from the spec in some cases. return [] if flattened_key is None: flattened_key = key else: flattened_key += f"[{key}]" return _extract_items( item, path, index=index, flattened_key=flattened_key, ) elif is_list(obj): if key != "": return [] return flatten( [ _extract_items( item, path, index=index, flattened_key=flattened_key + "[]" if flattened_key is not None else "[]", ) for item in obj ] ) # Something unexpected was passed, just ignore it. return [] def is_given(obj: _T | NotGiven | Omit) -> TypeGuard[_T]: return not isinstance(obj, NotGiven) and not isinstance(obj, Omit) # Type safe methods for narrowing types with TypeVars. # The default narrowing for isinstance(obj, dict) is dict[unknown, unknown], # however this cause Pyright to rightfully report errors. As we know we don't # care about the contained types we can safely use `object` in it's place. # # There are two separate functions defined, `is_*` and `is_*_t` for different use cases. # `is_*` is for when you're dealing with an unknown input # `is_*_t` is for when you're narrowing a known union type to a specific subset def is_tuple(obj: object) -> TypeGuard[tuple[object, ...]]: return isinstance(obj, tuple) def is_tuple_t(obj: _TupleT | object) -> TypeGuard[_TupleT]: return isinstance(obj, tuple) def is_sequence(obj: object) -> TypeGuard[Sequence[object]]: return isinstance(obj, Sequence) def is_sequence_t(obj: _SequenceT | object) -> TypeGuard[_SequenceT]: return isinstance(obj, Sequence) def is_mapping(obj: object) -> TypeGuard[Mapping[str, object]]: return isinstance(obj, Mapping) def is_mapping_t(obj: _MappingT | object) -> TypeGuard[_MappingT]: return isinstance(obj, Mapping) def is_dict(obj: object) -> TypeGuard[dict[object, object]]: return isinstance(obj, dict) def is_list(obj: object) -> TypeGuard[list[object]]: return isinstance(obj, list) 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) if size == 0: return "" if size == 1: return seq[0] if size == 2: return f"{seq[0]} {final} {seq[1]}" return delim.join(seq[:-1]) + f" {final} {seq[-1]}" def quote(string: str) -> str: """Add single quotation marks around the given string. Does *not* do any escaping.""" return f"'{string}'" def required_args(*variants: Sequence[str]) -> Callable[[CallableT], CallableT]: """Decorator to enforce a given set of arguments or variants of arguments are passed to the decorated function. Useful for enforcing runtime validation of overloaded functions. Example usage: ```py @overload def foo(*, a: str) -> str: ... @overload def foo(*, b: bool) -> str: ... # This enforces the same constraints that a static type checker would # i.e. that either a or b must be passed to the function @required_args(["a"], ["b"]) def foo(*, a: str | None = None, b: bool | None = None) -> str: ... ``` """ def inner(func: CallableT) -> CallableT: params = inspect.signature(func).parameters positional = [ name for name, param in params.items() if param.kind in { param.POSITIONAL_ONLY, param.POSITIONAL_OR_KEYWORD, } ] @functools.wraps(func) def wrapper(*args: object, **kwargs: object) -> object: given_params: set[str] = set() for i, _ in enumerate(args): try: given_params.add(positional[i]) except IndexError: raise TypeError( f"{func.__name__}() takes {len(positional)} argument(s) but {len(args)} were given" ) from None for key in kwargs.keys(): given_params.add(key) for variant in variants: matches = all((param in given_params for param in variant)) if matches: break else: # no break if len(variants) > 1: variations = human_join( ["(" + human_join([quote(arg) for arg in variant], final="and") + ")" for variant in variants] ) msg = f"Missing required arguments; Expected either {variations} arguments to be given" else: assert len(variants) > 0 # TODO: this error message is not deterministic missing = list(set(variants[0]) - given_params) if len(missing) > 1: msg = f"Missing required arguments: {human_join([quote(arg) for arg in missing])}" else: msg = f"Missing required argument: {quote(missing[0])}" raise TypeError(msg) return func(*args, **kwargs) return wrapper # type: ignore return inner _K = TypeVar("_K") _V = TypeVar("_V") @overload def strip_not_given(obj: None) -> None: ... @overload def strip_not_given(obj: Mapping[_K, _V | NotGiven]) -> dict[_K, _V]: ... @overload def strip_not_given(obj: object) -> object: ... def strip_not_given(obj: object | None) -> object: """Remove all top-level keys where their values are instances of `NotGiven`""" if obj is None: return None if not is_mapping(obj): return obj return {key: value for key, value in obj.items() if not isinstance(value, NotGiven)} def coerce_integer(val: str) -> int: return int(val, base=10) def coerce_float(val: str) -> float: return float(val) def coerce_boolean(val: str) -> bool: return val == "true" or val == "1" or val == "on" def maybe_coerce_integer(val: str | None) -> int | None: if val is None: return None return coerce_integer(val) def maybe_coerce_float(val: str | None) -> float | None: if val is None: return None return coerce_float(val) def maybe_coerce_boolean(val: str | None) -> bool | None: if val is None: return None return coerce_boolean(val) def removeprefix(string: str, prefix: str) -> str: """Remove a prefix from a string. Backport of `str.removeprefix` for Python < 3.9 """ if string.startswith(prefix): return string[len(prefix) :] return string def removesuffix(string: str, suffix: str) -> str: """Remove a suffix from a string. Backport of `str.removesuffix` for Python < 3.9 """ if string.endswith(suffix): return string[: -len(suffix)] return string def file_from_path(path: str) -> FileTypes: contents = Path(path).read_bytes() file_name = os.path.basename(path) return (file_name, contents) def get_required_header(headers: HeadersLike, header: str) -> str: lower_header = header.lower() if is_mapping_t(headers): # mypy doesn't understand the type narrowing here for k, v in headers.items(): # type: ignore if k.lower() == lower_header and isinstance(v, str): return v # to deal with the case where the header looks like Stainless-Event-Id intercaps_header = re.sub(r"([^\w])(\w)", lambda pat: pat.group(1) + pat.group(2).upper(), header.capitalize()) for normalized_header in [header, lower_header, header.upper(), intercaps_header]: value = headers.get(normalized_header) if value: return value raise ValueError(f"Could not find {header} header") def get_async_library() -> str: try: return sniffio.current_async_library() except Exception: return "false" def lru_cache(*, maxsize: int | None = 128) -> Callable[[CallableT], CallableT]: """A version of functools.lru_cache that retains the type signature for the wrapped function arguments. """ wrapper = functools.lru_cache( # noqa: TID251 maxsize=maxsize, ) return cast(Any, wrapper) # type: ignore[no-any-return] def json_safe(data: object) -> object: """Translates a mapping / sequence recursively in the same fashion as `pydantic` v2's `model_dump(mode="json")`. """ if is_mapping(data): return {json_safe(key): json_safe(value) for key, value in data.items()} if is_iterable(data) and not isinstance(data, (str, bytes, bytearray)): return [json_safe(item) for item in data] if isinstance(data, (datetime, date)): return data.isoformat() return data anthropic-sdk-python-0.69.0/src/anthropic/_version.py000066400000000000000000000002421506653454500226620ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "anthropic" __version__ = "0.69.0" # x-release-please-version anthropic-sdk-python-0.69.0/src/anthropic/lib/000077500000000000000000000000001506653454500212345ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/lib/.keep000066400000000000000000000003401506653454500221560ustar00rootroot00000000000000File generated from our OpenAPI spec by Stainless. This directory can be used to store custom files to expand the SDK. It is ignored by Stainless code generation and its content (other than this keep file) won't be touched.anthropic-sdk-python-0.69.0/src/anthropic/lib/__init__.py000066400000000000000000000000001506653454500233330ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/lib/_extras/000077500000000000000000000000001506653454500227015ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/lib/_extras/__init__.py000066400000000000000000000000651506653454500250130ustar00rootroot00000000000000from ._google_auth import google_auth as google_auth anthropic-sdk-python-0.69.0/src/anthropic/lib/_extras/_common.py000066400000000000000000000005341506653454500247040ustar00rootroot00000000000000from ..._exceptions import AnthropicError INSTRUCTIONS = """ Anthropic error: missing required dependency `{library}`. $ pip install anthropic[{extra}] """ class MissingDependencyError(AnthropicError): def __init__(self, *, library: str, extra: str) -> None: super().__init__(INSTRUCTIONS.format(library=library, extra=extra)) anthropic-sdk-python-0.69.0/src/anthropic/lib/_extras/_google_auth.py000066400000000000000000000012601506653454500257060ustar00rootroot00000000000000from __future__ import annotations from typing import TYPE_CHECKING, Any from typing_extensions import ClassVar, override from ._common import MissingDependencyError from ..._utils import LazyProxy if TYPE_CHECKING: import google.auth # type: ignore google_auth = google.auth class GoogleAuthProxy(LazyProxy[Any]): should_cache: ClassVar[bool] = True @override def __load__(self) -> Any: try: import google.auth # type: ignore except ImportError as err: raise MissingDependencyError(extra="vertex", library="google-auth") from err return google.auth if not TYPE_CHECKING: google_auth = GoogleAuthProxy() anthropic-sdk-python-0.69.0/src/anthropic/lib/bedrock/000077500000000000000000000000001506653454500226455ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/lib/bedrock/__init__.py000066400000000000000000000001521506653454500247540ustar00rootroot00000000000000from ._client import AnthropicBedrock as AnthropicBedrock, AsyncAnthropicBedrock as AsyncAnthropicBedrock anthropic-sdk-python-0.69.0/src/anthropic/lib/bedrock/_auth.py000066400000000000000000000035421506653454500243230ustar00rootroot00000000000000from __future__ import annotations from typing import TYPE_CHECKING import httpx from ..._utils import lru_cache if TYPE_CHECKING: import boto3 @lru_cache(maxsize=512) def _get_session( *, aws_access_key: str | None, aws_secret_key: str | None, aws_session_token: str | None, region: str | None, profile: str | None, ) -> boto3.Session: import boto3 return boto3.Session( profile_name=profile, region_name=region, aws_access_key_id=aws_access_key, aws_secret_access_key=aws_secret_key, aws_session_token=aws_session_token, ) def get_auth_headers( *, method: str, url: str, headers: httpx.Headers, aws_access_key: str | None, aws_secret_key: str | None, aws_session_token: str | None, region: str | None, profile: str | None, data: str | None, ) -> dict[str, str]: from botocore.auth import SigV4Auth from botocore.awsrequest import AWSRequest session = _get_session( profile=profile, region=region, aws_access_key=aws_access_key, aws_secret_key=aws_secret_key, aws_session_token=aws_session_token, ) # The connection header may be stripped by a proxy somewhere, so the receiver # of this message may not see this header, so we remove it from the set of headers # that are signed. headers = headers.copy() del headers["connection"] request = AWSRequest(method=method.upper(), url=url, headers=headers, data=data) credentials = session.get_credentials() if not credentials: raise RuntimeError("could not resolve credentials from session") signer = SigV4Auth(credentials, "bedrock", session.region_name) signer.add_auth(request) prepped = request.prepare() return {key: value for key, value in dict(prepped.headers).items() if value is not None} anthropic-sdk-python-0.69.0/src/anthropic/lib/bedrock/_beta.py000066400000000000000000000063731506653454500243020ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource from ._beta_messages import ( Messages, AsyncMessages, MessagesWithRawResponse, AsyncMessagesWithRawResponse, MessagesWithStreamingResponse, AsyncMessagesWithStreamingResponse, ) __all__ = ["Beta", "AsyncBeta"] class Beta(SyncAPIResource): @cached_property def messages(self) -> Messages: return Messages(self._client) @cached_property def with_raw_response(self) -> BetaWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the the raw response object instead of the parsed content. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers """ return BetaWithRawResponse(self) @cached_property def with_streaming_response(self) -> BetaWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response """ return BetaWithStreamingResponse(self) class AsyncBeta(AsyncAPIResource): @cached_property def messages(self) -> AsyncMessages: return AsyncMessages(self._client) @cached_property def with_raw_response(self) -> AsyncBetaWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the the raw response object instead of the parsed content. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers """ return AsyncBetaWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncBetaWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response """ return AsyncBetaWithStreamingResponse(self) class BetaWithRawResponse: def __init__(self, beta: Beta) -> None: self._beta = beta @cached_property def messages(self) -> MessagesWithRawResponse: return MessagesWithRawResponse(self._beta.messages) class AsyncBetaWithRawResponse: def __init__(self, beta: AsyncBeta) -> None: self._beta = beta @cached_property def messages(self) -> AsyncMessagesWithRawResponse: return AsyncMessagesWithRawResponse(self._beta.messages) class BetaWithStreamingResponse: def __init__(self, beta: Beta) -> None: self._beta = beta @cached_property def messages(self) -> MessagesWithStreamingResponse: return MessagesWithStreamingResponse(self._beta.messages) class AsyncBetaWithStreamingResponse: def __init__(self, beta: AsyncBeta) -> None: self._beta = beta @cached_property def messages(self) -> AsyncMessagesWithStreamingResponse: return AsyncMessagesWithStreamingResponse(self._beta.messages) anthropic-sdk-python-0.69.0/src/anthropic/lib/bedrock/_beta_messages.py000066400000000000000000000061751506653454500261710ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from ... import _legacy_response from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper from ...resources.beta import Messages as FirstPartyMessagesAPI, AsyncMessages as FirstPartyAsyncMessagesAPI __all__ = ["Messages", "AsyncMessages"] class Messages(SyncAPIResource): create = FirstPartyMessagesAPI.create @cached_property def with_raw_response(self) -> MessagesWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the the raw response object instead of the parsed content. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers """ return MessagesWithRawResponse(self) @cached_property def with_streaming_response(self) -> MessagesWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response """ return MessagesWithStreamingResponse(self) class AsyncMessages(AsyncAPIResource): create = FirstPartyAsyncMessagesAPI.create @cached_property def with_raw_response(self) -> AsyncMessagesWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the the raw response object instead of the parsed content. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers """ return AsyncMessagesWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncMessagesWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response """ return AsyncMessagesWithStreamingResponse(self) class MessagesWithRawResponse: def __init__(self, messages: Messages) -> None: self._messages = messages self.create = _legacy_response.to_raw_response_wrapper( messages.create, ) class AsyncMessagesWithRawResponse: def __init__(self, messages: AsyncMessages) -> None: self._messages = messages self.create = _legacy_response.async_to_raw_response_wrapper( messages.create, ) class MessagesWithStreamingResponse: def __init__(self, messages: Messages) -> None: self._messages = messages self.create = to_streamed_response_wrapper( messages.create, ) class AsyncMessagesWithStreamingResponse: def __init__(self, messages: AsyncMessages) -> None: self._messages = messages self.create = async_to_streamed_response_wrapper( messages.create, ) anthropic-sdk-python-0.69.0/src/anthropic/lib/bedrock/_client.py000066400000000000000000000370531506653454500246440ustar00rootroot00000000000000from __future__ import annotations import os import logging import urllib.parse from typing import Any, Union, Mapping, TypeVar from typing_extensions import Self, override import httpx from ... import _exceptions from ._beta import Beta, AsyncBeta from ..._types import NOT_GIVEN, Timeout, NotGiven from ..._utils import is_dict, is_given from ..._compat import model_copy from ..._version import __version__ from ..._streaming import Stream, AsyncStream from ..._exceptions import AnthropicError, APIStatusError from ..._base_client import ( DEFAULT_MAX_RETRIES, BaseClient, SyncAPIClient, AsyncAPIClient, FinalRequestOptions, ) from ._stream_decoder import AWSEventStreamDecoder from ...resources.messages import Messages, AsyncMessages from ...resources.completions import Completions, AsyncCompletions log: logging.Logger = logging.getLogger(__name__) DEFAULT_VERSION = "bedrock-2023-05-31" _HttpxClientT = TypeVar("_HttpxClientT", bound=Union[httpx.Client, httpx.AsyncClient]) _DefaultStreamT = TypeVar("_DefaultStreamT", bound=Union[Stream[Any], AsyncStream[Any]]) def _prepare_options(input_options: FinalRequestOptions) -> FinalRequestOptions: options = model_copy(input_options, deep=True) if is_dict(options.json_data): options.json_data.setdefault("anthropic_version", DEFAULT_VERSION) if is_given(options.headers): betas = options.headers.get("anthropic-beta") if betas: options.json_data.setdefault("anthropic_beta", betas.split(",")) if options.url in {"/v1/complete", "/v1/messages", "/v1/messages?beta=true"} and options.method == "post": if not is_dict(options.json_data): raise RuntimeError("Expected dictionary json_data for post /completions endpoint") model = options.json_data.pop("model", None) model = urllib.parse.quote(str(model), safe=":") stream = options.json_data.pop("stream", False) if stream: options.url = f"/model/{model}/invoke-with-response-stream" else: options.url = f"/model/{model}/invoke" if options.url.startswith("/v1/messages/batches"): raise AnthropicError("The Batch API is not supported in Bedrock yet") if options.url == "/v1/messages/count_tokens": raise AnthropicError("Token counting is not supported in Bedrock yet") return options def _infer_region() -> str: """ Infer the AWS region from the environment variables or from the boto3 session if available. """ aws_region = os.environ.get("AWS_REGION") if aws_region is None: try: import boto3 session = boto3.Session() if session.region_name: aws_region = session.region_name except ImportError: pass if aws_region is None: log.warning("No AWS region specified, defaulting to us-east-1") aws_region = "us-east-1" # fall back to legacy behavior return aws_region class BaseBedrockClient(BaseClient[_HttpxClientT, _DefaultStreamT]): @override def _make_status_error( self, err_msg: str, *, body: object, response: httpx.Response, ) -> APIStatusError: if response.status_code == 400: return _exceptions.BadRequestError(err_msg, response=response, body=body) if response.status_code == 401: return _exceptions.AuthenticationError(err_msg, response=response, body=body) if response.status_code == 403: return _exceptions.PermissionDeniedError(err_msg, response=response, body=body) if response.status_code == 404: return _exceptions.NotFoundError(err_msg, response=response, body=body) if response.status_code == 409: return _exceptions.ConflictError(err_msg, response=response, body=body) if response.status_code == 422: return _exceptions.UnprocessableEntityError(err_msg, response=response, body=body) if response.status_code == 429: return _exceptions.RateLimitError(err_msg, response=response, body=body) if response.status_code == 503: return _exceptions.ServiceUnavailableError(err_msg, response=response, body=body) if response.status_code >= 500: return _exceptions.InternalServerError(err_msg, response=response, body=body) return APIStatusError(err_msg, response=response, body=body) class AnthropicBedrock(BaseBedrockClient[httpx.Client, Stream[Any]], SyncAPIClient): messages: Messages completions: Completions beta: Beta def __init__( self, aws_secret_key: str | None = None, aws_access_key: str | None = None, aws_region: str | None = None, aws_profile: str | None = None, aws_session_token: str | None = None, base_url: str | httpx.URL | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, max_retries: int = DEFAULT_MAX_RETRIES, default_headers: Mapping[str, str] | None = None, default_query: Mapping[str, object] | None = None, # Configure a custom httpx client. See the [httpx documentation](https://www.python-httpx.org/api/#client) for more details. http_client: httpx.Client | None = None, # Enable or disable schema validation for data returned by the API. # When enabled an error APIResponseValidationError is raised # if the API responds with invalid data for the expected schema. # # This parameter may be removed or changed in the future. # If you rely on this feature, please open a GitHub issue # outlining your use-case to help us decide if it should be # part of our public interface in the future. _strict_response_validation: bool = False, ) -> None: self.aws_secret_key = aws_secret_key self.aws_access_key = aws_access_key self.aws_region = _infer_region() if aws_region is None else aws_region self.aws_profile = aws_profile self.aws_session_token = aws_session_token if base_url is None: base_url = os.environ.get("ANTHROPIC_BEDROCK_BASE_URL") if base_url is None: base_url = f"https://bedrock-runtime.{self.aws_region}.amazonaws.com" super().__init__( version=__version__, base_url=base_url, timeout=timeout, max_retries=max_retries, custom_headers=default_headers, custom_query=default_query, http_client=http_client, _strict_response_validation=_strict_response_validation, ) self.beta = Beta(self) self.messages = Messages(self) self.completions = Completions(self) @override def _make_sse_decoder(self) -> AWSEventStreamDecoder: return AWSEventStreamDecoder() @override def _prepare_options(self, options: FinalRequestOptions) -> FinalRequestOptions: return _prepare_options(options) @override def _prepare_request(self, request: httpx.Request) -> None: from ._auth import get_auth_headers data = request.read().decode() headers = get_auth_headers( method=request.method, url=str(request.url), headers=request.headers, aws_access_key=self.aws_access_key, aws_secret_key=self.aws_secret_key, aws_session_token=self.aws_session_token, region=self.aws_region or "us-east-1", profile=self.aws_profile, data=data, ) request.headers.update(headers) def copy( self, *, aws_secret_key: str | None = None, aws_access_key: str | None = None, aws_region: str | None = None, aws_session_token: str | None = None, base_url: str | httpx.URL | None = None, timeout: float | Timeout | None | NotGiven = NOT_GIVEN, http_client: httpx.Client | None = None, max_retries: int | NotGiven = NOT_GIVEN, default_headers: Mapping[str, str] | None = None, set_default_headers: Mapping[str, str] | None = None, default_query: Mapping[str, object] | None = None, set_default_query: Mapping[str, object] | None = None, _extra_kwargs: Mapping[str, Any] = {}, ) -> Self: """ Create a new client instance re-using the same options given to the current client with optional overriding. """ if default_headers is not None and set_default_headers is not None: raise ValueError("The `default_headers` and `set_default_headers` arguments are mutually exclusive") if default_query is not None and set_default_query is not None: raise ValueError("The `default_query` and `set_default_query` arguments are mutually exclusive") headers = self._custom_headers if default_headers is not None: headers = {**headers, **default_headers} elif set_default_headers is not None: headers = set_default_headers params = self._custom_query if default_query is not None: params = {**params, **default_query} elif set_default_query is not None: params = set_default_query return self.__class__( aws_secret_key=aws_secret_key or self.aws_secret_key, aws_access_key=aws_access_key or self.aws_access_key, aws_region=aws_region or self.aws_region, aws_session_token=aws_session_token or self.aws_session_token, base_url=base_url or self.base_url, timeout=self.timeout if isinstance(timeout, NotGiven) else timeout, http_client=http_client, max_retries=max_retries if is_given(max_retries) else self.max_retries, default_headers=headers, default_query=params, **_extra_kwargs, ) # Alias for `copy` for nicer inline usage, e.g. # client.with_options(timeout=10).foo.create(...) with_options = copy class AsyncAnthropicBedrock(BaseBedrockClient[httpx.AsyncClient, AsyncStream[Any]], AsyncAPIClient): messages: AsyncMessages completions: AsyncCompletions beta: AsyncBeta def __init__( self, aws_secret_key: str | None = None, aws_access_key: str | None = None, aws_region: str | None = None, aws_profile: str | None = None, aws_session_token: str | None = None, base_url: str | httpx.URL | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, max_retries: int = DEFAULT_MAX_RETRIES, default_headers: Mapping[str, str] | None = None, default_query: Mapping[str, object] | None = None, # Configure a custom httpx client. See the [httpx documentation](https://www.python-httpx.org/api/#client) for more details. http_client: httpx.AsyncClient | None = None, # Enable or disable schema validation for data returned by the API. # When enabled an error APIResponseValidationError is raised # if the API responds with invalid data for the expected schema. # # This parameter may be removed or changed in the future. # If you rely on this feature, please open a GitHub issue # outlining your use-case to help us decide if it should be # part of our public interface in the future. _strict_response_validation: bool = False, ) -> None: self.aws_secret_key = aws_secret_key self.aws_access_key = aws_access_key self.aws_region = _infer_region() if aws_region is None else aws_region self.aws_profile = aws_profile self.aws_session_token = aws_session_token if base_url is None: base_url = os.environ.get("ANTHROPIC_BEDROCK_BASE_URL") if base_url is None: base_url = f"https://bedrock-runtime.{self.aws_region}.amazonaws.com" super().__init__( version=__version__, base_url=base_url, timeout=timeout, max_retries=max_retries, custom_headers=default_headers, custom_query=default_query, http_client=http_client, _strict_response_validation=_strict_response_validation, ) self.messages = AsyncMessages(self) self.completions = AsyncCompletions(self) self.beta = AsyncBeta(self) @override def _make_sse_decoder(self) -> AWSEventStreamDecoder: return AWSEventStreamDecoder() @override async def _prepare_options(self, options: FinalRequestOptions) -> FinalRequestOptions: return _prepare_options(options) @override async def _prepare_request(self, request: httpx.Request) -> None: from ._auth import get_auth_headers data = request.read().decode() headers = get_auth_headers( method=request.method, url=str(request.url), headers=request.headers, aws_access_key=self.aws_access_key, aws_secret_key=self.aws_secret_key, aws_session_token=self.aws_session_token, region=self.aws_region or "us-east-1", profile=self.aws_profile, data=data, ) request.headers.update(headers) def copy( self, *, aws_secret_key: str | None = None, aws_access_key: str | None = None, aws_region: str | None = None, aws_session_token: str | None = None, base_url: str | httpx.URL | None = None, timeout: float | Timeout | None | NotGiven = NOT_GIVEN, http_client: httpx.AsyncClient | None = None, max_retries: int | NotGiven = NOT_GIVEN, default_headers: Mapping[str, str] | None = None, set_default_headers: Mapping[str, str] | None = None, default_query: Mapping[str, object] | None = None, set_default_query: Mapping[str, object] | None = None, _extra_kwargs: Mapping[str, Any] = {}, ) -> Self: """ Create a new client instance re-using the same options given to the current client with optional overriding. """ if default_headers is not None and set_default_headers is not None: raise ValueError("The `default_headers` and `set_default_headers` arguments are mutually exclusive") if default_query is not None and set_default_query is not None: raise ValueError("The `default_query` and `set_default_query` arguments are mutually exclusive") headers = self._custom_headers if default_headers is not None: headers = {**headers, **default_headers} elif set_default_headers is not None: headers = set_default_headers params = self._custom_query if default_query is not None: params = {**params, **default_query} elif set_default_query is not None: params = set_default_query return self.__class__( aws_secret_key=aws_secret_key or self.aws_secret_key, aws_access_key=aws_access_key or self.aws_access_key, aws_region=aws_region or self.aws_region, aws_session_token=aws_session_token or self.aws_session_token, base_url=base_url or self.base_url, timeout=self.timeout if isinstance(timeout, NotGiven) else timeout, http_client=http_client, max_retries=max_retries if is_given(max_retries) else self.max_retries, default_headers=headers, default_query=params, **_extra_kwargs, ) # Alias for `copy` for nicer inline usage, e.g. # client.with_options(timeout=10).foo.create(...) with_options = copy anthropic-sdk-python-0.69.0/src/anthropic/lib/bedrock/_stream.py000066400000000000000000000015471506653454500246600ustar00rootroot00000000000000from __future__ import annotations from typing import TypeVar import httpx from ..._client import Anthropic, AsyncAnthropic from ..._streaming import Stream, AsyncStream from ._stream_decoder import AWSEventStreamDecoder _T = TypeVar("_T") class BedrockStream(Stream[_T]): def __init__( self, *, cast_to: type[_T], response: httpx.Response, client: Anthropic, ) -> None: super().__init__(cast_to=cast_to, response=response, client=client) self._decoder = AWSEventStreamDecoder() class AsyncBedrockStream(AsyncStream[_T]): def __init__( self, *, cast_to: type[_T], response: httpx.Response, client: AsyncAnthropic, ) -> None: super().__init__(cast_to=cast_to, response=response, client=client) self._decoder = AWSEventStreamDecoder() anthropic-sdk-python-0.69.0/src/anthropic/lib/bedrock/_stream_decoder.py000066400000000000000000000047671506653454500263540ustar00rootroot00000000000000from __future__ import annotations from typing import TYPE_CHECKING, Iterator, AsyncIterator from ..._utils import lru_cache from ..._streaming import ServerSentEvent if TYPE_CHECKING: from botocore.model import Shape from botocore.eventstream import EventStreamMessage @lru_cache(maxsize=None) def get_response_stream_shape() -> Shape: from botocore.model import ServiceModel from botocore.loaders import Loader loader = Loader() bedrock_service_dict = loader.load_service_model("bedrock-runtime", "service-2") bedrock_service_model = ServiceModel(bedrock_service_dict) return bedrock_service_model.shape_for("ResponseStream") class AWSEventStreamDecoder: def __init__(self) -> None: from botocore.parsers import EventStreamJSONParser self.parser = EventStreamJSONParser() def iter_bytes(self, iterator: Iterator[bytes]) -> Iterator[ServerSentEvent]: """Given an iterator that yields lines, iterate over it & yield every event encountered""" from botocore.eventstream import EventStreamBuffer event_stream_buffer = EventStreamBuffer() for chunk in iterator: event_stream_buffer.add_data(chunk) for event in event_stream_buffer: message = self._parse_message_from_event(event) if message: yield ServerSentEvent(data=message, event="completion") async def aiter_bytes(self, iterator: AsyncIterator[bytes]) -> AsyncIterator[ServerSentEvent]: """Given an async iterator that yields lines, iterate over it & yield every event encountered""" from botocore.eventstream import EventStreamBuffer event_stream_buffer = EventStreamBuffer() async for chunk in iterator: event_stream_buffer.add_data(chunk) for event in event_stream_buffer: message = self._parse_message_from_event(event) if message: yield ServerSentEvent(data=message, event="completion") def _parse_message_from_event(self, event: EventStreamMessage) -> str | None: response_dict = event.to_response_dict() parsed_response = self.parser.parse(response_dict, get_response_stream_shape()) if response_dict["status_code"] != 200: raise ValueError(f"Bad response code, expected 200: {response_dict}") chunk = parsed_response.get("chunk") if not chunk: return None return chunk.get("bytes").decode() # type: ignore[no-any-return] anthropic-sdk-python-0.69.0/src/anthropic/lib/streaming/000077500000000000000000000000001506653454500232255ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/lib/streaming/__init__.py000066400000000000000000000017241506653454500253420ustar00rootroot00000000000000from ._types import ( TextEvent as TextEvent, InputJsonEvent as InputJsonEvent, MessageStopEvent as MessageStopEvent, MessageStreamEvent as MessageStreamEvent, ContentBlockStopEvent as ContentBlockStopEvent, ) from ._messages import ( MessageStream as MessageStream, AsyncMessageStream as AsyncMessageStream, MessageStreamManager as MessageStreamManager, AsyncMessageStreamManager as AsyncMessageStreamManager, ) from ._beta_types import ( BetaTextEvent as BetaTextEvent, BetaInputJsonEvent as BetaInputJsonEvent, BetaMessageStopEvent as BetaMessageStopEvent, BetaMessageStreamEvent as BetaMessageStreamEvent, BetaContentBlockStopEvent as BetaContentBlockStopEvent, ) from ._beta_messages import ( BetaMessageStream as BetaMessageStream, BetaAsyncMessageStream as BetaAsyncMessageStream, BetaMessageStreamManager as BetaMessageStreamManager, BetaAsyncMessageStreamManager as BetaAsyncMessageStreamManager, ) anthropic-sdk-python-0.69.0/src/anthropic/lib/streaming/_beta_messages.py000066400000000000000000000436321506653454500265500ustar00rootroot00000000000000from __future__ import annotations from types import TracebackType from typing import TYPE_CHECKING, Any, Type, Callable, cast from typing_extensions import Self, Iterator, Awaitable, AsyncIterator, assert_never import httpx from pydantic import BaseModel from anthropic.types.beta.beta_tool_use_block import BetaToolUseBlock from anthropic.types.beta.beta_mcp_tool_use_block import BetaMCPToolUseBlock from anthropic.types.beta.beta_server_tool_use_block import BetaServerToolUseBlock from ..._utils import consume_sync_iterator, consume_async_iterator from ..._models import build, construct_type, construct_type_unchecked from ._beta_types import ( BetaTextEvent, BetaCitationEvent, BetaThinkingEvent, BetaInputJsonEvent, BetaSignatureEvent, BetaMessageStopEvent, BetaMessageStreamEvent, BetaContentBlockStopEvent, ) from ..._streaming import Stream, AsyncStream from ...types.beta import BetaMessage, BetaContentBlock, BetaRawMessageStreamEvent class BetaMessageStream: text_stream: Iterator[str] """Iterator over just the text deltas in the stream. ```py for text in stream.text_stream: print(text, end="", flush=True) print() ``` """ def __init__(self, raw_stream: Stream[BetaRawMessageStreamEvent]) -> None: self._raw_stream = raw_stream self.text_stream = self.__stream_text__() self._iterator = self.__stream__() self.__final_message_snapshot: BetaMessage | None = None @property def response(self) -> httpx.Response: return self._raw_stream.response @property def request_id(self) -> str | None: return self.response.headers.get("request-id") # type: ignore[no-any-return] def __next__(self) -> BetaMessageStreamEvent: return self._iterator.__next__() def __iter__(self) -> Iterator[BetaMessageStreamEvent]: for item in self._iterator: yield item def __enter__(self) -> Self: return self def __exit__( self, exc_type: type[BaseException] | None, exc: BaseException | None, exc_tb: TracebackType | None, ) -> None: self.close() def close(self) -> None: """ Close the response and release the connection. Automatically called if the response body is read to completion. """ self._raw_stream.close() def get_final_message(self) -> BetaMessage: """Waits until the stream has been read to completion and returns the accumulated `Message` object. """ self.until_done() assert self.__final_message_snapshot is not None return self.__final_message_snapshot def get_final_text(self) -> str: """Returns all `text` content blocks concatenated together. > [!NOTE] > Currently the API will only respond with a single content block. Will raise an error if no `text` content blocks were returned. """ message = self.get_final_message() text_blocks: list[str] = [] for block in message.content: if block.type == "text": text_blocks.append(block.text) if not text_blocks: raise RuntimeError( f".get_final_text() can only be called when the API returns a `text` content block.\nThe API returned {','.join([b.type for b in message.content])} content block type(s) that you can access by calling get_final_message().content" ) return "".join(text_blocks) def until_done(self) -> None: """Blocks until the stream has been consumed""" consume_sync_iterator(self) # properties @property def current_message_snapshot(self) -> BetaMessage: assert self.__final_message_snapshot is not None return self.__final_message_snapshot def __stream__(self) -> Iterator[BetaMessageStreamEvent]: for sse_event in self._raw_stream: self.__final_message_snapshot = accumulate_event( event=sse_event, current_snapshot=self.__final_message_snapshot, request_headers=self.response.request.headers, ) events_to_fire = build_events(event=sse_event, message_snapshot=self.current_message_snapshot) for event in events_to_fire: yield event def __stream_text__(self) -> Iterator[str]: for chunk in self: if chunk.type == "content_block_delta" and chunk.delta.type == "text_delta": yield chunk.delta.text class BetaMessageStreamManager: """Wrapper over MessageStream that is returned by `.stream()`. ```py with client.beta.messages.stream(...) as stream: for chunk in stream: ... ``` """ def __init__( self, api_request: Callable[[], Stream[BetaRawMessageStreamEvent]], ) -> None: self.__stream: BetaMessageStream | None = None self.__api_request = api_request def __enter__(self) -> BetaMessageStream: raw_stream = self.__api_request() self.__stream = BetaMessageStream(raw_stream) return self.__stream def __exit__( self, exc_type: type[BaseException] | None, exc: BaseException | None, exc_tb: TracebackType | None, ) -> None: if self.__stream is not None: self.__stream.close() class BetaAsyncMessageStream: text_stream: AsyncIterator[str] """Async iterator over just the text deltas in the stream. ```py async for text in stream.text_stream: print(text, end="", flush=True) print() ``` """ def __init__(self, raw_stream: AsyncStream[BetaRawMessageStreamEvent]) -> None: self._raw_stream = raw_stream self.text_stream = self.__stream_text__() self._iterator = self.__stream__() self.__final_message_snapshot: BetaMessage | None = None @property def response(self) -> httpx.Response: return self._raw_stream.response @property def request_id(self) -> str | None: return self.response.headers.get("request-id") # type: ignore[no-any-return] async def __anext__(self) -> BetaMessageStreamEvent: return await self._iterator.__anext__() async def __aiter__(self) -> AsyncIterator[BetaMessageStreamEvent]: async for item in self._iterator: yield item async def __aenter__(self) -> Self: return self async def __aexit__( self, exc_type: type[BaseException] | None, exc: BaseException | None, exc_tb: TracebackType | None, ) -> None: await self.close() async def close(self) -> None: """ Close the response and release the connection. Automatically called if the response body is read to completion. """ await self._raw_stream.close() async def get_final_message(self) -> BetaMessage: """Waits until the stream has been read to completion and returns the accumulated `Message` object. """ await self.until_done() assert self.__final_message_snapshot is not None return self.__final_message_snapshot async def get_final_text(self) -> str: """Returns all `text` content blocks concatenated together. > [!NOTE] > Currently the API will only respond with a single content block. Will raise an error if no `text` content blocks were returned. """ message = await self.get_final_message() text_blocks: list[str] = [] for block in message.content: if block.type == "text": text_blocks.append(block.text) if not text_blocks: raise RuntimeError( f".get_final_text() can only be called when the API returns a `text` content block.\nThe API returned {','.join([b.type for b in message.content])} content block type(s) that you can access by calling get_final_message().content" ) return "".join(text_blocks) async def until_done(self) -> None: """Waits until the stream has been consumed""" await consume_async_iterator(self) # properties @property def current_message_snapshot(self) -> BetaMessage: assert self.__final_message_snapshot is not None return self.__final_message_snapshot async def __stream__(self) -> AsyncIterator[BetaMessageStreamEvent]: async for sse_event in self._raw_stream: self.__final_message_snapshot = accumulate_event( event=sse_event, current_snapshot=self.__final_message_snapshot, request_headers=self.response.request.headers, ) events_to_fire = build_events(event=sse_event, message_snapshot=self.current_message_snapshot) for event in events_to_fire: yield event async def __stream_text__(self) -> AsyncIterator[str]: async for chunk in self: if chunk.type == "content_block_delta" and chunk.delta.type == "text_delta": yield chunk.delta.text class BetaAsyncMessageStreamManager: """Wrapper over BetaAsyncMessageStream that is returned by `.stream()` so that an async context manager can be used without `await`ing the original client call. ```py async with client.beta.messages.stream(...) as stream: async for chunk in stream: ... ``` """ def __init__( self, api_request: Awaitable[AsyncStream[BetaRawMessageStreamEvent]], ) -> None: self.__stream: BetaAsyncMessageStream | None = None self.__api_request = api_request async def __aenter__(self) -> BetaAsyncMessageStream: raw_stream = await self.__api_request self.__stream = BetaAsyncMessageStream(raw_stream) return self.__stream async def __aexit__( self, exc_type: type[BaseException] | None, exc: BaseException | None, exc_tb: TracebackType | None, ) -> None: if self.__stream is not None: await self.__stream.close() def build_events( *, event: BetaRawMessageStreamEvent, message_snapshot: BetaMessage, ) -> list[BetaMessageStreamEvent]: events_to_fire: list[BetaMessageStreamEvent] = [] if event.type == "message_start": events_to_fire.append(event) elif event.type == "message_delta": events_to_fire.append(event) elif event.type == "message_stop": events_to_fire.append(build(BetaMessageStopEvent, type="message_stop", message=message_snapshot)) elif event.type == "content_block_start": events_to_fire.append(event) elif event.type == "content_block_delta": events_to_fire.append(event) content_block = message_snapshot.content[event.index] if event.delta.type == "text_delta": if content_block.type == "text": events_to_fire.append( build( BetaTextEvent, type="text", text=event.delta.text, snapshot=content_block.text, ) ) elif event.delta.type == "input_json_delta": if content_block.type == "tool_use" or content_block.type == "mcp_tool_use": events_to_fire.append( build( BetaInputJsonEvent, type="input_json", partial_json=event.delta.partial_json, snapshot=content_block.input, ) ) elif event.delta.type == "citations_delta": if content_block.type == "text": events_to_fire.append( build( BetaCitationEvent, type="citation", citation=event.delta.citation, snapshot=content_block.citations or [], ) ) elif event.delta.type == "thinking_delta": if content_block.type == "thinking": events_to_fire.append( build( BetaThinkingEvent, type="thinking", thinking=event.delta.thinking, snapshot=content_block.thinking, ) ) elif event.delta.type == "signature_delta": if content_block.type == "thinking": events_to_fire.append( build( BetaSignatureEvent, type="signature", signature=content_block.signature, ) ) pass else: # we only want exhaustive checking for linters, not at runtime if TYPE_CHECKING: # type: ignore[unreachable] assert_never(event.delta) elif event.type == "content_block_stop": content_block = message_snapshot.content[event.index] events_to_fire.append( build(BetaContentBlockStopEvent, type="content_block_stop", index=event.index, content_block=content_block), ) else: # we only want exhaustive checking for linters, not at runtime if TYPE_CHECKING: # type: ignore[unreachable] assert_never(event) return events_to_fire JSON_BUF_PROPERTY = "__json_buf" TRACKS_TOOL_INPUT = ( BetaToolUseBlock, BetaServerToolUseBlock, BetaMCPToolUseBlock, ) def accumulate_event( *, event: BetaRawMessageStreamEvent, current_snapshot: BetaMessage | None, request_headers: httpx.Headers, ) -> BetaMessage: if not isinstance(cast(Any, event), BaseModel): event = cast( # pyright: ignore[reportUnnecessaryCast] BetaRawMessageStreamEvent, construct_type_unchecked( type_=cast(Type[BetaRawMessageStreamEvent], BetaRawMessageStreamEvent), value=event, ), ) if not isinstance(cast(Any, event), BaseModel): raise TypeError(f"Unexpected event runtime type, after deserialising twice - {event} - {type(event)}") if current_snapshot is None: if event.type == "message_start": return BetaMessage.construct(**cast(Any, event.message.to_dict())) raise RuntimeError(f'Unexpected event order, got {event.type} before "message_start"') if event.type == "content_block_start": # TODO: check index current_snapshot.content.append( cast( BetaContentBlock, construct_type(type_=BetaContentBlock, value=event.content_block.model_dump()), ), ) elif event.type == "content_block_delta": content = current_snapshot.content[event.index] if event.delta.type == "text_delta": if content.type == "text": content.text += event.delta.text elif event.delta.type == "input_json_delta": if isinstance(content, TRACKS_TOOL_INPUT): from jiter import from_json # we need to keep track of the raw JSON string as well so that we can # re-parse it for each delta, for now we just store it as an untyped # property on the snapshot json_buf = cast(bytes, getattr(content, JSON_BUF_PROPERTY, b"")) json_buf += bytes(event.delta.partial_json, "utf-8") if json_buf: try: anthropic_beta = request_headers.get("anthropic-beta", "") if request_headers else "" if "fine-grained-tool-streaming-2025-05-14" in anthropic_beta: content.input = from_json(json_buf, partial_mode="trailing-strings") else: content.input = from_json(json_buf, partial_mode=True) except ValueError as e: raise ValueError( f"Unable to parse tool parameter JSON from model. Please retry your request or adjust your prompt. Error: {e}. JSON: {json_buf.decode('utf-8')}" ) from e setattr(content, JSON_BUF_PROPERTY, json_buf) elif event.delta.type == "citations_delta": if content.type == "text": if not content.citations: content.citations = [event.delta.citation] else: content.citations.append(event.delta.citation) elif event.delta.type == "thinking_delta": if content.type == "thinking": content.thinking += event.delta.thinking elif event.delta.type == "signature_delta": if content.type == "thinking": content.signature = event.delta.signature else: # we only want exhaustive checking for linters, not at runtime if TYPE_CHECKING: # type: ignore[unreachable] assert_never(event.delta) elif event.type == "message_delta": current_snapshot.container = event.delta.container current_snapshot.stop_reason = event.delta.stop_reason current_snapshot.stop_sequence = event.delta.stop_sequence current_snapshot.usage.output_tokens = event.usage.output_tokens current_snapshot.context_management = event.context_management # Update other usage fields if they exist in the event if event.usage.input_tokens is not None: current_snapshot.usage.input_tokens = event.usage.input_tokens if event.usage.cache_creation_input_tokens is not None: current_snapshot.usage.cache_creation_input_tokens = event.usage.cache_creation_input_tokens if event.usage.cache_read_input_tokens is not None: current_snapshot.usage.cache_read_input_tokens = event.usage.cache_read_input_tokens if event.usage.server_tool_use is not None: current_snapshot.usage.server_tool_use = event.usage.server_tool_use return current_snapshot anthropic-sdk-python-0.69.0/src/anthropic/lib/streaming/_beta_types.py000066400000000000000000000041231506653454500260750ustar00rootroot00000000000000from typing import Union from typing_extensions import List, Literal, Annotated from ..._models import BaseModel from ...types.beta import ( BetaMessage, BetaContentBlock, BetaRawMessageStopEvent, BetaRawMessageDeltaEvent, BetaRawMessageStartEvent, BetaRawContentBlockStopEvent, BetaRawContentBlockDeltaEvent, BetaRawContentBlockStartEvent, ) from ..._utils._transform import PropertyInfo from ...types.beta.beta_citations_delta import Citation class BetaTextEvent(BaseModel): type: Literal["text"] text: str """The text delta""" snapshot: str """The entire accumulated text""" class BetaCitationEvent(BaseModel): type: Literal["citation"] citation: Citation """The new citation""" snapshot: List[Citation] """All of the accumulated citations""" class BetaThinkingEvent(BaseModel): type: Literal["thinking"] thinking: str """The thinking delta""" snapshot: str """The accumulated thinking so far""" class BetaSignatureEvent(BaseModel): type: Literal["signature"] signature: str """The signature of the thinking block""" class BetaInputJsonEvent(BaseModel): type: Literal["input_json"] partial_json: str """A partial JSON string delta e.g. `'"San Francisco,'` """ snapshot: object """The currently accumulated parsed object. e.g. `{'location': 'San Francisco, CA'}` """ class BetaMessageStopEvent(BetaRawMessageStopEvent): type: Literal["message_stop"] message: BetaMessage class BetaContentBlockStopEvent(BetaRawContentBlockStopEvent): type: Literal["content_block_stop"] content_block: BetaContentBlock BetaMessageStreamEvent = Annotated[ Union[ BetaTextEvent, BetaCitationEvent, BetaThinkingEvent, BetaSignatureEvent, BetaInputJsonEvent, BetaRawMessageStartEvent, BetaRawMessageDeltaEvent, BetaMessageStopEvent, BetaRawContentBlockStartEvent, BetaRawContentBlockDeltaEvent, BetaContentBlockStopEvent, ], PropertyInfo(discriminator="type"), ] anthropic-sdk-python-0.69.0/src/anthropic/lib/streaming/_messages.py000066400000000000000000000410761506653454500255550ustar00rootroot00000000000000from __future__ import annotations from types import TracebackType from typing import TYPE_CHECKING, Any, Type, Callable, cast from typing_extensions import Self, Iterator, Awaitable, AsyncIterator, assert_never import httpx from pydantic import BaseModel from anthropic.types.tool_use_block import ToolUseBlock from anthropic.types.server_tool_use_block import ServerToolUseBlock from ._types import ( TextEvent, CitationEvent, ThinkingEvent, InputJsonEvent, SignatureEvent, MessageStopEvent, MessageStreamEvent, ContentBlockStopEvent, ) from ...types import Message, ContentBlock, RawMessageStreamEvent from ..._utils import consume_sync_iterator, consume_async_iterator from ..._models import build, construct_type, construct_type_unchecked from ..._streaming import Stream, AsyncStream class MessageStream: text_stream: Iterator[str] """Iterator over just the text deltas in the stream. ```py for text in stream.text_stream: print(text, end="", flush=True) print() ``` """ def __init__(self, raw_stream: Stream[RawMessageStreamEvent]) -> None: self._raw_stream = raw_stream self.text_stream = self.__stream_text__() self._iterator = self.__stream__() self.__final_message_snapshot: Message | None = None @property def response(self) -> httpx.Response: return self._raw_stream.response @property def request_id(self) -> str | None: return self.response.headers.get("request-id") # type: ignore[no-any-return] def __next__(self) -> MessageStreamEvent: return self._iterator.__next__() def __iter__(self) -> Iterator[MessageStreamEvent]: for item in self._iterator: yield item def __enter__(self) -> Self: return self def __exit__( self, exc_type: type[BaseException] | None, exc: BaseException | None, exc_tb: TracebackType | None, ) -> None: self.close() def close(self) -> None: """ Close the response and release the connection. Automatically called if the response body is read to completion. """ self._raw_stream.close() def get_final_message(self) -> Message: """Waits until the stream has been read to completion and returns the accumulated `Message` object. """ self.until_done() assert self.__final_message_snapshot is not None return self.__final_message_snapshot def get_final_text(self) -> str: """Returns all `text` content blocks concatenated together. > [!NOTE] > Currently the API will only respond with a single content block. Will raise an error if no `text` content blocks were returned. """ message = self.get_final_message() text_blocks: list[str] = [] for block in message.content: if block.type == "text": text_blocks.append(block.text) if not text_blocks: raise RuntimeError( f".get_final_text() can only be called when the API returns a `text` content block.\nThe API returned {','.join([b.type for b in message.content])} content block type(s) that you can access by calling get_final_message().content" ) return "".join(text_blocks) def until_done(self) -> None: """Blocks until the stream has been consumed""" consume_sync_iterator(self) # properties @property def current_message_snapshot(self) -> Message: assert self.__final_message_snapshot is not None return self.__final_message_snapshot def __stream__(self) -> Iterator[MessageStreamEvent]: for sse_event in self._raw_stream: self.__final_message_snapshot = accumulate_event( event=sse_event, current_snapshot=self.__final_message_snapshot, ) events_to_fire = build_events(event=sse_event, message_snapshot=self.current_message_snapshot) for event in events_to_fire: yield event def __stream_text__(self) -> Iterator[str]: for chunk in self: if chunk.type == "content_block_delta" and chunk.delta.type == "text_delta": yield chunk.delta.text class MessageStreamManager: """Wrapper over MessageStream that is returned by `.stream()`. ```py with client.messages.stream(...) as stream: for chunk in stream: ... ``` """ def __init__( self, api_request: Callable[[], Stream[RawMessageStreamEvent]], ) -> None: self.__stream: MessageStream | None = None self.__api_request = api_request def __enter__(self) -> MessageStream: raw_stream = self.__api_request() self.__stream = MessageStream(raw_stream) return self.__stream def __exit__( self, exc_type: type[BaseException] | None, exc: BaseException | None, exc_tb: TracebackType | None, ) -> None: if self.__stream is not None: self.__stream.close() class AsyncMessageStream: text_stream: AsyncIterator[str] """Async iterator over just the text deltas in the stream. ```py async for text in stream.text_stream: print(text, end="", flush=True) print() ``` """ def __init__(self, raw_stream: AsyncStream[RawMessageStreamEvent]) -> None: self._raw_stream = raw_stream self.text_stream = self.__stream_text__() self._iterator = self.__stream__() self.__final_message_snapshot: Message | None = None @property def response(self) -> httpx.Response: return self._raw_stream.response @property def request_id(self) -> str | None: return self.response.headers.get("request-id") # type: ignore[no-any-return] async def __anext__(self) -> MessageStreamEvent: return await self._iterator.__anext__() async def __aiter__(self) -> AsyncIterator[MessageStreamEvent]: async for item in self._iterator: yield item async def __aenter__(self) -> Self: return self async def __aexit__( self, exc_type: type[BaseException] | None, exc: BaseException | None, exc_tb: TracebackType | None, ) -> None: await self.close() async def close(self) -> None: """ Close the response and release the connection. Automatically called if the response body is read to completion. """ await self._raw_stream.close() async def get_final_message(self) -> Message: """Waits until the stream has been read to completion and returns the accumulated `Message` object. """ await self.until_done() assert self.__final_message_snapshot is not None return self.__final_message_snapshot async def get_final_text(self) -> str: """Returns all `text` content blocks concatenated together. > [!NOTE] > Currently the API will only respond with a single content block. Will raise an error if no `text` content blocks were returned. """ message = await self.get_final_message() text_blocks: list[str] = [] for block in message.content: if block.type == "text": text_blocks.append(block.text) if not text_blocks: raise RuntimeError( f".get_final_text() can only be called when the API returns a `text` content block.\nThe API returned {','.join([b.type for b in message.content])} content block type(s) that you can access by calling get_final_message().content" ) return "".join(text_blocks) async def until_done(self) -> None: """Waits until the stream has been consumed""" await consume_async_iterator(self) # properties @property def current_message_snapshot(self) -> Message: assert self.__final_message_snapshot is not None return self.__final_message_snapshot async def __stream__(self) -> AsyncIterator[MessageStreamEvent]: async for sse_event in self._raw_stream: self.__final_message_snapshot = accumulate_event( event=sse_event, current_snapshot=self.__final_message_snapshot, ) events_to_fire = build_events(event=sse_event, message_snapshot=self.current_message_snapshot) for event in events_to_fire: yield event async def __stream_text__(self) -> AsyncIterator[str]: async for chunk in self: if chunk.type == "content_block_delta" and chunk.delta.type == "text_delta": yield chunk.delta.text class AsyncMessageStreamManager: """Wrapper over AsyncMessageStream that is returned by `.stream()` so that an async context manager can be used without `await`ing the original client call. ```py async with client.messages.stream(...) as stream: async for chunk in stream: ... ``` """ def __init__( self, api_request: Awaitable[AsyncStream[RawMessageStreamEvent]], ) -> None: self.__stream: AsyncMessageStream | None = None self.__api_request = api_request async def __aenter__(self) -> AsyncMessageStream: raw_stream = await self.__api_request self.__stream = AsyncMessageStream(raw_stream) return self.__stream async def __aexit__( self, exc_type: type[BaseException] | None, exc: BaseException | None, exc_tb: TracebackType | None, ) -> None: if self.__stream is not None: await self.__stream.close() def build_events( *, event: RawMessageStreamEvent, message_snapshot: Message, ) -> list[MessageStreamEvent]: events_to_fire: list[MessageStreamEvent] = [] if event.type == "message_start": events_to_fire.append(event) elif event.type == "message_delta": events_to_fire.append(event) elif event.type == "message_stop": events_to_fire.append(build(MessageStopEvent, type="message_stop", message=message_snapshot)) elif event.type == "content_block_start": events_to_fire.append(event) elif event.type == "content_block_delta": events_to_fire.append(event) content_block = message_snapshot.content[event.index] if event.delta.type == "text_delta": if content_block.type == "text": events_to_fire.append( build( TextEvent, type="text", text=event.delta.text, snapshot=content_block.text, ) ) elif event.delta.type == "input_json_delta": if content_block.type == "tool_use": events_to_fire.append( build( InputJsonEvent, type="input_json", partial_json=event.delta.partial_json, snapshot=content_block.input, ) ) elif event.delta.type == "citations_delta": if content_block.type == "text": events_to_fire.append( build( CitationEvent, type="citation", citation=event.delta.citation, snapshot=content_block.citations or [], ) ) elif event.delta.type == "thinking_delta": if content_block.type == "thinking": events_to_fire.append( build( ThinkingEvent, type="thinking", thinking=event.delta.thinking, snapshot=content_block.thinking, ) ) elif event.delta.type == "signature_delta": if content_block.type == "thinking": events_to_fire.append( build( SignatureEvent, type="signature", signature=content_block.signature, ) ) pass else: # we only want exhaustive checking for linters, not at runtime if TYPE_CHECKING: # type: ignore[unreachable] assert_never(event.delta) elif event.type == "content_block_stop": content_block = message_snapshot.content[event.index] events_to_fire.append( build(ContentBlockStopEvent, type="content_block_stop", index=event.index, content_block=content_block), ) else: # we only want exhaustive checking for linters, not at runtime if TYPE_CHECKING: # type: ignore[unreachable] assert_never(event) return events_to_fire JSON_BUF_PROPERTY = "__json_buf" TRACKS_TOOL_INPUT = ( ToolUseBlock, ServerToolUseBlock, ) def accumulate_event( *, event: RawMessageStreamEvent, current_snapshot: Message | None, ) -> Message: if not isinstance(cast(Any, event), BaseModel): event = cast( # pyright: ignore[reportUnnecessaryCast] RawMessageStreamEvent, construct_type_unchecked( type_=cast(Type[RawMessageStreamEvent], RawMessageStreamEvent), value=event, ), ) if not isinstance(cast(Any, event), BaseModel): raise TypeError(f"Unexpected event runtime type, after deserialising twice - {event} - {type(event)}") if current_snapshot is None: if event.type == "message_start": return Message.construct(**cast(Any, event.message.to_dict())) raise RuntimeError(f'Unexpected event order, got {event.type} before "message_start"') if event.type == "content_block_start": # TODO: check index current_snapshot.content.append( cast( ContentBlock, construct_type(type_=ContentBlock, value=event.content_block.model_dump()), ), ) elif event.type == "content_block_delta": content = current_snapshot.content[event.index] if event.delta.type == "text_delta": if content.type == "text": content.text += event.delta.text elif event.delta.type == "input_json_delta": if isinstance(content, TRACKS_TOOL_INPUT): from jiter import from_json # we need to keep track of the raw JSON string as well so that we can # re-parse it for each delta, for now we just store it as an untyped # property on the snapshot json_buf = cast(bytes, getattr(content, JSON_BUF_PROPERTY, b"")) json_buf += bytes(event.delta.partial_json, "utf-8") if json_buf: content.input = from_json(json_buf, partial_mode=True) setattr(content, JSON_BUF_PROPERTY, json_buf) elif event.delta.type == "citations_delta": if content.type == "text": if not content.citations: content.citations = [event.delta.citation] else: content.citations.append(event.delta.citation) elif event.delta.type == "thinking_delta": if content.type == "thinking": content.thinking += event.delta.thinking elif event.delta.type == "signature_delta": if content.type == "thinking": content.signature = event.delta.signature else: # we only want exhaustive checking for linters, not at runtime if TYPE_CHECKING: # type: ignore[unreachable] assert_never(event.delta) elif event.type == "message_delta": current_snapshot.stop_reason = event.delta.stop_reason current_snapshot.stop_sequence = event.delta.stop_sequence current_snapshot.usage.output_tokens = event.usage.output_tokens # Update other usage fields if they exist in the event if event.usage.input_tokens is not None: current_snapshot.usage.input_tokens = event.usage.input_tokens if event.usage.cache_creation_input_tokens is not None: current_snapshot.usage.cache_creation_input_tokens = event.usage.cache_creation_input_tokens if event.usage.cache_read_input_tokens is not None: current_snapshot.usage.cache_read_input_tokens = event.usage.cache_read_input_tokens if event.usage.server_tool_use is not None: current_snapshot.usage.server_tool_use = event.usage.server_tool_use return current_snapshot anthropic-sdk-python-0.69.0/src/anthropic/lib/streaming/_types.py000066400000000000000000000040461506653454500251060ustar00rootroot00000000000000from typing import Union from typing_extensions import List, Literal, Annotated from ...types import ( Message, ContentBlock, MessageDeltaEvent as RawMessageDeltaEvent, MessageStartEvent as RawMessageStartEvent, RawMessageStopEvent, ContentBlockDeltaEvent as RawContentBlockDeltaEvent, ContentBlockStartEvent as RawContentBlockStartEvent, RawContentBlockStopEvent, ) from ..._models import BaseModel from ..._utils._transform import PropertyInfo from ...types.citations_delta import Citation class TextEvent(BaseModel): type: Literal["text"] text: str """The text delta""" snapshot: str """The entire accumulated text""" class CitationEvent(BaseModel): type: Literal["citation"] citation: Citation """The new citation""" snapshot: List[Citation] """All of the accumulated citations""" class ThinkingEvent(BaseModel): type: Literal["thinking"] thinking: str """The thinking delta""" snapshot: str """The accumulated thinking so far""" class SignatureEvent(BaseModel): type: Literal["signature"] signature: str """The signature of the thinking block""" class InputJsonEvent(BaseModel): type: Literal["input_json"] partial_json: str """A partial JSON string delta e.g. `'"San Francisco,'` """ snapshot: object """The currently accumulated parsed object. e.g. `{'location': 'San Francisco, CA'}` """ class MessageStopEvent(RawMessageStopEvent): type: Literal["message_stop"] message: Message class ContentBlockStopEvent(RawContentBlockStopEvent): type: Literal["content_block_stop"] content_block: ContentBlock MessageStreamEvent = Annotated[ Union[ TextEvent, CitationEvent, ThinkingEvent, SignatureEvent, InputJsonEvent, RawMessageStartEvent, RawMessageDeltaEvent, MessageStopEvent, RawContentBlockStartEvent, RawContentBlockDeltaEvent, ContentBlockStopEvent, ], PropertyInfo(discriminator="type"), ] anthropic-sdk-python-0.69.0/src/anthropic/lib/tools/000077500000000000000000000000001506653454500223745ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/lib/tools/__init__.py000066400000000000000000000014531506653454500245100ustar00rootroot00000000000000from ._beta_runner import BetaToolRunner, BetaAsyncToolRunner, BetaStreamingToolRunner, BetaAsyncStreamingToolRunner from ._beta_functions import ( BetaFunctionTool, BetaAsyncFunctionTool, BetaBuiltinFunctionTool, BetaFunctionToolResultType, BetaAsyncBuiltinFunctionTool, beta_tool, beta_async_tool, ) from ._beta_builtin_memory_tool import BetaAbstractMemoryTool, BetaAsyncAbstractMemoryTool __all__ = [ "beta_tool", "beta_async_tool", "BetaFunctionTool", "BetaAsyncFunctionTool", "BetaBuiltinFunctionTool", "BetaAsyncBuiltinFunctionTool", "BetaToolRunner", "BetaAsyncStreamingToolRunner", "BetaStreamingToolRunner", "BetaAsyncToolRunner", "BetaFunctionToolResultType", "BetaAbstractMemoryTool", "BetaAsyncAbstractMemoryTool", ] anthropic-sdk-python-0.69.0/src/anthropic/lib/tools/_beta_builtin_memory_tool.py000066400000000000000000000216431506653454500302010ustar00rootroot00000000000000from __future__ import annotations from abc import abstractmethod from typing import TYPE_CHECKING, Any, cast from typing_extensions import override, assert_never from ..._models import construct_type_unchecked from ...types.beta import ( BetaMemoryTool20250818Param, BetaMemoryTool20250818Command, BetaCacheControlEphemeralParam, BetaMemoryTool20250818ViewCommand, BetaMemoryTool20250818CreateCommand, BetaMemoryTool20250818DeleteCommand, BetaMemoryTool20250818InsertCommand, BetaMemoryTool20250818RenameCommand, BetaMemoryTool20250818StrReplaceCommand, ) from ._beta_functions import BetaBuiltinFunctionTool, BetaFunctionToolResultType, BetaAsyncBuiltinFunctionTool class BetaAbstractMemoryTool(BetaBuiltinFunctionTool): """Abstract base class for memory tool implementations. This class provides the interface for implementing a custom memory backend for Claude. Subclass this to create your own memory storage solution (e.g., database, cloud storage, encrypted files, etc.). Example usage: ```py class MyMemoryTool(BetaAbstractMemoryTool): def view(self, command: BetaMemoryTool20250818ViewCommand) -> BetaFunctionToolResultType: ... return "view result" def create(self, command: BetaMemoryTool20250818CreateCommand) -> BetaFunctionToolResultType: ... return "created successfully" # ... implement other abstract methods client = Anthropic() memory_tool = MyMemoryTool() message = client.beta.messages.run_tools( model="claude-sonnet-4-5", messages=[{"role": "user", "content": "Remember that I like coffee"}], tools=[memory_tool], ).until_done() ``` """ def __init__(self, *, cache_control: BetaCacheControlEphemeralParam | None = None) -> None: super().__init__() self._cache_control = cache_control @override def to_dict(self) -> BetaMemoryTool20250818Param: param: BetaMemoryTool20250818Param = {"type": "memory_20250818", "name": "memory"} if self._cache_control is not None: param["cache_control"] = self._cache_control return param @override def call(self, input: object) -> BetaFunctionToolResultType: command = cast( BetaMemoryTool20250818Command, construct_type_unchecked(value=input, type_=cast(Any, BetaMemoryTool20250818Command)), ) return self.execute(command) def execute(self, command: BetaMemoryTool20250818Command) -> BetaFunctionToolResultType: """Execute a memory command and return the result. This method dispatches to the appropriate handler method based on the command type (view, create, str_replace, insert, delete, rename). You typically don't need to override this method. """ if command.command == "view": return self.view(command) elif command.command == "create": return self.create(command) elif command.command == "str_replace": return self.str_replace(command) elif command.command == "insert": return self.insert(command) elif command.command == "delete": return self.delete(command) elif command.command == "rename": return self.rename(command) elif TYPE_CHECKING: # type: ignore[unreachable] assert_never(command) else: raise NotImplementedError(f"Unknown command: {command.command}") @abstractmethod def view(self, command: BetaMemoryTool20250818ViewCommand) -> BetaFunctionToolResultType: """View the contents of a memory path.""" pass @abstractmethod def create(self, command: BetaMemoryTool20250818CreateCommand) -> BetaFunctionToolResultType: """Create a new memory file with the specified content.""" pass @abstractmethod def str_replace(self, command: BetaMemoryTool20250818StrReplaceCommand) -> BetaFunctionToolResultType: """Replace text in a memory file.""" pass @abstractmethod def insert(self, command: BetaMemoryTool20250818InsertCommand) -> BetaFunctionToolResultType: """Insert text at a specific line number in a memory file.""" pass @abstractmethod def delete(self, command: BetaMemoryTool20250818DeleteCommand) -> BetaFunctionToolResultType: """Delete a memory file or directory.""" pass @abstractmethod def rename(self, command: BetaMemoryTool20250818RenameCommand) -> BetaFunctionToolResultType: """Rename or move a memory file or directory.""" pass def clear_all_memory(self) -> BetaFunctionToolResultType: """Clear all memory data.""" raise NotImplementedError("clear_all_memory not implemented") class BetaAsyncAbstractMemoryTool(BetaAsyncBuiltinFunctionTool): """Abstract base class for memory tool implementations. This class provides the interface for implementing a custom memory backend for Claude. Subclass this to create your own memory storage solution (e.g., database, cloud storage, encrypted files, etc.). Example usage: ```py class MyMemoryTool(BetaAbstractMemoryTool): def view(self, command: BetaMemoryTool20250818ViewCommand) -> BetaFunctionToolResultType: ... return "view result" def create(self, command: BetaMemoryTool20250818CreateCommand) -> BetaFunctionToolResultType: ... return "created successfully" # ... implement other abstract methods client = Anthropic() memory_tool = MyMemoryTool() message = client.beta.messages.run_tools( model="claude-3-5-sonnet-20241022", messages=[{"role": "user", "content": "Remember that I like coffee"}], tools=[memory_tool], ).until_done() ``` """ def __init__(self, *, cache_control: BetaCacheControlEphemeralParam | None = None) -> None: super().__init__() self._cache_control = cache_control @override def to_dict(self) -> BetaMemoryTool20250818Param: param: BetaMemoryTool20250818Param = {"type": "memory_20250818", "name": "memory"} if self._cache_control is not None: param["cache_control"] = self._cache_control return param @override async def call(self, input: object) -> BetaFunctionToolResultType: command = cast( BetaMemoryTool20250818Command, construct_type_unchecked(value=input, type_=cast(Any, BetaMemoryTool20250818Command)), ) return await self.execute(command) async def execute(self, command: BetaMemoryTool20250818Command) -> BetaFunctionToolResultType: """Execute a memory command and return the result. This method dispatches to the appropriate handler method based on the command type (view, create, str_replace, insert, delete, rename). You typically don't need to override this method. """ if command.command == "view": return await self.view(command) elif command.command == "create": return await self.create(command) elif command.command == "str_replace": return await self.str_replace(command) elif command.command == "insert": return await self.insert(command) elif command.command == "delete": return await self.delete(command) elif command.command == "rename": return await self.rename(command) elif TYPE_CHECKING: # type: ignore[unreachable] assert_never(command) else: raise NotImplementedError(f"Unknown command: {command.command}") @abstractmethod async def view(self, command: BetaMemoryTool20250818ViewCommand) -> BetaFunctionToolResultType: """View the contents of a memory path.""" pass @abstractmethod async def create(self, command: BetaMemoryTool20250818CreateCommand) -> BetaFunctionToolResultType: """Create a new memory file with the specified content.""" pass @abstractmethod async def str_replace(self, command: BetaMemoryTool20250818StrReplaceCommand) -> BetaFunctionToolResultType: """Replace text in a memory file.""" pass @abstractmethod async def insert(self, command: BetaMemoryTool20250818InsertCommand) -> BetaFunctionToolResultType: """Insert text at a specific line number in a memory file.""" pass @abstractmethod async def delete(self, command: BetaMemoryTool20250818DeleteCommand) -> BetaFunctionToolResultType: """Delete a memory file or directory.""" pass @abstractmethod async def rename(self, command: BetaMemoryTool20250818RenameCommand) -> BetaFunctionToolResultType: """Rename or move a memory file or directory.""" pass async def clear_all_memory(self) -> BetaFunctionToolResultType: """Clear all memory data.""" raise NotImplementedError("clear_all_memory not implemented") anthropic-sdk-python-0.69.0/src/anthropic/lib/tools/_beta_functions.py000066400000000000000000000244631506653454500261210ustar00rootroot00000000000000from __future__ import annotations import logging from abc import ABC, abstractmethod from typing import Any, Union, Generic, TypeVar, Callable, Iterable, Coroutine, cast, overload from inspect import iscoroutinefunction from typing_extensions import TypeAlias, override import pydantic import docstring_parser from pydantic import BaseModel from ... import _compat from ..._utils import is_dict from ..._compat import cached_property from ..._models import TypeAdapter from ...types.beta import BetaToolUnionParam from ..._utils._utils import CallableT from ...types.tool_param import ToolParam, InputSchema from ...types.beta.beta_tool_result_block_param import Content as BetaContent log = logging.getLogger(__name__) BetaFunctionToolResultType: TypeAlias = Union[str, Iterable[BetaContent]] Function = Callable[..., BetaFunctionToolResultType] FunctionT = TypeVar("FunctionT", bound=Function) AsyncFunction = Callable[..., Coroutine[Any, Any, BetaFunctionToolResultType]] AsyncFunctionT = TypeVar("AsyncFunctionT", bound=AsyncFunction) class BetaBuiltinFunctionTool(ABC): @abstractmethod def to_dict(self) -> BetaToolUnionParam: ... @abstractmethod def call(self, input: object) -> BetaFunctionToolResultType: ... @property def name(self) -> str: return self.to_dict()["name"] class BetaAsyncBuiltinFunctionTool(ABC): @abstractmethod def to_dict(self) -> BetaToolUnionParam: ... @abstractmethod async def call(self, input: object) -> BetaFunctionToolResultType: ... @property def name(self) -> str: return self.to_dict()["name"] class BaseFunctionTool(Generic[CallableT]): func: CallableT """The function this tool is wrapping""" name: str """The name of the tool that will be sent to the API""" description: str input_schema: InputSchema def __init__( self, func: CallableT, *, name: str | None = None, description: str | None = None, input_schema: InputSchema | type[BaseModel] | None = None, ) -> None: if _compat.PYDANTIC_V1: raise RuntimeError("Tool functions are only supported with Pydantic v2") self.func = func self._func_with_validate = pydantic.validate_call(func) self.name = name or func.__name__ self.description = description or self._get_description_from_docstring() if input_schema is not None: if isinstance(input_schema, type): self.input_schema: InputSchema = input_schema.model_json_schema() else: self.input_schema = input_schema else: self.input_schema = self._create_schema_from_function() @property def __call__(self) -> CallableT: return self.func def to_dict(self) -> ToolParam: return { "name": self.name, "description": self.description, "input_schema": self.input_schema, } @cached_property def _parsed_docstring(self) -> docstring_parser.Docstring: return docstring_parser.parse(self.func.__doc__ or "") def _get_description_from_docstring(self) -> str: """Extract description from parsed docstring.""" if self._parsed_docstring.short_description: description = self._parsed_docstring.short_description if self._parsed_docstring.long_description: description += f"\n\n{self._parsed_docstring.long_description}" return description return "" def _create_schema_from_function(self) -> InputSchema: """Create JSON schema from function signature using pydantic.""" from pydantic_core import CoreSchema from pydantic.json_schema import JsonSchemaValue, GenerateJsonSchema from pydantic_core.core_schema import ArgumentsParameter class CustomGenerateJsonSchema(GenerateJsonSchema): def __init__(self, *, func: Callable[..., Any], parsed_docstring: Any) -> None: super().__init__() self._func = func self._parsed_docstring = parsed_docstring def __call__(self, *_args: Any, **_kwds: Any) -> "CustomGenerateJsonSchema": # noqa: ARG002 return self @override def kw_arguments_schema( self, arguments: "list[ArgumentsParameter]", var_kwargs_schema: CoreSchema | None, ) -> JsonSchemaValue: schema = super().kw_arguments_schema(arguments, var_kwargs_schema) if schema.get("type") != "object": return schema properties = schema.get("properties") if not properties or not is_dict(properties): return schema # Add parameter descriptions from docstring for param in self._parsed_docstring.params: prop_schema = properties.get(param.arg_name) if not prop_schema or not is_dict(prop_schema): continue if param.description and "description" not in prop_schema: prop_schema["description"] = param.description return schema schema_generator = CustomGenerateJsonSchema(func=self.func, parsed_docstring=self._parsed_docstring) return self._adapter.json_schema(schema_generator=schema_generator) # type: ignore @cached_property def _adapter(self) -> TypeAdapter[Any]: return TypeAdapter(self._func_with_validate) class BetaFunctionTool(BaseFunctionTool[FunctionT]): def call(self, input: object) -> BetaFunctionToolResultType: if iscoroutinefunction(self.func): raise RuntimeError("Cannot call a coroutine function synchronously. Use `@async_tool` instead.") if not is_dict(input): raise TypeError(f"Input must be a dictionary, got {type(input).__name__}") try: return self._func_with_validate(**cast(Any, input)) except pydantic.ValidationError as e: raise ValueError(f"Invalid arguments for function {self.name}") from e class BetaAsyncFunctionTool(BaseFunctionTool[AsyncFunctionT]): async def call(self, input: object) -> BetaFunctionToolResultType: if not iscoroutinefunction(self.func): raise RuntimeError("Cannot call a synchronous function asynchronously. Use `@tool` instead.") if not is_dict(input): raise TypeError(f"Input must be a dictionary, got {type(input).__name__}") try: return await self._func_with_validate(**cast(Any, input)) except pydantic.ValidationError as e: raise ValueError(f"Invalid arguments for function {self.name}") from e @overload def beta_tool(func: FunctionT) -> BetaFunctionTool[FunctionT]: ... @overload def beta_tool( func: FunctionT, *, name: str | None = None, description: str | None = None, input_schema: InputSchema | type[BaseModel] | None = None, ) -> BetaFunctionTool[FunctionT]: ... @overload def beta_tool( *, name: str | None = None, description: str | None = None, input_schema: InputSchema | type[BaseModel] | None = None, ) -> Callable[[FunctionT], BetaFunctionTool[FunctionT]]: ... def beta_tool( func: FunctionT | None = None, *, name: str | None = None, description: str | None = None, input_schema: InputSchema | type[BaseModel] | None = None, ) -> BetaFunctionTool[FunctionT] | Callable[[FunctionT], BetaFunctionTool[FunctionT]]: """Create a FunctionTool from a function with automatic schema inference. Can be used as a decorator with or without parentheses: @function_tool def my_func(x: int) -> str: ... @function_tool() def my_func(x: int) -> str: ... @function_tool(name="custom_name") def my_func(x: int) -> str: ... """ if _compat.PYDANTIC_V1: raise RuntimeError("Tool functions are only supported with Pydantic v2") if func is not None: # @beta_tool called without parentheses return BetaFunctionTool(func=func, name=name, description=description, input_schema=input_schema) # @beta_tool() def decorator(func: FunctionT) -> BetaFunctionTool[FunctionT]: return BetaFunctionTool(func=func, name=name, description=description, input_schema=input_schema) return decorator @overload def beta_async_tool(func: AsyncFunctionT) -> BetaAsyncFunctionTool[AsyncFunctionT]: ... @overload def beta_async_tool( func: AsyncFunctionT, *, name: str | None = None, description: str | None = None, input_schema: InputSchema | type[BaseModel] | None = None, ) -> BetaAsyncFunctionTool[AsyncFunctionT]: ... @overload def beta_async_tool( *, name: str | None = None, description: str | None = None, input_schema: InputSchema | type[BaseModel] | None = None, ) -> Callable[[AsyncFunctionT], BetaAsyncFunctionTool[AsyncFunctionT]]: ... def beta_async_tool( func: AsyncFunctionT | None = None, *, name: str | None = None, description: str | None = None, input_schema: InputSchema | type[BaseModel] | None = None, ) -> BetaAsyncFunctionTool[AsyncFunctionT] | Callable[[AsyncFunctionT], BetaAsyncFunctionTool[AsyncFunctionT]]: """Create an AsyncFunctionTool from a function with automatic schema inference. Can be used as a decorator with or without parentheses: @async_tool async def my_func(x: int) -> str: ... @async_tool() async def my_func(x: int) -> str: ... @async_tool(name="custom_name") async def my_func(x: int) -> str: ... """ if _compat.PYDANTIC_V1: raise RuntimeError("Tool functions are only supported with Pydantic v2") if func is not None: # @beta_async_tool called without parentheses return BetaAsyncFunctionTool( func=func, name=name, description=description, input_schema=input_schema, ) # @beta_async_tool() def decorator(func: AsyncFunctionT) -> BetaAsyncFunctionTool[AsyncFunctionT]: return BetaAsyncFunctionTool( func=func, name=name, description=description, input_schema=input_schema, ) return decorator BetaRunnableTool = Union[BetaFunctionTool[Any], BetaBuiltinFunctionTool] BetaAsyncRunnableTool = Union[BetaAsyncFunctionTool[Any], BetaAsyncBuiltinFunctionTool] anthropic-sdk-python-0.69.0/src/anthropic/lib/tools/_beta_runner.py000066400000000000000000000364461506653454500254260ustar00rootroot00000000000000from __future__ import annotations import logging from abc import ABC, abstractmethod from typing import ( TYPE_CHECKING, Any, List, Union, Generic, TypeVar, Callable, Iterable, Iterator, Coroutine, AsyncIterator, ) from typing_extensions import TypedDict, override import httpx from ..._types import Body, Query, Headers, NotGiven from ..._utils import consume_sync_iterator, consume_async_iterator from ...types.beta import BetaMessage, BetaContentBlock, BetaMessageParam from ._beta_functions import ( BetaFunctionTool, BetaRunnableTool, BetaAsyncFunctionTool, BetaAsyncRunnableTool, BetaBuiltinFunctionTool, BetaAsyncBuiltinFunctionTool, ) from ..streaming._beta_messages import BetaMessageStream, BetaAsyncMessageStream from ...types.beta.message_create_params import MessageCreateParamsBase from ...types.beta.beta_tool_result_block_param import BetaToolResultBlockParam if TYPE_CHECKING: from ..._client import Anthropic, AsyncAnthropic AnyFunctionToolT = TypeVar( "AnyFunctionToolT", bound=Union[ BetaFunctionTool[Any], BetaAsyncFunctionTool[Any], BetaBuiltinFunctionTool, BetaAsyncBuiltinFunctionTool ], ) RunnerItemT = TypeVar("RunnerItemT") log = logging.getLogger(__name__) class RequestOptions(TypedDict, total=False): extra_headers: Headers | None extra_query: Query | None extra_body: Body | None timeout: float | httpx.Timeout | None | NotGiven class BaseToolRunner(Generic[AnyFunctionToolT]): def __init__( self, *, params: MessageCreateParamsBase, options: RequestOptions, tools: Iterable[AnyFunctionToolT], max_iterations: int | None = None, ) -> None: self._tools_by_name = {tool.name: tool for tool in tools} self._params: MessageCreateParamsBase = { **params, "messages": [message for message in params["messages"]], } self._options = options self._messages_modified = False self._cached_tool_call_response: BetaMessageParam | None = None self._max_iterations = max_iterations self._iteration_count = 0 def set_messages_params( self, params: MessageCreateParamsBase | Callable[[MessageCreateParamsBase], MessageCreateParamsBase] ) -> None: """ Update the parameters for the next API call. This invalidates any cached tool responses. Args: params (MessageCreateParamsBase | Callable): Either new parameters or a function to mutate existing parameters """ if callable(params): params = params(self._params) self._params = params def append_messages(self, *messages: BetaMessageParam | BetaMessage) -> None: """Add one or more messages to the conversation history. This invalidates the cached tool response, i.e. if tools were already called, then they will be called again on the next loop iteration. """ message_params: List[BetaMessageParam] = [ {"role": message.role, "content": message.content} if isinstance(message, BetaMessage) else message for message in messages ] self._messages_modified = True self.set_messages_params(lambda params: {**params, "messages": [*self._params["messages"], *message_params]}) self._cached_tool_call_response = None def _should_stop(self) -> bool: if self._max_iterations is not None and self._iteration_count >= self._max_iterations: return True return False class BaseSyncToolRunner(BaseToolRunner[BetaRunnableTool], Generic[RunnerItemT], ABC): def __init__( self, *, params: MessageCreateParamsBase, options: RequestOptions, tools: Iterable[BetaRunnableTool], client: Anthropic, max_iterations: int | None = None, ) -> None: super().__init__(params=params, options=options, tools=tools, max_iterations=max_iterations) self._client = client self._iterator = self.__run__() self._last_message: Callable[[], BetaMessage] | BetaMessage | None = None def __next__(self) -> RunnerItemT: return self._iterator.__next__() def __iter__(self) -> Iterator[RunnerItemT]: for item in self._iterator: yield item @abstractmethod def __run__(self) -> Iterator[RunnerItemT]: raise NotImplementedError() def until_done(self) -> BetaMessage: """ Consumes the tool runner stream and returns the last message if it has not been consumed yet. If it has, it simply returns the last message. """ consume_sync_iterator(self) last_message = self._get_last_message() assert last_message is not None return last_message def generate_tool_call_response(self) -> BetaMessageParam | None: """Generate a MessageParam by calling tool functions with any tool use blocks from the last message. Note the tool call response is cached, repeated calls to this method will return the same response. None can be returned if no tool call was applicable. """ if self._cached_tool_call_response is not None: log.debug("Returning cached tool call response.") return self._cached_tool_call_response response = self._generate_tool_call_response() self._cached_tool_call_response = response return response def _generate_tool_call_response(self) -> BetaMessageParam | None: content = self._get_last_assistant_message_content() if not content: return None tool_use_blocks = [block for block in content if block.type == "tool_use"] if not tool_use_blocks: return None results: list[BetaToolResultBlockParam] = [] for tool_use in tool_use_blocks: tool = self._tools_by_name.get(tool_use.name) if tool is None: results.append( { "type": "tool_result", "tool_use_id": tool_use.id, "content": f"Error: Tool '{tool_use.name}' not found", "is_error": True, } ) continue try: result = tool.call(tool_use.input) results.append({"type": "tool_result", "tool_use_id": tool_use.id, "content": result}) except Exception as exc: log.exception(f"Error occurred while calling tool: {tool.name}", exc_info=exc) results.append( { "type": "tool_result", "tool_use_id": tool_use.id, "content": repr(exc), "is_error": True, } ) return {"role": "user", "content": results} def _get_last_message(self) -> BetaMessage | None: if callable(self._last_message): return self._last_message() return self._last_message def _get_last_assistant_message_content(self) -> list[BetaContentBlock] | None: last_message = self._get_last_message() if last_message is None or last_message.role != "assistant" or not last_message.content: return None return last_message.content class BetaToolRunner(BaseSyncToolRunner[BetaMessage]): @override def __run__(self) -> Iterator[BetaMessage]: self._last_message = message = self._client.beta.messages.create(**self._params, **self._options) yield message self._iteration_count += 1 while not self._should_stop(): response = self.generate_tool_call_response() if response is None: log.debug("Tool call was not requested, exiting from tool runner loop.") return if not self._messages_modified: self.append_messages(message, response) self._iteration_count += 1 self._messages_modified = False self._cached_tool_call_response = None self._last_message = message = self._client.beta.messages.create(**self._params, **self._options) yield message class BetaStreamingToolRunner(BaseSyncToolRunner[BetaMessageStream]): @override def __run__(self) -> Iterator[BetaMessageStream]: with self._client.beta.messages.stream(**self._params, **self._options) as stream: self._last_message = stream.get_final_message yield stream message = stream.get_final_message() self._iteration_count += 1 while not self._should_stop(): response = self.generate_tool_call_response() if response is None: log.debug("Tool call was not requested, exiting from tool runner loop.") return if not self._messages_modified: self.append_messages(message, response) self._iteration_count += 1 self._messages_modified = False with self._client.beta.messages.stream(**self._params, **self._options) as stream: self._cached_tool_call_response = None self._last_message = stream.get_final_message yield stream message = stream.get_final_message() class BaseAsyncToolRunner(BaseToolRunner[BetaAsyncRunnableTool], Generic[RunnerItemT], ABC): def __init__( self, *, params: MessageCreateParamsBase, options: RequestOptions, tools: Iterable[BetaAsyncRunnableTool], client: AsyncAnthropic, max_iterations: int | None = None, ) -> None: super().__init__(params=params, options=options, tools=tools, max_iterations=max_iterations) self._client = client self._iterator = self.__run__() self._last_message: Callable[[], Coroutine[None, None, BetaMessage]] | BetaMessage | None = None async def __anext__(self) -> RunnerItemT: return await self._iterator.__anext__() async def __aiter__(self) -> AsyncIterator[RunnerItemT]: async for item in self._iterator: yield item @abstractmethod async def __run__(self) -> AsyncIterator[RunnerItemT]: raise NotImplementedError() yield # type: ignore[unreachable] async def until_done(self) -> BetaMessage: """ Consumes the tool runner stream and returns the last message if it has not been consumed yet. If it has, it simply returns the last message. """ await consume_async_iterator(self) last_message = await self._get_last_message() assert last_message is not None return last_message async def generate_tool_call_response(self) -> BetaMessageParam | None: """Generate a MessageParam by calling tool functions with any tool use blocks from the last message. Note the tool call response is cached, repeated calls to this method will return the same response. None can be returned if no tool call was applicable. """ if self._cached_tool_call_response is not None: log.debug("Returning cached tool call response.") return self._cached_tool_call_response response = await self._generate_tool_call_response() self._cached_tool_call_response = response return response async def _get_last_message(self) -> BetaMessage | None: if callable(self._last_message): return await self._last_message() return self._last_message async def _get_last_assistant_message_content(self) -> list[BetaContentBlock] | None: last_message = await self._get_last_message() if last_message is None or last_message.role != "assistant" or not last_message.content: return None return last_message.content async def _generate_tool_call_response(self) -> BetaMessageParam | None: content = await self._get_last_assistant_message_content() if not content: return None tool_use_blocks = [block for block in content if block.type == "tool_use"] if not tool_use_blocks: return None results: list[BetaToolResultBlockParam] = [] for tool_use in tool_use_blocks: tool = self._tools_by_name.get(tool_use.name) if tool is None: results.append( { "type": "tool_result", "tool_use_id": tool_use.id, "content": f"Error: Tool '{tool_use.name}' not found", "is_error": True, } ) continue try: result = await tool.call(tool_use.input) results.append({"type": "tool_result", "tool_use_id": tool_use.id, "content": result}) except Exception as exc: log.exception(f"Error occurred while calling tool: {tool.name}", exc_info=exc) results.append( { "type": "tool_result", "tool_use_id": tool_use.id, "content": repr(exc), "is_error": True, } ) return {"role": "user", "content": results} class BetaAsyncToolRunner(BaseAsyncToolRunner[BetaMessage]): @override async def __run__(self) -> AsyncIterator[BetaMessage]: self._last_message = message = await self._client.beta.messages.create(**self._params, **self._options) yield message self._iteration_count += 1 while not self._should_stop(): response = await self.generate_tool_call_response() if response is None: log.debug("Tool call was not requested, exiting from tool runner loop.") return if not self._messages_modified: self.append_messages(message, response) self._iteration_count += 1 self._messages_modified = False self._cached_tool_call_response = None self._last_message = message = await self._client.beta.messages.create(**self._params, **self._options) yield message class BetaAsyncStreamingToolRunner(BaseAsyncToolRunner[BetaAsyncMessageStream]): @override async def __run__(self) -> AsyncIterator[BetaAsyncMessageStream]: async with self._client.beta.messages.stream(**self._params, **self._options) as stream: self._last_message = stream.get_final_message yield stream message = await stream.get_final_message() self._iteration_count += 1 while not self._should_stop(): response = await self.generate_tool_call_response() if response is None: log.debug("Tool call was not requested, exiting from tool runner loop.") return if not self._messages_modified: self.append_messages(message, response) self._iteration_count += 1 self._messages_modified = False async with self._client.beta.messages.stream(**self._params, **self._options) as stream: self._last_message = stream.get_final_message self._cached_tool_call_response = None yield stream message = await stream.get_final_message() anthropic-sdk-python-0.69.0/src/anthropic/lib/vertex/000077500000000000000000000000001506653454500225515ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/lib/vertex/__init__.py000066400000000000000000000001461506653454500246630ustar00rootroot00000000000000from ._client import AnthropicVertex as AnthropicVertex, AsyncAnthropicVertex as AsyncAnthropicVertex anthropic-sdk-python-0.69.0/src/anthropic/lib/vertex/_auth.py000066400000000000000000000031541506653454500242260ustar00rootroot00000000000000from __future__ import annotations from typing import TYPE_CHECKING, Any, cast from .._extras import google_auth if TYPE_CHECKING: from google.auth.credentials import Credentials # type: ignore[import-untyped] # pyright: reportMissingTypeStubs=false, reportUnknownVariableType=false, reportUnknownMemberType=false, reportUnknownArgumentType=false # google libraries don't provide types :/ # Note: these functions are blocking as they make HTTP requests, the async # client runs these functions in a separate thread to ensure they do not # cause synchronous blocking issues. def load_auth(*, project_id: str | None) -> tuple[Credentials, str]: try: from google.auth.transport.requests import Request # type: ignore[import-untyped] except ModuleNotFoundError as err: raise RuntimeError( f"Could not import google.auth, you need to install the SDK with `pip install anthropic[vertex]`" ) from err credentials, loaded_project_id = google_auth.default( scopes=["https://www.googleapis.com/auth/cloud-platform"], ) credentials = cast(Any, credentials) credentials.refresh(Request()) if not project_id: project_id = loaded_project_id if not project_id: raise ValueError("Could not resolve project_id") if not isinstance(project_id, str): raise TypeError(f"Expected project_id to be a str but got {type(project_id)}") return credentials, project_id def refresh_auth(credentials: Credentials) -> None: from google.auth.transport.requests import Request # type: ignore[import-untyped] credentials.refresh(Request()) anthropic-sdk-python-0.69.0/src/anthropic/lib/vertex/_beta.py000066400000000000000000000063731506653454500242060ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource from ._beta_messages import ( Messages, AsyncMessages, MessagesWithRawResponse, AsyncMessagesWithRawResponse, MessagesWithStreamingResponse, AsyncMessagesWithStreamingResponse, ) __all__ = ["Beta", "AsyncBeta"] class Beta(SyncAPIResource): @cached_property def messages(self) -> Messages: return Messages(self._client) @cached_property def with_raw_response(self) -> BetaWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the the raw response object instead of the parsed content. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers """ return BetaWithRawResponse(self) @cached_property def with_streaming_response(self) -> BetaWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response """ return BetaWithStreamingResponse(self) class AsyncBeta(AsyncAPIResource): @cached_property def messages(self) -> AsyncMessages: return AsyncMessages(self._client) @cached_property def with_raw_response(self) -> AsyncBetaWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the the raw response object instead of the parsed content. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers """ return AsyncBetaWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncBetaWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response """ return AsyncBetaWithStreamingResponse(self) class BetaWithRawResponse: def __init__(self, beta: Beta) -> None: self._beta = beta @cached_property def messages(self) -> MessagesWithRawResponse: return MessagesWithRawResponse(self._beta.messages) class AsyncBetaWithRawResponse: def __init__(self, beta: AsyncBeta) -> None: self._beta = beta @cached_property def messages(self) -> AsyncMessagesWithRawResponse: return AsyncMessagesWithRawResponse(self._beta.messages) class BetaWithStreamingResponse: def __init__(self, beta: Beta) -> None: self._beta = beta @cached_property def messages(self) -> MessagesWithStreamingResponse: return MessagesWithStreamingResponse(self._beta.messages) class AsyncBetaWithStreamingResponse: def __init__(self, beta: AsyncBeta) -> None: self._beta = beta @cached_property def messages(self) -> AsyncMessagesWithStreamingResponse: return AsyncMessagesWithStreamingResponse(self._beta.messages) anthropic-sdk-python-0.69.0/src/anthropic/lib/vertex/_beta_messages.py000066400000000000000000000065071506653454500260740ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from ... import _legacy_response from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper from ...resources.beta import Messages as FirstPartyMessagesAPI, AsyncMessages as FirstPartyAsyncMessagesAPI __all__ = ["Messages", "AsyncMessages"] class Messages(SyncAPIResource): create = FirstPartyMessagesAPI.create stream = FirstPartyMessagesAPI.stream count_tokens = FirstPartyMessagesAPI.count_tokens @cached_property def with_raw_response(self) -> MessagesWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the the raw response object instead of the parsed content. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers """ return MessagesWithRawResponse(self) @cached_property def with_streaming_response(self) -> MessagesWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response """ return MessagesWithStreamingResponse(self) class AsyncMessages(AsyncAPIResource): create = FirstPartyAsyncMessagesAPI.create stream = FirstPartyAsyncMessagesAPI.stream count_tokens = FirstPartyAsyncMessagesAPI.count_tokens @cached_property def with_raw_response(self) -> AsyncMessagesWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the the raw response object instead of the parsed content. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers """ return AsyncMessagesWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncMessagesWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response """ return AsyncMessagesWithStreamingResponse(self) class MessagesWithRawResponse: def __init__(self, messages: Messages) -> None: self._messages = messages self.create = _legacy_response.to_raw_response_wrapper( messages.create, ) class AsyncMessagesWithRawResponse: def __init__(self, messages: AsyncMessages) -> None: self._messages = messages self.create = _legacy_response.async_to_raw_response_wrapper( messages.create, ) class MessagesWithStreamingResponse: def __init__(self, messages: Messages) -> None: self._messages = messages self.create = to_streamed_response_wrapper( messages.create, ) class AsyncMessagesWithStreamingResponse: def __init__(self, messages: AsyncMessages) -> None: self._messages = messages self.create = async_to_streamed_response_wrapper( messages.create, ) anthropic-sdk-python-0.69.0/src/anthropic/lib/vertex/_client.py000066400000000000000000000403531506653454500245450ustar00rootroot00000000000000from __future__ import annotations import os from typing import TYPE_CHECKING, Any, Union, Mapping, TypeVar from typing_extensions import Self, override import httpx from ... import _exceptions from ._auth import load_auth, refresh_auth from ._beta import Beta, AsyncBeta from ..._types import NOT_GIVEN, NotGiven from ..._utils import is_dict, asyncify, is_given from ..._compat import model_copy, typed_cached_property from ..._models import FinalRequestOptions from ..._version import __version__ from ..._streaming import Stream, AsyncStream from ..._exceptions import AnthropicError, APIStatusError from ..._base_client import ( DEFAULT_MAX_RETRIES, BaseClient, SyncAPIClient, AsyncAPIClient, ) from ...resources.messages import Messages, AsyncMessages if TYPE_CHECKING: from google.auth.credentials import Credentials as GoogleCredentials # type: ignore DEFAULT_VERSION = "vertex-2023-10-16" _HttpxClientT = TypeVar("_HttpxClientT", bound=Union[httpx.Client, httpx.AsyncClient]) _DefaultStreamT = TypeVar("_DefaultStreamT", bound=Union[Stream[Any], AsyncStream[Any]]) class BaseVertexClient(BaseClient[_HttpxClientT, _DefaultStreamT]): @typed_cached_property def region(self) -> str: raise RuntimeError("region not set") @typed_cached_property def project_id(self) -> str | None: project_id = os.environ.get("ANTHROPIC_VERTEX_PROJECT_ID") if project_id: return project_id return None @override def _make_status_error( self, err_msg: str, *, body: object, response: httpx.Response, ) -> APIStatusError: if response.status_code == 400: return _exceptions.BadRequestError(err_msg, response=response, body=body) if response.status_code == 401: return _exceptions.AuthenticationError(err_msg, response=response, body=body) if response.status_code == 403: return _exceptions.PermissionDeniedError(err_msg, response=response, body=body) if response.status_code == 404: return _exceptions.NotFoundError(err_msg, response=response, body=body) if response.status_code == 409: return _exceptions.ConflictError(err_msg, response=response, body=body) if response.status_code == 422: return _exceptions.UnprocessableEntityError(err_msg, response=response, body=body) if response.status_code == 429: return _exceptions.RateLimitError(err_msg, response=response, body=body) if response.status_code == 503: return _exceptions.ServiceUnavailableError(err_msg, response=response, body=body) if response.status_code == 504: return _exceptions.DeadlineExceededError(err_msg, response=response, body=body) if response.status_code >= 500: return _exceptions.InternalServerError(err_msg, response=response, body=body) return APIStatusError(err_msg, response=response, body=body) class AnthropicVertex(BaseVertexClient[httpx.Client, Stream[Any]], SyncAPIClient): messages: Messages beta: Beta def __init__( self, *, region: str | NotGiven = NOT_GIVEN, project_id: str | NotGiven = NOT_GIVEN, access_token: str | None = None, credentials: GoogleCredentials | None = None, base_url: str | httpx.URL | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, max_retries: int = DEFAULT_MAX_RETRIES, default_headers: Mapping[str, str] | None = None, default_query: Mapping[str, object] | None = None, # Configure a custom httpx client. See the [httpx documentation](https://www.python-httpx.org/api/#client) for more details. http_client: httpx.Client | None = None, _strict_response_validation: bool = False, ) -> None: if not is_given(region): region = os.environ.get("CLOUD_ML_REGION", NOT_GIVEN) if not is_given(region): raise ValueError( "No region was given. The client should be instantiated with the `region` argument or the `CLOUD_ML_REGION` environment variable should be set." ) if base_url is None: base_url = os.environ.get("ANTHROPIC_VERTEX_BASE_URL") if base_url is None: if region == "global": base_url = "https://aiplatform.googleapis.com/v1" else: base_url = f"https://{region}-aiplatform.googleapis.com/v1" super().__init__( version=__version__, base_url=base_url, timeout=timeout, max_retries=max_retries, custom_headers=default_headers, custom_query=default_query, http_client=http_client, _strict_response_validation=_strict_response_validation, ) if is_given(project_id): self.project_id = project_id self.region = region self.access_token = access_token self.credentials = credentials self.messages = Messages(self) self.beta = Beta(self) @override def _prepare_options(self, options: FinalRequestOptions) -> FinalRequestOptions: return _prepare_options(options, project_id=self.project_id, region=self.region) @override def _prepare_request(self, request: httpx.Request) -> None: if request.headers.get("Authorization"): # already authenticated, nothing for us to do return request.headers["Authorization"] = f"Bearer {self._ensure_access_token()}" def _ensure_access_token(self) -> str: if self.access_token is not None: return self.access_token if not self.credentials: self.credentials, project_id = load_auth(project_id=self.project_id) if not self.project_id: self.project_id = project_id if self.credentials.expired or not self.credentials.token: refresh_auth(self.credentials) if not self.credentials.token: raise RuntimeError("Could not resolve API token from the environment") assert isinstance(self.credentials.token, str) return self.credentials.token def copy( self, *, region: str | NotGiven = NOT_GIVEN, project_id: str | NotGiven = NOT_GIVEN, access_token: str | None = None, credentials: GoogleCredentials | None = None, base_url: str | httpx.URL | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, http_client: httpx.Client | None = None, max_retries: int | NotGiven = NOT_GIVEN, default_headers: Mapping[str, str] | None = None, set_default_headers: Mapping[str, str] | None = None, default_query: Mapping[str, object] | None = None, set_default_query: Mapping[str, object] | None = None, _extra_kwargs: Mapping[str, Any] = {}, ) -> Self: """ Create a new client instance re-using the same options given to the current client with optional overriding. """ if default_headers is not None and set_default_headers is not None: raise ValueError("The `default_headers` and `set_default_headers` arguments are mutually exclusive") if default_query is not None and set_default_query is not None: raise ValueError("The `default_query` and `set_default_query` arguments are mutually exclusive") headers = self._custom_headers if default_headers is not None: headers = {**headers, **default_headers} elif set_default_headers is not None: headers = set_default_headers params = self._custom_query if default_query is not None: params = {**params, **default_query} elif set_default_query is not None: params = set_default_query http_client = http_client or self._client return self.__class__( region=region if is_given(region) else self.region, project_id=project_id if is_given(project_id) else self.project_id or NOT_GIVEN, access_token=access_token or self.access_token, credentials=credentials or self.credentials, base_url=base_url or self.base_url, timeout=self.timeout if isinstance(timeout, NotGiven) else timeout, http_client=http_client, max_retries=max_retries if is_given(max_retries) else self.max_retries, default_headers=headers, default_query=params, **_extra_kwargs, ) # Alias for `copy` for nicer inline usage, e.g. # client.with_options(timeout=10).foo.create(...) with_options = copy class AsyncAnthropicVertex(BaseVertexClient[httpx.AsyncClient, AsyncStream[Any]], AsyncAPIClient): messages: AsyncMessages beta: AsyncBeta def __init__( self, *, region: str | NotGiven = NOT_GIVEN, project_id: str | NotGiven = NOT_GIVEN, access_token: str | None = None, credentials: GoogleCredentials | None = None, base_url: str | httpx.URL | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, max_retries: int = DEFAULT_MAX_RETRIES, default_headers: Mapping[str, str] | None = None, default_query: Mapping[str, object] | None = None, # Configure a custom httpx client. See the [httpx documentation](https://www.python-httpx.org/api/#client) for more details. http_client: httpx.AsyncClient | None = None, _strict_response_validation: bool = False, ) -> None: if not is_given(region): region = os.environ.get("CLOUD_ML_REGION", NOT_GIVEN) if not is_given(region): raise ValueError( "No region was given. The client should be instantiated with the `region` argument or the `CLOUD_ML_REGION` environment variable should be set." ) if base_url is None: base_url = os.environ.get("ANTHROPIC_VERTEX_BASE_URL") if base_url is None: if region == "global": base_url = "https://aiplatform.googleapis.com/v1" else: base_url = f"https://{region}-aiplatform.googleapis.com/v1" super().__init__( version=__version__, base_url=base_url, timeout=timeout, max_retries=max_retries, custom_headers=default_headers, custom_query=default_query, http_client=http_client, _strict_response_validation=_strict_response_validation, ) if is_given(project_id): self.project_id = project_id self.region = region self.access_token = access_token self.credentials = credentials self.messages = AsyncMessages(self) self.beta = AsyncBeta(self) @override async def _prepare_options(self, options: FinalRequestOptions) -> FinalRequestOptions: return _prepare_options(options, project_id=self.project_id, region=self.region) @override async def _prepare_request(self, request: httpx.Request) -> None: if request.headers.get("Authorization"): # already authenticated, nothing for us to do return request.headers["Authorization"] = f"Bearer {await self._ensure_access_token()}" async def _ensure_access_token(self) -> str: if self.access_token is not None: return self.access_token if not self.credentials: self.credentials, project_id = await asyncify(load_auth)(project_id=self.project_id) if not self.project_id: self.project_id = project_id if self.credentials.expired or not self.credentials.token: await asyncify(refresh_auth)(self.credentials) if not self.credentials.token: raise RuntimeError("Could not resolve API token from the environment") assert isinstance(self.credentials.token, str) return self.credentials.token def copy( self, *, region: str | NotGiven = NOT_GIVEN, project_id: str | NotGiven = NOT_GIVEN, access_token: str | None = None, credentials: GoogleCredentials | None = None, base_url: str | httpx.URL | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, http_client: httpx.AsyncClient | None = None, max_retries: int | NotGiven = NOT_GIVEN, default_headers: Mapping[str, str] | None = None, set_default_headers: Mapping[str, str] | None = None, default_query: Mapping[str, object] | None = None, set_default_query: Mapping[str, object] | None = None, _extra_kwargs: Mapping[str, Any] = {}, ) -> Self: """ Create a new client instance re-using the same options given to the current client with optional overriding. """ if default_headers is not None and set_default_headers is not None: raise ValueError("The `default_headers` and `set_default_headers` arguments are mutually exclusive") if default_query is not None and set_default_query is not None: raise ValueError("The `default_query` and `set_default_query` arguments are mutually exclusive") headers = self._custom_headers if default_headers is not None: headers = {**headers, **default_headers} elif set_default_headers is not None: headers = set_default_headers params = self._custom_query if default_query is not None: params = {**params, **default_query} elif set_default_query is not None: params = set_default_query http_client = http_client or self._client return self.__class__( region=region if is_given(region) else self.region, project_id=project_id if is_given(project_id) else self.project_id or NOT_GIVEN, access_token=access_token or self.access_token, credentials=credentials or self.credentials, base_url=base_url or self.base_url, timeout=self.timeout if isinstance(timeout, NotGiven) else timeout, http_client=http_client, max_retries=max_retries if is_given(max_retries) else self.max_retries, default_headers=headers, default_query=params, **_extra_kwargs, ) # Alias for `copy` for nicer inline usage, e.g. # client.with_options(timeout=10).foo.create(...) with_options = copy def _prepare_options(input_options: FinalRequestOptions, *, project_id: str | None, region: str) -> FinalRequestOptions: options = model_copy(input_options, deep=True) if is_dict(options.json_data): options.json_data.setdefault("anthropic_version", DEFAULT_VERSION) if options.url in {"/v1/messages", "/v1/messages?beta=true"} and options.method == "post": if project_id is None: raise RuntimeError( "No project_id was given and it could not be resolved from credentials. The client should be instantiated with the `project_id` argument or the `ANTHROPIC_VERTEX_PROJECT_ID` environment variable should be set." ) if not is_dict(options.json_data): raise RuntimeError("Expected json data to be a dictionary for post /v1/messages") model = options.json_data.pop("model") stream = options.json_data.get("stream", False) specifier = "streamRawPredict" if stream else "rawPredict" options.url = f"/projects/{project_id}/locations/{region}/publishers/anthropic/models/{model}:{specifier}" if options.url in {"/v1/messages/count_tokens", "/v1/messages/count_tokens?beta=true"} and options.method == "post": if project_id is None: raise RuntimeError( "No project_id was given and it could not be resolved from credentials. The client should be instantiated with the `project_id` argument or the `ANTHROPIC_VERTEX_PROJECT_ID` environment variable should be set." ) options.url = f"/projects/{project_id}/locations/{region}/publishers/anthropic/models/count-tokens:rawPredict" if options.url.startswith("/v1/messages/batches"): raise AnthropicError("The Batch API is not supported in the Vertex client yet") return options anthropic-sdk-python-0.69.0/src/anthropic/pagination.py000066400000000000000000000042321506653454500231720ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import List, Generic, TypeVar, Optional from typing_extensions import override from ._base_client import BasePage, PageInfo, BaseSyncPage, BaseAsyncPage __all__ = ["SyncPage", "AsyncPage"] _T = TypeVar("_T") class SyncPage(BaseSyncPage[_T], BasePage[_T], Generic[_T]): data: List[_T] has_more: Optional[bool] = None first_id: Optional[str] = None last_id: Optional[str] = None @override def _get_page_items(self) -> List[_T]: data = self.data if not data: return [] return data @override def has_next_page(self) -> bool: has_more = self.has_more if has_more is not None and has_more is False: return False return super().has_next_page() @override def next_page_info(self) -> Optional[PageInfo]: if self._options.params.get("before_id"): first_id = self.first_id if not first_id: return None return PageInfo(params={"before_id": first_id}) last_id = self.last_id if not last_id: return None return PageInfo(params={"after_id": last_id}) class AsyncPage(BaseAsyncPage[_T], BasePage[_T], Generic[_T]): data: List[_T] has_more: Optional[bool] = None first_id: Optional[str] = None last_id: Optional[str] = None @override def _get_page_items(self) -> List[_T]: data = self.data if not data: return [] return data @override def has_next_page(self) -> bool: has_more = self.has_more if has_more is not None and has_more is False: return False return super().has_next_page() @override def next_page_info(self) -> Optional[PageInfo]: if self._options.params.get("before_id"): first_id = self.first_id if not first_id: return None return PageInfo(params={"before_id": first_id}) last_id = self.last_id if not last_id: return None return PageInfo(params={"after_id": last_id}) anthropic-sdk-python-0.69.0/src/anthropic/py.typed000066400000000000000000000000001506653454500221530ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/resources/000077500000000000000000000000001506653454500225005ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/resources/__init__.py000066400000000000000000000030571506653454500246160ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from .beta import ( Beta, AsyncBeta, BetaWithRawResponse, AsyncBetaWithRawResponse, BetaWithStreamingResponse, AsyncBetaWithStreamingResponse, ) from .models import ( Models, AsyncModels, ModelsWithRawResponse, AsyncModelsWithRawResponse, ModelsWithStreamingResponse, AsyncModelsWithStreamingResponse, ) from .messages import ( Messages, AsyncMessages, MessagesWithRawResponse, AsyncMessagesWithRawResponse, MessagesWithStreamingResponse, AsyncMessagesWithStreamingResponse, ) from .completions import ( Completions, AsyncCompletions, CompletionsWithRawResponse, AsyncCompletionsWithRawResponse, CompletionsWithStreamingResponse, AsyncCompletionsWithStreamingResponse, ) __all__ = [ "Completions", "AsyncCompletions", "CompletionsWithRawResponse", "AsyncCompletionsWithRawResponse", "CompletionsWithStreamingResponse", "AsyncCompletionsWithStreamingResponse", "Messages", "AsyncMessages", "MessagesWithRawResponse", "AsyncMessagesWithRawResponse", "MessagesWithStreamingResponse", "AsyncMessagesWithStreamingResponse", "Models", "AsyncModels", "ModelsWithRawResponse", "AsyncModelsWithRawResponse", "ModelsWithStreamingResponse", "AsyncModelsWithStreamingResponse", "Beta", "AsyncBeta", "BetaWithRawResponse", "AsyncBetaWithRawResponse", "BetaWithStreamingResponse", "AsyncBetaWithStreamingResponse", ] anthropic-sdk-python-0.69.0/src/anthropic/resources/beta/000077500000000000000000000000001506653454500234135ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/resources/beta/__init__.py000066400000000000000000000027411506653454500255300ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from .beta import ( Beta, AsyncBeta, BetaWithRawResponse, AsyncBetaWithRawResponse, BetaWithStreamingResponse, AsyncBetaWithStreamingResponse, ) from .files import ( Files, AsyncFiles, FilesWithRawResponse, AsyncFilesWithRawResponse, FilesWithStreamingResponse, AsyncFilesWithStreamingResponse, ) from .models import ( Models, AsyncModels, ModelsWithRawResponse, AsyncModelsWithRawResponse, ModelsWithStreamingResponse, AsyncModelsWithStreamingResponse, ) from .messages import ( Messages, AsyncMessages, MessagesWithRawResponse, AsyncMessagesWithRawResponse, MessagesWithStreamingResponse, AsyncMessagesWithStreamingResponse, ) __all__ = [ "Models", "AsyncModels", "ModelsWithRawResponse", "AsyncModelsWithRawResponse", "ModelsWithStreamingResponse", "AsyncModelsWithStreamingResponse", "Messages", "AsyncMessages", "MessagesWithRawResponse", "AsyncMessagesWithRawResponse", "MessagesWithStreamingResponse", "AsyncMessagesWithStreamingResponse", "Files", "AsyncFiles", "FilesWithRawResponse", "AsyncFilesWithRawResponse", "FilesWithStreamingResponse", "AsyncFilesWithStreamingResponse", "Beta", "AsyncBeta", "BetaWithRawResponse", "AsyncBetaWithRawResponse", "BetaWithStreamingResponse", "AsyncBetaWithStreamingResponse", ] anthropic-sdk-python-0.69.0/src/anthropic/resources/beta/beta.py000066400000000000000000000120031506653454500246740ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from .files import ( Files, AsyncFiles, FilesWithRawResponse, AsyncFilesWithRawResponse, FilesWithStreamingResponse, AsyncFilesWithStreamingResponse, ) from .models import ( Models, AsyncModels, ModelsWithRawResponse, AsyncModelsWithRawResponse, ModelsWithStreamingResponse, AsyncModelsWithStreamingResponse, ) from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource from .messages.messages import ( Messages, AsyncMessages, MessagesWithRawResponse, AsyncMessagesWithRawResponse, MessagesWithStreamingResponse, AsyncMessagesWithStreamingResponse, ) __all__ = ["Beta", "AsyncBeta"] class Beta(SyncAPIResource): @cached_property def models(self) -> Models: return Models(self._client) @cached_property def messages(self) -> Messages: return Messages(self._client) @cached_property def files(self) -> Files: return Files(self._client) @cached_property def with_raw_response(self) -> BetaWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the raw response object instead of the parsed content. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers """ return BetaWithRawResponse(self) @cached_property def with_streaming_response(self) -> BetaWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response """ return BetaWithStreamingResponse(self) class AsyncBeta(AsyncAPIResource): @cached_property def models(self) -> AsyncModels: return AsyncModels(self._client) @cached_property def messages(self) -> AsyncMessages: return AsyncMessages(self._client) @cached_property def files(self) -> AsyncFiles: return AsyncFiles(self._client) @cached_property def with_raw_response(self) -> AsyncBetaWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the raw response object instead of the parsed content. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers """ return AsyncBetaWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncBetaWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response """ return AsyncBetaWithStreamingResponse(self) class BetaWithRawResponse: def __init__(self, beta: Beta) -> None: self._beta = beta @cached_property def models(self) -> ModelsWithRawResponse: return ModelsWithRawResponse(self._beta.models) @cached_property def messages(self) -> MessagesWithRawResponse: return MessagesWithRawResponse(self._beta.messages) @cached_property def files(self) -> FilesWithRawResponse: return FilesWithRawResponse(self._beta.files) class AsyncBetaWithRawResponse: def __init__(self, beta: AsyncBeta) -> None: self._beta = beta @cached_property def models(self) -> AsyncModelsWithRawResponse: return AsyncModelsWithRawResponse(self._beta.models) @cached_property def messages(self) -> AsyncMessagesWithRawResponse: return AsyncMessagesWithRawResponse(self._beta.messages) @cached_property def files(self) -> AsyncFilesWithRawResponse: return AsyncFilesWithRawResponse(self._beta.files) class BetaWithStreamingResponse: def __init__(self, beta: Beta) -> None: self._beta = beta @cached_property def models(self) -> ModelsWithStreamingResponse: return ModelsWithStreamingResponse(self._beta.models) @cached_property def messages(self) -> MessagesWithStreamingResponse: return MessagesWithStreamingResponse(self._beta.messages) @cached_property def files(self) -> FilesWithStreamingResponse: return FilesWithStreamingResponse(self._beta.files) class AsyncBetaWithStreamingResponse: def __init__(self, beta: AsyncBeta) -> None: self._beta = beta @cached_property def models(self) -> AsyncModelsWithStreamingResponse: return AsyncModelsWithStreamingResponse(self._beta.models) @cached_property def messages(self) -> AsyncMessagesWithStreamingResponse: return AsyncMessagesWithStreamingResponse(self._beta.messages) @cached_property def files(self) -> AsyncFilesWithStreamingResponse: return AsyncFilesWithStreamingResponse(self._beta.files) anthropic-sdk-python-0.69.0/src/anthropic/resources/beta/files.py000066400000000000000000000642331506653454500250770ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import List, Mapping, cast from itertools import chain import httpx from ... import _legacy_response from ..._types import Body, Omit, Query, Headers, NotGiven, FileTypes, omit, not_given from ..._utils import is_given, extract_files, maybe_transform, strip_not_given, deepcopy_minimal, async_maybe_transform from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource from ..._response import ( BinaryAPIResponse, AsyncBinaryAPIResponse, StreamedBinaryAPIResponse, AsyncStreamedBinaryAPIResponse, to_streamed_response_wrapper, to_custom_raw_response_wrapper, async_to_streamed_response_wrapper, to_custom_streamed_response_wrapper, async_to_custom_raw_response_wrapper, async_to_custom_streamed_response_wrapper, ) from ...pagination import SyncPage, AsyncPage from ...types.beta import file_list_params, file_upload_params from ..._base_client import AsyncPaginator, make_request_options from ...types.beta.deleted_file import DeletedFile from ...types.beta.file_metadata import FileMetadata from ...types.anthropic_beta_param import AnthropicBetaParam __all__ = ["Files", "AsyncFiles"] class Files(SyncAPIResource): @cached_property def with_raw_response(self) -> FilesWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the raw response object instead of the parsed content. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers """ return FilesWithRawResponse(self) @cached_property def with_streaming_response(self) -> FilesWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response """ return FilesWithStreamingResponse(self) def list( self, *, after_id: str | Omit = omit, before_id: str | Omit = omit, limit: int | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncPage[FileMetadata]: """List Files Args: after_id: ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately after this object. before_id: ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately before this object. limit: Number of items to return per page. Defaults to `20`. Ranges from `1` to `1000`. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ extra_headers = { **strip_not_given( { "anthropic-beta": ",".join(chain((str(e) for e in betas), ["files-api-2025-04-14"])) if is_given(betas) else not_given } ), **(extra_headers or {}), } extra_headers = {"anthropic-beta": "files-api-2025-04-14", **(extra_headers or {})} return self._get_api_list( "/v1/files?beta=true", page=SyncPage[FileMetadata], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, query=maybe_transform( { "after_id": after_id, "before_id": before_id, "limit": limit, }, file_list_params.FileListParams, ), ), model=FileMetadata, ) def delete( self, file_id: str, *, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> DeletedFile: """ Delete File Args: file_id: ID of the File. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ if not file_id: raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}") extra_headers = { **strip_not_given( { "anthropic-beta": ",".join(chain((str(e) for e in betas), ["files-api-2025-04-14"])) if is_given(betas) else not_given } ), **(extra_headers or {}), } extra_headers = {"anthropic-beta": "files-api-2025-04-14", **(extra_headers or {})} return self._delete( f"/v1/files/{file_id}?beta=true", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=DeletedFile, ) def download( self, file_id: str, *, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BinaryAPIResponse: """ Download File Args: file_id: ID of the File. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ if not file_id: raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}") extra_headers = {"Accept": "application/binary", **(extra_headers or {})} extra_headers = { **strip_not_given( { "anthropic-beta": ",".join(chain((str(e) for e in betas), ["files-api-2025-04-14"])) if is_given(betas) else not_given } ), **(extra_headers or {}), } extra_headers = {"anthropic-beta": "files-api-2025-04-14", **(extra_headers or {})} return self._get( f"/v1/files/{file_id}/content?beta=true", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=BinaryAPIResponse, ) def retrieve_metadata( self, file_id: str, *, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> FileMetadata: """ Get File Metadata Args: file_id: ID of the File. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ if not file_id: raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}") extra_headers = { **strip_not_given( { "anthropic-beta": ",".join(chain((str(e) for e in betas), ["files-api-2025-04-14"])) if is_given(betas) else not_given } ), **(extra_headers or {}), } extra_headers = {"anthropic-beta": "files-api-2025-04-14", **(extra_headers or {})} return self._get( f"/v1/files/{file_id}?beta=true", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=FileMetadata, ) def upload( self, *, file: FileTypes, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> FileMetadata: """ Upload File Args: file: The file to upload betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ extra_headers = { **strip_not_given( { "anthropic-beta": ",".join(chain((str(e) for e in betas), ["files-api-2025-04-14"])) if is_given(betas) else not_given } ), **(extra_headers or {}), } extra_headers = {"anthropic-beta": "files-api-2025-04-14", **(extra_headers or {})} body = deepcopy_minimal({"file": file}) files = extract_files(cast(Mapping[str, object], body), paths=[["file"]]) # It should be noted that the actual Content-Type header that will be # sent to the server will contain a `boundary` parameter, e.g. # multipart/form-data; boundary=---abc-- extra_headers["Content-Type"] = "multipart/form-data" return self._post( "/v1/files?beta=true", body=maybe_transform(body, file_upload_params.FileUploadParams), files=files, options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=FileMetadata, ) class AsyncFiles(AsyncAPIResource): @cached_property def with_raw_response(self) -> AsyncFilesWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the raw response object instead of the parsed content. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers """ return AsyncFilesWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncFilesWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response """ return AsyncFilesWithStreamingResponse(self) def list( self, *, after_id: str | Omit = omit, before_id: str | Omit = omit, limit: int | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[FileMetadata, AsyncPage[FileMetadata]]: """List Files Args: after_id: ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately after this object. before_id: ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately before this object. limit: Number of items to return per page. Defaults to `20`. Ranges from `1` to `1000`. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ extra_headers = { **strip_not_given( { "anthropic-beta": ",".join(chain((str(e) for e in betas), ["files-api-2025-04-14"])) if is_given(betas) else not_given } ), **(extra_headers or {}), } extra_headers = {"anthropic-beta": "files-api-2025-04-14", **(extra_headers or {})} return self._get_api_list( "/v1/files?beta=true", page=AsyncPage[FileMetadata], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, query=maybe_transform( { "after_id": after_id, "before_id": before_id, "limit": limit, }, file_list_params.FileListParams, ), ), model=FileMetadata, ) async def delete( self, file_id: str, *, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> DeletedFile: """ Delete File Args: file_id: ID of the File. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ if not file_id: raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}") extra_headers = { **strip_not_given( { "anthropic-beta": ",".join(chain((str(e) for e in betas), ["files-api-2025-04-14"])) if is_given(betas) else not_given } ), **(extra_headers or {}), } extra_headers = {"anthropic-beta": "files-api-2025-04-14", **(extra_headers or {})} return await self._delete( f"/v1/files/{file_id}?beta=true", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=DeletedFile, ) async def download( self, file_id: str, *, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncBinaryAPIResponse: """ Download File Args: file_id: ID of the File. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ if not file_id: raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}") extra_headers = {"Accept": "application/binary", **(extra_headers or {})} extra_headers = { **strip_not_given( { "anthropic-beta": ",".join(chain((str(e) for e in betas), ["files-api-2025-04-14"])) if is_given(betas) else not_given } ), **(extra_headers or {}), } extra_headers = {"anthropic-beta": "files-api-2025-04-14", **(extra_headers or {})} return await self._get( f"/v1/files/{file_id}/content?beta=true", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=AsyncBinaryAPIResponse, ) async def retrieve_metadata( self, file_id: str, *, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> FileMetadata: """ Get File Metadata Args: file_id: ID of the File. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ if not file_id: raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}") extra_headers = { **strip_not_given( { "anthropic-beta": ",".join(chain((str(e) for e in betas), ["files-api-2025-04-14"])) if is_given(betas) else not_given } ), **(extra_headers or {}), } extra_headers = {"anthropic-beta": "files-api-2025-04-14", **(extra_headers or {})} return await self._get( f"/v1/files/{file_id}?beta=true", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=FileMetadata, ) async def upload( self, *, file: FileTypes, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> FileMetadata: """ Upload File Args: file: The file to upload betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ extra_headers = { **strip_not_given( { "anthropic-beta": ",".join(chain((str(e) for e in betas), ["files-api-2025-04-14"])) if is_given(betas) else not_given } ), **(extra_headers or {}), } extra_headers = {"anthropic-beta": "files-api-2025-04-14", **(extra_headers or {})} body = deepcopy_minimal({"file": file}) files = extract_files(cast(Mapping[str, object], body), paths=[["file"]]) # It should be noted that the actual Content-Type header that will be # sent to the server will contain a `boundary` parameter, e.g. # multipart/form-data; boundary=---abc-- extra_headers["Content-Type"] = "multipart/form-data" return await self._post( "/v1/files?beta=true", body=await async_maybe_transform(body, file_upload_params.FileUploadParams), files=files, options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=FileMetadata, ) class FilesWithRawResponse: def __init__(self, files: Files) -> None: self._files = files self.list = _legacy_response.to_raw_response_wrapper( files.list, ) self.delete = _legacy_response.to_raw_response_wrapper( files.delete, ) self.download = to_custom_raw_response_wrapper( files.download, BinaryAPIResponse, ) self.retrieve_metadata = _legacy_response.to_raw_response_wrapper( files.retrieve_metadata, ) self.upload = _legacy_response.to_raw_response_wrapper( files.upload, ) class AsyncFilesWithRawResponse: def __init__(self, files: AsyncFiles) -> None: self._files = files self.list = _legacy_response.async_to_raw_response_wrapper( files.list, ) self.delete = _legacy_response.async_to_raw_response_wrapper( files.delete, ) self.download = async_to_custom_raw_response_wrapper( files.download, AsyncBinaryAPIResponse, ) self.retrieve_metadata = _legacy_response.async_to_raw_response_wrapper( files.retrieve_metadata, ) self.upload = _legacy_response.async_to_raw_response_wrapper( files.upload, ) class FilesWithStreamingResponse: def __init__(self, files: Files) -> None: self._files = files self.list = to_streamed_response_wrapper( files.list, ) self.delete = to_streamed_response_wrapper( files.delete, ) self.download = to_custom_streamed_response_wrapper( files.download, StreamedBinaryAPIResponse, ) self.retrieve_metadata = to_streamed_response_wrapper( files.retrieve_metadata, ) self.upload = to_streamed_response_wrapper( files.upload, ) class AsyncFilesWithStreamingResponse: def __init__(self, files: AsyncFiles) -> None: self._files = files self.list = async_to_streamed_response_wrapper( files.list, ) self.delete = async_to_streamed_response_wrapper( files.delete, ) self.download = async_to_custom_streamed_response_wrapper( files.download, AsyncStreamedBinaryAPIResponse, ) self.retrieve_metadata = async_to_streamed_response_wrapper( files.retrieve_metadata, ) self.upload = async_to_streamed_response_wrapper( files.upload, ) anthropic-sdk-python-0.69.0/src/anthropic/resources/beta/messages/000077500000000000000000000000001506653454500252225ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/resources/beta/messages/__init__.py000066400000000000000000000015211506653454500273320ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from .batches import ( Batches, AsyncBatches, BatchesWithRawResponse, AsyncBatchesWithRawResponse, BatchesWithStreamingResponse, AsyncBatchesWithStreamingResponse, ) from .messages import ( Messages, AsyncMessages, MessagesWithRawResponse, AsyncMessagesWithRawResponse, MessagesWithStreamingResponse, AsyncMessagesWithStreamingResponse, ) __all__ = [ "Batches", "AsyncBatches", "BatchesWithRawResponse", "AsyncBatchesWithRawResponse", "BatchesWithStreamingResponse", "AsyncBatchesWithStreamingResponse", "Messages", "AsyncMessages", "MessagesWithRawResponse", "AsyncMessagesWithRawResponse", "MessagesWithStreamingResponse", "AsyncMessagesWithStreamingResponse", ] anthropic-sdk-python-0.69.0/src/anthropic/resources/beta/messages/batches.py000066400000000000000000001060001506653454500272020ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import List, Iterable from itertools import chain import httpx from .... import _legacy_response from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given from ...._utils import is_given, maybe_transform, strip_not_given, async_maybe_transform from ...._compat import cached_property from ...._resource import SyncAPIResource, AsyncAPIResource from ...._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper from ....pagination import SyncPage, AsyncPage from ...._exceptions import AnthropicError from ...._base_client import AsyncPaginator, make_request_options from ...._decoders.jsonl import JSONLDecoder, AsyncJSONLDecoder from ....types.beta.messages import batch_list_params, batch_create_params from ....types.anthropic_beta_param import AnthropicBetaParam from ....types.beta.messages.beta_message_batch import BetaMessageBatch from ....types.beta.messages.beta_deleted_message_batch import BetaDeletedMessageBatch from ....types.beta.messages.beta_message_batch_individual_response import BetaMessageBatchIndividualResponse __all__ = ["Batches", "AsyncBatches"] class Batches(SyncAPIResource): @cached_property def with_raw_response(self) -> BatchesWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the raw response object instead of the parsed content. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers """ return BatchesWithRawResponse(self) @cached_property def with_streaming_response(self) -> BatchesWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response """ return BatchesWithStreamingResponse(self) def create( self, *, requests: Iterable[batch_create_params.Request], betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BetaMessageBatch: """ Send a batch of Message creation requests. The Message Batches API can be used to process multiple Messages API requests at once. Once a Message Batch is created, it begins processing immediately. Batches can take up to 24 hours to complete. Learn more about the Message Batches API in our [user guide](/en/docs/build-with-claude/batch-processing) Args: requests: List of requests for prompt completion. Each is an individual request to create a Message. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ extra_headers = { **strip_not_given( { "anthropic-beta": ",".join(chain((str(e) for e in betas), ["message-batches-2024-09-24"])) if is_given(betas) else not_given } ), **(extra_headers or {}), } extra_headers = {"anthropic-beta": "message-batches-2024-09-24", **(extra_headers or {})} return self._post( "/v1/messages/batches?beta=true", body=maybe_transform({"requests": requests}, batch_create_params.BatchCreateParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=BetaMessageBatch, ) def retrieve( self, message_batch_id: str, *, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BetaMessageBatch: """This endpoint is idempotent and can be used to poll for Message Batch completion. To access the results of a Message Batch, make a request to the `results_url` field in the response. Learn more about the Message Batches API in our [user guide](/en/docs/build-with-claude/batch-processing) Args: message_batch_id: ID of the Message Batch. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ if not message_batch_id: raise ValueError(f"Expected a non-empty value for `message_batch_id` but received {message_batch_id!r}") extra_headers = { **strip_not_given( { "anthropic-beta": ",".join(chain((str(e) for e in betas), ["message-batches-2024-09-24"])) if is_given(betas) else not_given } ), **(extra_headers or {}), } extra_headers = {"anthropic-beta": "message-batches-2024-09-24", **(extra_headers or {})} return self._get( f"/v1/messages/batches/{message_batch_id}?beta=true", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=BetaMessageBatch, ) def list( self, *, after_id: str | Omit = omit, before_id: str | Omit = omit, limit: int | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncPage[BetaMessageBatch]: """List all Message Batches within a Workspace. Most recently created batches are returned first. Learn more about the Message Batches API in our [user guide](/en/docs/build-with-claude/batch-processing) Args: after_id: ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately after this object. before_id: ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately before this object. limit: Number of items to return per page. Defaults to `20`. Ranges from `1` to `1000`. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ extra_headers = { **strip_not_given( { "anthropic-beta": ",".join(chain((str(e) for e in betas), ["message-batches-2024-09-24"])) if is_given(betas) else not_given } ), **(extra_headers or {}), } extra_headers = {"anthropic-beta": "message-batches-2024-09-24", **(extra_headers or {})} return self._get_api_list( "/v1/messages/batches?beta=true", page=SyncPage[BetaMessageBatch], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, query=maybe_transform( { "after_id": after_id, "before_id": before_id, "limit": limit, }, batch_list_params.BatchListParams, ), ), model=BetaMessageBatch, ) def delete( self, message_batch_id: str, *, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BetaDeletedMessageBatch: """ Delete a Message Batch. Message Batches can only be deleted once they've finished processing. If you'd like to delete an in-progress batch, you must first cancel it. Learn more about the Message Batches API in our [user guide](/en/docs/build-with-claude/batch-processing) Args: message_batch_id: ID of the Message Batch. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ if not message_batch_id: raise ValueError(f"Expected a non-empty value for `message_batch_id` but received {message_batch_id!r}") extra_headers = { **strip_not_given( { "anthropic-beta": ",".join(chain((str(e) for e in betas), ["message-batches-2024-09-24"])) if is_given(betas) else not_given } ), **(extra_headers or {}), } extra_headers = {"anthropic-beta": "message-batches-2024-09-24", **(extra_headers or {})} return self._delete( f"/v1/messages/batches/{message_batch_id}?beta=true", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=BetaDeletedMessageBatch, ) def cancel( self, message_batch_id: str, *, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BetaMessageBatch: """Batches may be canceled any time before processing ends. Once cancellation is initiated, the batch enters a `canceling` state, at which time the system may complete any in-progress, non-interruptible requests before finalizing cancellation. The number of canceled requests is specified in `request_counts`. To determine which requests were canceled, check the individual results within the batch. Note that cancellation may not result in any canceled requests if they were non-interruptible. Learn more about the Message Batches API in our [user guide](/en/docs/build-with-claude/batch-processing) Args: message_batch_id: ID of the Message Batch. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ if not message_batch_id: raise ValueError(f"Expected a non-empty value for `message_batch_id` but received {message_batch_id!r}") extra_headers = { **strip_not_given( { "anthropic-beta": ",".join(chain((str(e) for e in betas), ["message-batches-2024-09-24"])) if is_given(betas) else not_given } ), **(extra_headers or {}), } extra_headers = {"anthropic-beta": "message-batches-2024-09-24", **(extra_headers or {})} return self._post( f"/v1/messages/batches/{message_batch_id}/cancel?beta=true", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=BetaMessageBatch, ) def results( self, message_batch_id: str, *, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> JSONLDecoder[BetaMessageBatchIndividualResponse]: """ Streams the results of a Message Batch as a `.jsonl` file. Each line in the file is a JSON object containing the result of a single request in the Message Batch. Results are not guaranteed to be in the same order as requests. Use the `custom_id` field to match results to requests. Learn more about the Message Batches API in our [user guide](/en/docs/build-with-claude/batch-processing) Args: message_batch_id: ID of the Message Batch. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ if not message_batch_id: raise ValueError(f"Expected a non-empty value for `message_batch_id` but received {message_batch_id!r}") batch = self.retrieve(message_batch_id=message_batch_id) if not batch.results_url: raise AnthropicError( f"No `results_url` for the given batch; Has it finished processing? {batch.processing_status}" ) extra_headers = {"Accept": "application/binary", **(extra_headers or {})} extra_headers = { **strip_not_given( { "anthropic-beta": ",".join(chain((str(e) for e in betas), ["message-batches-2024-09-24"])) if is_given(betas) else not_given } ), **(extra_headers or {}), } extra_headers = {"anthropic-beta": "message-batches-2024-09-24", **(extra_headers or {})} return self._get( batch.results_url, options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=JSONLDecoder[BetaMessageBatchIndividualResponse], stream=True, ) class AsyncBatches(AsyncAPIResource): @cached_property def with_raw_response(self) -> AsyncBatchesWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the raw response object instead of the parsed content. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers """ return AsyncBatchesWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncBatchesWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response """ return AsyncBatchesWithStreamingResponse(self) async def create( self, *, requests: Iterable[batch_create_params.Request], betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BetaMessageBatch: """ Send a batch of Message creation requests. The Message Batches API can be used to process multiple Messages API requests at once. Once a Message Batch is created, it begins processing immediately. Batches can take up to 24 hours to complete. Learn more about the Message Batches API in our [user guide](/en/docs/build-with-claude/batch-processing) Args: requests: List of requests for prompt completion. Each is an individual request to create a Message. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ extra_headers = { **strip_not_given( { "anthropic-beta": ",".join(chain((str(e) for e in betas), ["message-batches-2024-09-24"])) if is_given(betas) else not_given } ), **(extra_headers or {}), } extra_headers = {"anthropic-beta": "message-batches-2024-09-24", **(extra_headers or {})} return await self._post( "/v1/messages/batches?beta=true", body=await async_maybe_transform({"requests": requests}, batch_create_params.BatchCreateParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=BetaMessageBatch, ) async def retrieve( self, message_batch_id: str, *, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BetaMessageBatch: """This endpoint is idempotent and can be used to poll for Message Batch completion. To access the results of a Message Batch, make a request to the `results_url` field in the response. Learn more about the Message Batches API in our [user guide](/en/docs/build-with-claude/batch-processing) Args: message_batch_id: ID of the Message Batch. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ if not message_batch_id: raise ValueError(f"Expected a non-empty value for `message_batch_id` but received {message_batch_id!r}") extra_headers = { **strip_not_given( { "anthropic-beta": ",".join(chain((str(e) for e in betas), ["message-batches-2024-09-24"])) if is_given(betas) else not_given } ), **(extra_headers or {}), } extra_headers = {"anthropic-beta": "message-batches-2024-09-24", **(extra_headers or {})} return await self._get( f"/v1/messages/batches/{message_batch_id}?beta=true", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=BetaMessageBatch, ) def list( self, *, after_id: str | Omit = omit, before_id: str | Omit = omit, limit: int | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[BetaMessageBatch, AsyncPage[BetaMessageBatch]]: """List all Message Batches within a Workspace. Most recently created batches are returned first. Learn more about the Message Batches API in our [user guide](/en/docs/build-with-claude/batch-processing) Args: after_id: ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately after this object. before_id: ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately before this object. limit: Number of items to return per page. Defaults to `20`. Ranges from `1` to `1000`. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ extra_headers = { **strip_not_given( { "anthropic-beta": ",".join(chain((str(e) for e in betas), ["message-batches-2024-09-24"])) if is_given(betas) else not_given } ), **(extra_headers or {}), } extra_headers = {"anthropic-beta": "message-batches-2024-09-24", **(extra_headers or {})} return self._get_api_list( "/v1/messages/batches?beta=true", page=AsyncPage[BetaMessageBatch], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, query=maybe_transform( { "after_id": after_id, "before_id": before_id, "limit": limit, }, batch_list_params.BatchListParams, ), ), model=BetaMessageBatch, ) async def delete( self, message_batch_id: str, *, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BetaDeletedMessageBatch: """ Delete a Message Batch. Message Batches can only be deleted once they've finished processing. If you'd like to delete an in-progress batch, you must first cancel it. Learn more about the Message Batches API in our [user guide](/en/docs/build-with-claude/batch-processing) Args: message_batch_id: ID of the Message Batch. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ if not message_batch_id: raise ValueError(f"Expected a non-empty value for `message_batch_id` but received {message_batch_id!r}") extra_headers = { **strip_not_given( { "anthropic-beta": ",".join(chain((str(e) for e in betas), ["message-batches-2024-09-24"])) if is_given(betas) else not_given } ), **(extra_headers or {}), } extra_headers = {"anthropic-beta": "message-batches-2024-09-24", **(extra_headers or {})} return await self._delete( f"/v1/messages/batches/{message_batch_id}?beta=true", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=BetaDeletedMessageBatch, ) async def cancel( self, message_batch_id: str, *, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BetaMessageBatch: """Batches may be canceled any time before processing ends. Once cancellation is initiated, the batch enters a `canceling` state, at which time the system may complete any in-progress, non-interruptible requests before finalizing cancellation. The number of canceled requests is specified in `request_counts`. To determine which requests were canceled, check the individual results within the batch. Note that cancellation may not result in any canceled requests if they were non-interruptible. Learn more about the Message Batches API in our [user guide](/en/docs/build-with-claude/batch-processing) Args: message_batch_id: ID of the Message Batch. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ if not message_batch_id: raise ValueError(f"Expected a non-empty value for `message_batch_id` but received {message_batch_id!r}") extra_headers = { **strip_not_given( { "anthropic-beta": ",".join(chain((str(e) for e in betas), ["message-batches-2024-09-24"])) if is_given(betas) else not_given } ), **(extra_headers or {}), } extra_headers = {"anthropic-beta": "message-batches-2024-09-24", **(extra_headers or {})} return await self._post( f"/v1/messages/batches/{message_batch_id}/cancel?beta=true", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=BetaMessageBatch, ) async def results( self, message_batch_id: str, *, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncJSONLDecoder[BetaMessageBatchIndividualResponse]: """ Streams the results of a Message Batch as a `.jsonl` file. Each line in the file is a JSON object containing the result of a single request in the Message Batch. Results are not guaranteed to be in the same order as requests. Use the `custom_id` field to match results to requests. Learn more about the Message Batches API in our [user guide](/en/docs/build-with-claude/batch-processing) Args: message_batch_id: ID of the Message Batch. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ if not message_batch_id: raise ValueError(f"Expected a non-empty value for `message_batch_id` but received {message_batch_id!r}") batch = await self.retrieve(message_batch_id=message_batch_id) if not batch.results_url: raise AnthropicError( f"No `results_url` for the given batch; Has it finished processing? {batch.processing_status}" ) extra_headers = {"Accept": "application/binary", **(extra_headers or {})} extra_headers = { **strip_not_given( { "anthropic-beta": ",".join(chain((str(e) for e in betas), ["message-batches-2024-09-24"])) if is_given(betas) else not_given } ), **(extra_headers or {}), } extra_headers = {"anthropic-beta": "message-batches-2024-09-24", **(extra_headers or {})} return await self._get( batch.results_url, options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=AsyncJSONLDecoder[BetaMessageBatchIndividualResponse], stream=True, ) class BatchesWithRawResponse: def __init__(self, batches: Batches) -> None: self._batches = batches self.create = _legacy_response.to_raw_response_wrapper( batches.create, ) self.retrieve = _legacy_response.to_raw_response_wrapper( batches.retrieve, ) self.list = _legacy_response.to_raw_response_wrapper( batches.list, ) self.delete = _legacy_response.to_raw_response_wrapper( batches.delete, ) self.cancel = _legacy_response.to_raw_response_wrapper( batches.cancel, ) class AsyncBatchesWithRawResponse: def __init__(self, batches: AsyncBatches) -> None: self._batches = batches self.create = _legacy_response.async_to_raw_response_wrapper( batches.create, ) self.retrieve = _legacy_response.async_to_raw_response_wrapper( batches.retrieve, ) self.list = _legacy_response.async_to_raw_response_wrapper( batches.list, ) self.delete = _legacy_response.async_to_raw_response_wrapper( batches.delete, ) self.cancel = _legacy_response.async_to_raw_response_wrapper( batches.cancel, ) class BatchesWithStreamingResponse: def __init__(self, batches: Batches) -> None: self._batches = batches self.create = to_streamed_response_wrapper( batches.create, ) self.retrieve = to_streamed_response_wrapper( batches.retrieve, ) self.list = to_streamed_response_wrapper( batches.list, ) self.delete = to_streamed_response_wrapper( batches.delete, ) self.cancel = to_streamed_response_wrapper( batches.cancel, ) class AsyncBatchesWithStreamingResponse: def __init__(self, batches: AsyncBatches) -> None: self._batches = batches self.create = async_to_streamed_response_wrapper( batches.create, ) self.retrieve = async_to_streamed_response_wrapper( batches.retrieve, ) self.list = async_to_streamed_response_wrapper( batches.list, ) self.delete = async_to_streamed_response_wrapper( batches.delete, ) self.cancel = async_to_streamed_response_wrapper( batches.cancel, ) anthropic-sdk-python-0.69.0/src/anthropic/resources/beta/messages/messages.py000066400000000000000000004056041506653454500274140ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations import warnings from typing import TYPE_CHECKING, List, Union, Iterable, Optional, cast from functools import partial from itertools import chain from typing_extensions import Literal, overload import httpx from .... import _legacy_response from .batches import ( Batches, AsyncBatches, BatchesWithRawResponse, AsyncBatchesWithRawResponse, BatchesWithStreamingResponse, AsyncBatchesWithStreamingResponse, ) from ...._types import NOT_GIVEN, Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given from ...._utils import is_given, required_args, maybe_transform, strip_not_given, async_maybe_transform from ...._compat import cached_property from ...._resource import SyncAPIResource, AsyncAPIResource from ...._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper from ....lib.tools import ( BetaToolRunner, BetaAsyncToolRunner, BetaStreamingToolRunner, BetaAsyncStreamingToolRunner, ) from ...._constants import DEFAULT_TIMEOUT, MODEL_NONSTREAMING_TOKENS from ...._streaming import Stream, AsyncStream from ....types.beta import ( BetaThinkingConfigParam, message_create_params, message_count_tokens_params, ) from ...._base_client import make_request_options from ....lib.streaming import BetaMessageStreamManager, BetaAsyncMessageStreamManager from ...messages.messages import DEPRECATED_MODELS from ....types.model_param import ModelParam from ....types.beta.beta_message import BetaMessage from ....lib.tools._beta_functions import BetaRunnableTool, BetaAsyncRunnableTool from ....types.anthropic_beta_param import AnthropicBetaParam from ....types.beta.beta_message_param import BetaMessageParam from ....types.beta.beta_metadata_param import BetaMetadataParam from ....types.beta.beta_text_block_param import BetaTextBlockParam from ....types.beta.beta_tool_union_param import BetaToolUnionParam from ....types.beta.beta_tool_choice_param import BetaToolChoiceParam from ....types.beta.beta_message_tokens_count import BetaMessageTokensCount from ....types.beta.beta_thinking_config_param import BetaThinkingConfigParam from ....types.beta.beta_raw_message_stream_event import BetaRawMessageStreamEvent from ....types.beta.beta_context_management_config_param import BetaContextManagementConfigParam from ....types.beta.beta_request_mcp_server_url_definition_param import BetaRequestMCPServerURLDefinitionParam if TYPE_CHECKING: from ...._client import Anthropic, AsyncAnthropic __all__ = ["Messages", "AsyncMessages"] class Messages(SyncAPIResource): @cached_property def batches(self) -> Batches: return Batches(self._client) @cached_property def with_raw_response(self) -> MessagesWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the raw response object instead of the parsed content. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers """ return MessagesWithRawResponse(self) @cached_property def with_streaming_response(self) -> MessagesWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response """ return MessagesWithStreamingResponse(self) @overload def create( self, *, max_tokens: int, messages: Iterable[BetaMessageParam], model: ModelParam, container: Optional[str] | Omit = omit, context_management: Optional[BetaContextManagementConfigParam] | Omit = omit, mcp_servers: Iterable[BetaRequestMCPServerURLDefinitionParam] | Omit = omit, metadata: BetaMetadataParam | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, stream: Literal[False] | Omit = omit, system: Union[str, Iterable[BetaTextBlockParam]] | Omit = omit, temperature: float | Omit = omit, thinking: BetaThinkingConfigParam | Omit = omit, tool_choice: BetaToolChoiceParam | Omit = omit, tools: Iterable[BetaToolUnionParam] | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BetaMessage: """ Send a structured list of input messages with text and/or image content, and the model will generate the next message in the conversation. The Messages API can be used for either single queries or stateless multi-turn conversations. Learn more about the Messages API in our [user guide](/en/docs/initial-setup) Args: max_tokens: The maximum number of tokens to generate before stopping. Note that our models may stop _before_ reaching this maximum. This parameter only specifies the absolute maximum number of tokens to generate. Different models have different maximum values for this parameter. See [models](https://docs.anthropic.com/en/docs/models-overview) for details. messages: Input messages. Our models are trained to operate on alternating `user` and `assistant` conversational turns. When creating a new `Message`, you specify the prior conversational turns with the `messages` parameter, and the model then generates the next `Message` in the conversation. Consecutive `user` or `assistant` turns in your request will be combined into a single turn. Each input message must be an object with a `role` and `content`. You can specify a single `user`-role message, or you can include multiple `user` and `assistant` messages. If the final message uses the `assistant` role, the response content will continue immediately from the content in that message. This can be used to constrain part of the model's response. Example with a single `user` message: ```json [{ "role": "user", "content": "Hello, Claude" }] ``` Example with multiple conversational turns: ```json [ { "role": "user", "content": "Hello there." }, { "role": "assistant", "content": "Hi, I'm Claude. How can I help you?" }, { "role": "user", "content": "Can you explain LLMs in plain English?" } ] ``` Example with a partially-filled response from Claude: ```json [ { "role": "user", "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun" }, { "role": "assistant", "content": "The best answer is (" } ] ``` Each input message `content` may be either a single `string` or an array of content blocks, where each block has a specific `type`. Using a `string` for `content` is shorthand for an array of one content block of type `"text"`. The following input messages are equivalent: ```json { "role": "user", "content": "Hello, Claude" } ``` ```json { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } ``` See [input examples](https://docs.anthropic.com/en/api/messages-examples). Note that if you want to include a [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use the top-level `system` parameter — there is no `"system"` role for input messages in the Messages API. There is a limit of 100,000 messages in a single request. model: The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. container: Container identifier for reuse across requests. context_management: Configuration for context management operations. mcp_servers: MCP servers to be utilized in this request metadata: An object describing metadata about the request. service_tier: Determines whether to use priority capacity (if available) or standard capacity for this request. Anthropic offers different levels of service for your API requests. See [service-tiers](https://docs.anthropic.com/en/api/service-tiers) for details. stop_sequences: Custom text sequences that will cause the model to stop generating. Our models will normally stop when they have naturally completed their turn, which will result in a response `stop_reason` of `"end_turn"`. If you want the model to stop generating when it encounters custom strings of text, you can use the `stop_sequences` parameter. If the model encounters one of the custom sequences, the response `stop_reason` value will be `"stop_sequence"` and the response `stop_sequence` value will contain the matched stop sequence. stream: Whether to incrementally stream the response using server-sent events. See [streaming](https://docs.anthropic.com/en/api/messages-streaming) for details. system: System prompt. A system prompt is a way of providing context and instructions to Claude, such as specifying a particular goal or role. See our [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts). temperature: Amount of randomness injected into the response. Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0` for analytical / multiple choice, and closer to `1.0` for creative and generative tasks. Note that even with `temperature` of `0.0`, the results will not be fully deterministic. thinking: Configuration for enabling Claude's extended thinking. When enabled, responses include `thinking` content blocks showing Claude's thinking process before the final answer. Requires a minimum budget of 1,024 tokens and counts towards your `max_tokens` limit. See [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) for details. tool_choice: How the model should use the provided tools. The model can use a specific tool, any available tool, decide by itself, or not use tools at all. tools: Definitions of tools that the model may use. If you include `tools` in your API request, the model may return `tool_use` content blocks that represent the model's use of those tools. You can then run those tools using the tool input generated by the model and then optionally return results back to the model using `tool_result` content blocks. There are two types of tools: **client tools** and **server tools**. The behavior described below applies to client tools. For [server tools](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#server-tools), see their individual documentation as each has its own behavior (e.g., the [web search tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool)). Each tool definition includes: - `name`: Name of the tool. - `description`: Optional, but strongly-recommended description of the tool. - `input_schema`: [JSON schema](https://json-schema.org/draft/2020-12) for the tool `input` shape that the model will produce in `tool_use` output content blocks. For example, if you defined `tools` as: ```json [ { "name": "get_stock_price", "description": "Get the current stock price for a given ticker symbol.", "input_schema": { "type": "object", "properties": { "ticker": { "type": "string", "description": "The stock ticker symbol, e.g. AAPL for Apple Inc." } }, "required": ["ticker"] } } ] ``` And then asked the model "What's the S&P 500 at today?", the model might produce `tool_use` content blocks in the response like this: ```json [ { "type": "tool_use", "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "name": "get_stock_price", "input": { "ticker": "^GSPC" } } ] ``` You might then run your `get_stock_price` tool with `{"ticker": "^GSPC"}` as an input, and return the following back to the model in a subsequent `user` message: ```json [ { "type": "tool_result", "tool_use_id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "content": "259.75 USD" } ] ``` Tools can be used for workflows that include running client-side tools and functions, or more generally whenever you want the model to produce a particular JSON structure of output. See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. top_k: Only sample from the top K options for each subsequent token. Used to remove "long tail" low probability responses. [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277). Recommended for advanced use cases only. You usually only need to use `temperature`. top_p: Use nucleus sampling. In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by `top_p`. You should either alter `temperature` or `top_p`, but not both. Recommended for advanced use cases only. You usually only need to use `temperature`. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ ... @overload def create( self, *, max_tokens: int, messages: Iterable[BetaMessageParam], model: ModelParam, stream: Literal[True], container: Optional[str] | Omit = omit, context_management: Optional[BetaContextManagementConfigParam] | Omit = omit, mcp_servers: Iterable[BetaRequestMCPServerURLDefinitionParam] | Omit = omit, metadata: BetaMetadataParam | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, system: Union[str, Iterable[BetaTextBlockParam]] | Omit = omit, temperature: float | Omit = omit, thinking: BetaThinkingConfigParam | Omit = omit, tool_choice: BetaToolChoiceParam | Omit = omit, tools: Iterable[BetaToolUnionParam] | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Stream[BetaRawMessageStreamEvent]: """ Send a structured list of input messages with text and/or image content, and the model will generate the next message in the conversation. The Messages API can be used for either single queries or stateless multi-turn conversations. Learn more about the Messages API in our [user guide](/en/docs/initial-setup) Args: max_tokens: The maximum number of tokens to generate before stopping. Note that our models may stop _before_ reaching this maximum. This parameter only specifies the absolute maximum number of tokens to generate. Different models have different maximum values for this parameter. See [models](https://docs.anthropic.com/en/docs/models-overview) for details. messages: Input messages. Our models are trained to operate on alternating `user` and `assistant` conversational turns. When creating a new `Message`, you specify the prior conversational turns with the `messages` parameter, and the model then generates the next `Message` in the conversation. Consecutive `user` or `assistant` turns in your request will be combined into a single turn. Each input message must be an object with a `role` and `content`. You can specify a single `user`-role message, or you can include multiple `user` and `assistant` messages. If the final message uses the `assistant` role, the response content will continue immediately from the content in that message. This can be used to constrain part of the model's response. Example with a single `user` message: ```json [{ "role": "user", "content": "Hello, Claude" }] ``` Example with multiple conversational turns: ```json [ { "role": "user", "content": "Hello there." }, { "role": "assistant", "content": "Hi, I'm Claude. How can I help you?" }, { "role": "user", "content": "Can you explain LLMs in plain English?" } ] ``` Example with a partially-filled response from Claude: ```json [ { "role": "user", "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun" }, { "role": "assistant", "content": "The best answer is (" } ] ``` Each input message `content` may be either a single `string` or an array of content blocks, where each block has a specific `type`. Using a `string` for `content` is shorthand for an array of one content block of type `"text"`. The following input messages are equivalent: ```json { "role": "user", "content": "Hello, Claude" } ``` ```json { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } ``` See [input examples](https://docs.anthropic.com/en/api/messages-examples). Note that if you want to include a [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use the top-level `system` parameter — there is no `"system"` role for input messages in the Messages API. There is a limit of 100,000 messages in a single request. model: The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. stream: Whether to incrementally stream the response using server-sent events. See [streaming](https://docs.anthropic.com/en/api/messages-streaming) for details. container: Container identifier for reuse across requests. context_management: Configuration for context management operations. mcp_servers: MCP servers to be utilized in this request metadata: An object describing metadata about the request. service_tier: Determines whether to use priority capacity (if available) or standard capacity for this request. Anthropic offers different levels of service for your API requests. See [service-tiers](https://docs.anthropic.com/en/api/service-tiers) for details. stop_sequences: Custom text sequences that will cause the model to stop generating. Our models will normally stop when they have naturally completed their turn, which will result in a response `stop_reason` of `"end_turn"`. If you want the model to stop generating when it encounters custom strings of text, you can use the `stop_sequences` parameter. If the model encounters one of the custom sequences, the response `stop_reason` value will be `"stop_sequence"` and the response `stop_sequence` value will contain the matched stop sequence. system: System prompt. A system prompt is a way of providing context and instructions to Claude, such as specifying a particular goal or role. See our [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts). temperature: Amount of randomness injected into the response. Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0` for analytical / multiple choice, and closer to `1.0` for creative and generative tasks. Note that even with `temperature` of `0.0`, the results will not be fully deterministic. thinking: Configuration for enabling Claude's extended thinking. When enabled, responses include `thinking` content blocks showing Claude's thinking process before the final answer. Requires a minimum budget of 1,024 tokens and counts towards your `max_tokens` limit. See [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) for details. tool_choice: How the model should use the provided tools. The model can use a specific tool, any available tool, decide by itself, or not use tools at all. tools: Definitions of tools that the model may use. If you include `tools` in your API request, the model may return `tool_use` content blocks that represent the model's use of those tools. You can then run those tools using the tool input generated by the model and then optionally return results back to the model using `tool_result` content blocks. There are two types of tools: **client tools** and **server tools**. The behavior described below applies to client tools. For [server tools](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#server-tools), see their individual documentation as each has its own behavior (e.g., the [web search tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool)). Each tool definition includes: - `name`: Name of the tool. - `description`: Optional, but strongly-recommended description of the tool. - `input_schema`: [JSON schema](https://json-schema.org/draft/2020-12) for the tool `input` shape that the model will produce in `tool_use` output content blocks. For example, if you defined `tools` as: ```json [ { "name": "get_stock_price", "description": "Get the current stock price for a given ticker symbol.", "input_schema": { "type": "object", "properties": { "ticker": { "type": "string", "description": "The stock ticker symbol, e.g. AAPL for Apple Inc." } }, "required": ["ticker"] } } ] ``` And then asked the model "What's the S&P 500 at today?", the model might produce `tool_use` content blocks in the response like this: ```json [ { "type": "tool_use", "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "name": "get_stock_price", "input": { "ticker": "^GSPC" } } ] ``` You might then run your `get_stock_price` tool with `{"ticker": "^GSPC"}` as an input, and return the following back to the model in a subsequent `user` message: ```json [ { "type": "tool_result", "tool_use_id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "content": "259.75 USD" } ] ``` Tools can be used for workflows that include running client-side tools and functions, or more generally whenever you want the model to produce a particular JSON structure of output. See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. top_k: Only sample from the top K options for each subsequent token. Used to remove "long tail" low probability responses. [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277). Recommended for advanced use cases only. You usually only need to use `temperature`. top_p: Use nucleus sampling. In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by `top_p`. You should either alter `temperature` or `top_p`, but not both. Recommended for advanced use cases only. You usually only need to use `temperature`. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ ... @overload def create( self, *, max_tokens: int, messages: Iterable[BetaMessageParam], model: ModelParam, stream: bool, container: Optional[str] | Omit = omit, context_management: Optional[BetaContextManagementConfigParam] | Omit = omit, mcp_servers: Iterable[BetaRequestMCPServerURLDefinitionParam] | Omit = omit, metadata: BetaMetadataParam | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, system: Union[str, Iterable[BetaTextBlockParam]] | Omit = omit, temperature: float | Omit = omit, thinking: BetaThinkingConfigParam | Omit = omit, tool_choice: BetaToolChoiceParam | Omit = omit, tools: Iterable[BetaToolUnionParam] | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BetaMessage | Stream[BetaRawMessageStreamEvent]: """ Send a structured list of input messages with text and/or image content, and the model will generate the next message in the conversation. The Messages API can be used for either single queries or stateless multi-turn conversations. Learn more about the Messages API in our [user guide](/en/docs/initial-setup) Args: max_tokens: The maximum number of tokens to generate before stopping. Note that our models may stop _before_ reaching this maximum. This parameter only specifies the absolute maximum number of tokens to generate. Different models have different maximum values for this parameter. See [models](https://docs.anthropic.com/en/docs/models-overview) for details. messages: Input messages. Our models are trained to operate on alternating `user` and `assistant` conversational turns. When creating a new `Message`, you specify the prior conversational turns with the `messages` parameter, and the model then generates the next `Message` in the conversation. Consecutive `user` or `assistant` turns in your request will be combined into a single turn. Each input message must be an object with a `role` and `content`. You can specify a single `user`-role message, or you can include multiple `user` and `assistant` messages. If the final message uses the `assistant` role, the response content will continue immediately from the content in that message. This can be used to constrain part of the model's response. Example with a single `user` message: ```json [{ "role": "user", "content": "Hello, Claude" }] ``` Example with multiple conversational turns: ```json [ { "role": "user", "content": "Hello there." }, { "role": "assistant", "content": "Hi, I'm Claude. How can I help you?" }, { "role": "user", "content": "Can you explain LLMs in plain English?" } ] ``` Example with a partially-filled response from Claude: ```json [ { "role": "user", "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun" }, { "role": "assistant", "content": "The best answer is (" } ] ``` Each input message `content` may be either a single `string` or an array of content blocks, where each block has a specific `type`. Using a `string` for `content` is shorthand for an array of one content block of type `"text"`. The following input messages are equivalent: ```json { "role": "user", "content": "Hello, Claude" } ``` ```json { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } ``` See [input examples](https://docs.anthropic.com/en/api/messages-examples). Note that if you want to include a [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use the top-level `system` parameter — there is no `"system"` role for input messages in the Messages API. There is a limit of 100,000 messages in a single request. model: The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. stream: Whether to incrementally stream the response using server-sent events. See [streaming](https://docs.anthropic.com/en/api/messages-streaming) for details. container: Container identifier for reuse across requests. context_management: Configuration for context management operations. mcp_servers: MCP servers to be utilized in this request metadata: An object describing metadata about the request. service_tier: Determines whether to use priority capacity (if available) or standard capacity for this request. Anthropic offers different levels of service for your API requests. See [service-tiers](https://docs.anthropic.com/en/api/service-tiers) for details. stop_sequences: Custom text sequences that will cause the model to stop generating. Our models will normally stop when they have naturally completed their turn, which will result in a response `stop_reason` of `"end_turn"`. If you want the model to stop generating when it encounters custom strings of text, you can use the `stop_sequences` parameter. If the model encounters one of the custom sequences, the response `stop_reason` value will be `"stop_sequence"` and the response `stop_sequence` value will contain the matched stop sequence. system: System prompt. A system prompt is a way of providing context and instructions to Claude, such as specifying a particular goal or role. See our [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts). temperature: Amount of randomness injected into the response. Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0` for analytical / multiple choice, and closer to `1.0` for creative and generative tasks. Note that even with `temperature` of `0.0`, the results will not be fully deterministic. thinking: Configuration for enabling Claude's extended thinking. When enabled, responses include `thinking` content blocks showing Claude's thinking process before the final answer. Requires a minimum budget of 1,024 tokens and counts towards your `max_tokens` limit. See [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) for details. tool_choice: How the model should use the provided tools. The model can use a specific tool, any available tool, decide by itself, or not use tools at all. tools: Definitions of tools that the model may use. If you include `tools` in your API request, the model may return `tool_use` content blocks that represent the model's use of those tools. You can then run those tools using the tool input generated by the model and then optionally return results back to the model using `tool_result` content blocks. There are two types of tools: **client tools** and **server tools**. The behavior described below applies to client tools. For [server tools](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#server-tools), see their individual documentation as each has its own behavior (e.g., the [web search tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool)). Each tool definition includes: - `name`: Name of the tool. - `description`: Optional, but strongly-recommended description of the tool. - `input_schema`: [JSON schema](https://json-schema.org/draft/2020-12) for the tool `input` shape that the model will produce in `tool_use` output content blocks. For example, if you defined `tools` as: ```json [ { "name": "get_stock_price", "description": "Get the current stock price for a given ticker symbol.", "input_schema": { "type": "object", "properties": { "ticker": { "type": "string", "description": "The stock ticker symbol, e.g. AAPL for Apple Inc." } }, "required": ["ticker"] } } ] ``` And then asked the model "What's the S&P 500 at today?", the model might produce `tool_use` content blocks in the response like this: ```json [ { "type": "tool_use", "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "name": "get_stock_price", "input": { "ticker": "^GSPC" } } ] ``` You might then run your `get_stock_price` tool with `{"ticker": "^GSPC"}` as an input, and return the following back to the model in a subsequent `user` message: ```json [ { "type": "tool_result", "tool_use_id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "content": "259.75 USD" } ] ``` Tools can be used for workflows that include running client-side tools and functions, or more generally whenever you want the model to produce a particular JSON structure of output. See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. top_k: Only sample from the top K options for each subsequent token. Used to remove "long tail" low probability responses. [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277). Recommended for advanced use cases only. You usually only need to use `temperature`. top_p: Use nucleus sampling. In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by `top_p`. You should either alter `temperature` or `top_p`, but not both. Recommended for advanced use cases only. You usually only need to use `temperature`. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ ... @required_args(["max_tokens", "messages", "model"], ["max_tokens", "messages", "model", "stream"]) def create( self, *, max_tokens: int, messages: Iterable[BetaMessageParam], model: ModelParam, container: Optional[str] | Omit = omit, context_management: Optional[BetaContextManagementConfigParam] | Omit = omit, mcp_servers: Iterable[BetaRequestMCPServerURLDefinitionParam] | Omit = omit, metadata: BetaMetadataParam | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, stream: Literal[False] | Literal[True] | Omit = omit, system: Union[str, Iterable[BetaTextBlockParam]] | Omit = omit, temperature: float | Omit = omit, thinking: BetaThinkingConfigParam | Omit = omit, tool_choice: BetaToolChoiceParam | Omit = omit, tools: Iterable[BetaToolUnionParam] | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BetaMessage | Stream[BetaRawMessageStreamEvent]: if not stream and not is_given(timeout) and self._client.timeout == DEFAULT_TIMEOUT: timeout = self._client._calculate_nonstreaming_timeout( max_tokens, MODEL_NONSTREAMING_TOKENS.get(model, None) ) if model in DEPRECATED_MODELS: warnings.warn( f"The model '{model}' is deprecated and will reach end-of-life on {DEPRECATED_MODELS[model]}.\nPlease migrate to a newer model. Visit https://docs.anthropic.com/en/docs/resources/model-deprecations for more information.", DeprecationWarning, stacklevel=3, ) extra_headers = { **strip_not_given({"anthropic-beta": ",".join(str(e) for e in betas) if is_given(betas) else not_given}), **(extra_headers or {}), } return self._post( "/v1/messages?beta=true", body=maybe_transform( { "max_tokens": max_tokens, "messages": messages, "model": model, "container": container, "context_management": context_management, "mcp_servers": mcp_servers, "metadata": metadata, "service_tier": service_tier, "stop_sequences": stop_sequences, "stream": stream, "system": system, "temperature": temperature, "thinking": thinking, "tool_choice": tool_choice, "tools": tools, "top_k": top_k, "top_p": top_p, }, message_create_params.MessageCreateParamsStreaming if stream else message_create_params.MessageCreateParamsNonStreaming, ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=BetaMessage, stream=stream or False, stream_cls=Stream[BetaRawMessageStreamEvent], ) @overload def tool_runner( self, *, max_tokens: int, messages: Iterable[BetaMessageParam], model: ModelParam, tools: Iterable[BetaRunnableTool], max_iterations: int | Omit = omit, container: Optional[str] | Omit = omit, context_management: Optional[BetaContextManagementConfigParam] | Omit = omit, mcp_servers: Iterable[BetaRequestMCPServerURLDefinitionParam] | Omit = omit, metadata: BetaMetadataParam | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, stream: Literal[False] | Omit = omit, system: Union[str, Iterable[BetaTextBlockParam]] | Omit = omit, temperature: float | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, thinking: BetaThinkingConfigParam | Omit = omit, tool_choice: BetaToolChoiceParam | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, ) -> BetaToolRunner: ... @overload def tool_runner( self, *, max_tokens: int, messages: Iterable[BetaMessageParam], model: ModelParam, tools: Iterable[BetaRunnableTool], stream: Literal[True], max_iterations: int | Omit = omit, container: Optional[str] | Omit = omit, context_management: Optional[BetaContextManagementConfigParam] | Omit = omit, mcp_servers: Iterable[BetaRequestMCPServerURLDefinitionParam] | Omit = omit, metadata: BetaMetadataParam | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, system: Union[str, Iterable[BetaTextBlockParam]] | Omit = omit, temperature: float | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, thinking: BetaThinkingConfigParam | Omit = omit, tool_choice: BetaToolChoiceParam | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, ) -> BetaStreamingToolRunner: ... @overload def tool_runner( self, *, max_tokens: int, messages: Iterable[BetaMessageParam], model: ModelParam, tools: Iterable[BetaRunnableTool], stream: bool, max_iterations: int | Omit = omit, container: Optional[str] | Omit = omit, context_management: Optional[BetaContextManagementConfigParam] | Omit = omit, mcp_servers: Iterable[BetaRequestMCPServerURLDefinitionParam] | Omit = omit, metadata: BetaMetadataParam | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, system: Union[str, Iterable[BetaTextBlockParam]] | Omit = omit, temperature: float | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, thinking: BetaThinkingConfigParam | Omit = omit, tool_choice: BetaToolChoiceParam | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, ) -> BetaStreamingToolRunner | BetaToolRunner: ... def tool_runner( self, *, max_tokens: int, messages: Iterable[BetaMessageParam], model: ModelParam, tools: Iterable[BetaRunnableTool], max_iterations: int | Omit = omit, container: Optional[str] | Omit = omit, context_management: Optional[BetaContextManagementConfigParam] | Omit = omit, mcp_servers: Iterable[BetaRequestMCPServerURLDefinitionParam] | Omit = omit, metadata: BetaMetadataParam | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, stream: bool | Omit = omit, system: Union[str, Iterable[BetaTextBlockParam]] | Omit = omit, temperature: float | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, thinking: BetaThinkingConfigParam | Omit = omit, tool_choice: BetaToolChoiceParam | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, ) -> BetaToolRunner | BetaStreamingToolRunner: """Create a Message stream""" if model in DEPRECATED_MODELS: warnings.warn( f"The model '{model}' is deprecated and will reach end-of-life on {DEPRECATED_MODELS[model]}.\nPlease migrate to a newer model. Visit https://docs.anthropic.com/en/docs/resources/model-deprecations for more information.", DeprecationWarning, stacklevel=3, ) extra_headers = { "X-Stainless-Helper": "BetaToolRunner", **strip_not_given({"anthropic-beta": ",".join(str(e) for e in betas) if is_given(betas) else NOT_GIVEN}), **(extra_headers or {}), } params = cast( message_create_params.MessageCreateParamsNonStreaming, { "max_tokens": max_tokens, "messages": messages, "model": model, "container": container, "context_management": context_management, "mcp_servers": mcp_servers, "metadata": metadata, "service_tier": service_tier, "stop_sequences": stop_sequences, "system": system, "temperature": temperature, "thinking": thinking, "tool_choice": tool_choice, "tools": [tool.to_dict() for tool in tools], "top_k": top_k, "top_p": top_p, }, ) if stream: return BetaStreamingToolRunner( tools=tools, params=params, options={ "extra_headers": extra_headers, "extra_query": extra_query, "extra_body": extra_body, "timeout": timeout, }, client=cast("Anthropic", self._client), max_iterations=max_iterations if is_given(max_iterations) else None, ) return BetaToolRunner( tools=tools, params=params, options={ "extra_headers": extra_headers, "extra_query": extra_query, "extra_body": extra_body, "timeout": timeout, }, client=cast("Anthropic", self._client), max_iterations=max_iterations if is_given(max_iterations) else None, ) def stream( self, *, max_tokens: int, messages: Iterable[BetaMessageParam], model: ModelParam, container: Optional[str] | Omit = omit, context_management: Optional[BetaContextManagementConfigParam] | Omit = omit, mcp_servers: Iterable[BetaRequestMCPServerURLDefinitionParam] | Omit = omit, metadata: BetaMetadataParam | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, system: Union[str, Iterable[BetaTextBlockParam]] | Omit = omit, temperature: float | Omit = omit, thinking: BetaThinkingConfigParam | Omit = omit, tool_choice: BetaToolChoiceParam | Omit = omit, tools: Iterable[BetaToolUnionParam] | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, ) -> BetaMessageStreamManager: if model in DEPRECATED_MODELS: warnings.warn( f"The model '{model}' is deprecated and will reach end-of-life on {DEPRECATED_MODELS[model]}.\nPlease migrate to a newer model. Visit https://docs.anthropic.com/en/docs/resources/model-deprecations for more information.", DeprecationWarning, stacklevel=3, ) """Create a Message stream""" extra_headers = { "X-Stainless-Stream-Helper": "beta.messages", **strip_not_given({"anthropic-beta": ",".join(str(e) for e in betas) if is_given(betas) else NOT_GIVEN}), **(extra_headers or {}), } make_request = partial( self._post, "/v1/messages?beta=true", body=maybe_transform( { "max_tokens": max_tokens, "messages": messages, "model": model, "metadata": metadata, "container": container, "context_management": context_management, "mcp_servers": mcp_servers, "service_tier": service_tier, "stop_sequences": stop_sequences, "system": system, "temperature": temperature, "thinking": thinking, "top_k": top_k, "top_p": top_p, "tools": tools, "tool_choice": tool_choice, "stream": True, }, message_create_params.MessageCreateParams, ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=BetaMessage, stream=True, stream_cls=Stream[BetaRawMessageStreamEvent], ) return BetaMessageStreamManager(make_request) def count_tokens( self, *, messages: Iterable[BetaMessageParam], model: ModelParam, context_management: Optional[BetaContextManagementConfigParam] | Omit = omit, mcp_servers: Iterable[BetaRequestMCPServerURLDefinitionParam] | Omit = omit, system: Union[str, Iterable[BetaTextBlockParam]] | Omit = omit, thinking: BetaThinkingConfigParam | Omit = omit, tool_choice: BetaToolChoiceParam | Omit = omit, tools: Iterable[message_count_tokens_params.Tool] | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BetaMessageTokensCount: """ Count the number of tokens in a Message. The Token Count API can be used to count the number of tokens in a Message, including tools, images, and documents, without creating it. Learn more about token counting in our [user guide](/en/docs/build-with-claude/token-counting) Args: messages: Input messages. Our models are trained to operate on alternating `user` and `assistant` conversational turns. When creating a new `Message`, you specify the prior conversational turns with the `messages` parameter, and the model then generates the next `Message` in the conversation. Consecutive `user` or `assistant` turns in your request will be combined into a single turn. Each input message must be an object with a `role` and `content`. You can specify a single `user`-role message, or you can include multiple `user` and `assistant` messages. If the final message uses the `assistant` role, the response content will continue immediately from the content in that message. This can be used to constrain part of the model's response. Example with a single `user` message: ```json [{ "role": "user", "content": "Hello, Claude" }] ``` Example with multiple conversational turns: ```json [ { "role": "user", "content": "Hello there." }, { "role": "assistant", "content": "Hi, I'm Claude. How can I help you?" }, { "role": "user", "content": "Can you explain LLMs in plain English?" } ] ``` Example with a partially-filled response from Claude: ```json [ { "role": "user", "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun" }, { "role": "assistant", "content": "The best answer is (" } ] ``` Each input message `content` may be either a single `string` or an array of content blocks, where each block has a specific `type`. Using a `string` for `content` is shorthand for an array of one content block of type `"text"`. The following input messages are equivalent: ```json { "role": "user", "content": "Hello, Claude" } ``` ```json { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } ``` See [input examples](https://docs.anthropic.com/en/api/messages-examples). Note that if you want to include a [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use the top-level `system` parameter — there is no `"system"` role for input messages in the Messages API. There is a limit of 100,000 messages in a single request. model: The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. context_management: Configuration for context management operations. mcp_servers: MCP servers to be utilized in this request system: System prompt. A system prompt is a way of providing context and instructions to Claude, such as specifying a particular goal or role. See our [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts). thinking: Configuration for enabling Claude's extended thinking. When enabled, responses include `thinking` content blocks showing Claude's thinking process before the final answer. Requires a minimum budget of 1,024 tokens and counts towards your `max_tokens` limit. See [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) for details. tool_choice: How the model should use the provided tools. The model can use a specific tool, any available tool, decide by itself, or not use tools at all. tools: Definitions of tools that the model may use. If you include `tools` in your API request, the model may return `tool_use` content blocks that represent the model's use of those tools. You can then run those tools using the tool input generated by the model and then optionally return results back to the model using `tool_result` content blocks. There are two types of tools: **client tools** and **server tools**. The behavior described below applies to client tools. For [server tools](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#server-tools), see their individual documentation as each has its own behavior (e.g., the [web search tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool)). Each tool definition includes: - `name`: Name of the tool. - `description`: Optional, but strongly-recommended description of the tool. - `input_schema`: [JSON schema](https://json-schema.org/draft/2020-12) for the tool `input` shape that the model will produce in `tool_use` output content blocks. For example, if you defined `tools` as: ```json [ { "name": "get_stock_price", "description": "Get the current stock price for a given ticker symbol.", "input_schema": { "type": "object", "properties": { "ticker": { "type": "string", "description": "The stock ticker symbol, e.g. AAPL for Apple Inc." } }, "required": ["ticker"] } } ] ``` And then asked the model "What's the S&P 500 at today?", the model might produce `tool_use` content blocks in the response like this: ```json [ { "type": "tool_use", "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "name": "get_stock_price", "input": { "ticker": "^GSPC" } } ] ``` You might then run your `get_stock_price` tool with `{"ticker": "^GSPC"}` as an input, and return the following back to the model in a subsequent `user` message: ```json [ { "type": "tool_result", "tool_use_id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "content": "259.75 USD" } ] ``` Tools can be used for workflows that include running client-side tools and functions, or more generally whenever you want the model to produce a particular JSON structure of output. See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ extra_headers = { **strip_not_given( { "anthropic-beta": ",".join(chain((str(e) for e in betas), ["token-counting-2024-11-01"])) if is_given(betas) else not_given } ), **(extra_headers or {}), } extra_headers = {"anthropic-beta": "token-counting-2024-11-01", **(extra_headers or {})} return self._post( "/v1/messages/count_tokens?beta=true", body=maybe_transform( { "messages": messages, "model": model, "context_management": context_management, "mcp_servers": mcp_servers, "system": system, "thinking": thinking, "tool_choice": tool_choice, "tools": tools, }, message_count_tokens_params.MessageCountTokensParams, ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=BetaMessageTokensCount, ) class AsyncMessages(AsyncAPIResource): @cached_property def batches(self) -> AsyncBatches: return AsyncBatches(self._client) @cached_property def with_raw_response(self) -> AsyncMessagesWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the raw response object instead of the parsed content. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers """ return AsyncMessagesWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncMessagesWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response """ return AsyncMessagesWithStreamingResponse(self) @overload async def create( self, *, max_tokens: int, messages: Iterable[BetaMessageParam], model: ModelParam, container: Optional[str] | Omit = omit, context_management: Optional[BetaContextManagementConfigParam] | Omit = omit, mcp_servers: Iterable[BetaRequestMCPServerURLDefinitionParam] | Omit = omit, metadata: BetaMetadataParam | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, stream: Literal[False] | Omit = omit, system: Union[str, Iterable[BetaTextBlockParam]] | Omit = omit, temperature: float | Omit = omit, thinking: BetaThinkingConfigParam | Omit = omit, tool_choice: BetaToolChoiceParam | Omit = omit, tools: Iterable[BetaToolUnionParam] | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BetaMessage: """ Send a structured list of input messages with text and/or image content, and the model will generate the next message in the conversation. The Messages API can be used for either single queries or stateless multi-turn conversations. Learn more about the Messages API in our [user guide](/en/docs/initial-setup) Args: max_tokens: The maximum number of tokens to generate before stopping. Note that our models may stop _before_ reaching this maximum. This parameter only specifies the absolute maximum number of tokens to generate. Different models have different maximum values for this parameter. See [models](https://docs.anthropic.com/en/docs/models-overview) for details. messages: Input messages. Our models are trained to operate on alternating `user` and `assistant` conversational turns. When creating a new `Message`, you specify the prior conversational turns with the `messages` parameter, and the model then generates the next `Message` in the conversation. Consecutive `user` or `assistant` turns in your request will be combined into a single turn. Each input message must be an object with a `role` and `content`. You can specify a single `user`-role message, or you can include multiple `user` and `assistant` messages. If the final message uses the `assistant` role, the response content will continue immediately from the content in that message. This can be used to constrain part of the model's response. Example with a single `user` message: ```json [{ "role": "user", "content": "Hello, Claude" }] ``` Example with multiple conversational turns: ```json [ { "role": "user", "content": "Hello there." }, { "role": "assistant", "content": "Hi, I'm Claude. How can I help you?" }, { "role": "user", "content": "Can you explain LLMs in plain English?" } ] ``` Example with a partially-filled response from Claude: ```json [ { "role": "user", "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun" }, { "role": "assistant", "content": "The best answer is (" } ] ``` Each input message `content` may be either a single `string` or an array of content blocks, where each block has a specific `type`. Using a `string` for `content` is shorthand for an array of one content block of type `"text"`. The following input messages are equivalent: ```json { "role": "user", "content": "Hello, Claude" } ``` ```json { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } ``` See [input examples](https://docs.anthropic.com/en/api/messages-examples). Note that if you want to include a [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use the top-level `system` parameter — there is no `"system"` role for input messages in the Messages API. There is a limit of 100,000 messages in a single request. model: The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. container: Container identifier for reuse across requests. context_management: Configuration for context management operations. mcp_servers: MCP servers to be utilized in this request metadata: An object describing metadata about the request. service_tier: Determines whether to use priority capacity (if available) or standard capacity for this request. Anthropic offers different levels of service for your API requests. See [service-tiers](https://docs.anthropic.com/en/api/service-tiers) for details. stop_sequences: Custom text sequences that will cause the model to stop generating. Our models will normally stop when they have naturally completed their turn, which will result in a response `stop_reason` of `"end_turn"`. If you want the model to stop generating when it encounters custom strings of text, you can use the `stop_sequences` parameter. If the model encounters one of the custom sequences, the response `stop_reason` value will be `"stop_sequence"` and the response `stop_sequence` value will contain the matched stop sequence. stream: Whether to incrementally stream the response using server-sent events. See [streaming](https://docs.anthropic.com/en/api/messages-streaming) for details. system: System prompt. A system prompt is a way of providing context and instructions to Claude, such as specifying a particular goal or role. See our [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts). temperature: Amount of randomness injected into the response. Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0` for analytical / multiple choice, and closer to `1.0` for creative and generative tasks. Note that even with `temperature` of `0.0`, the results will not be fully deterministic. thinking: Configuration for enabling Claude's extended thinking. When enabled, responses include `thinking` content blocks showing Claude's thinking process before the final answer. Requires a minimum budget of 1,024 tokens and counts towards your `max_tokens` limit. See [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) for details. tool_choice: How the model should use the provided tools. The model can use a specific tool, any available tool, decide by itself, or not use tools at all. tools: Definitions of tools that the model may use. If you include `tools` in your API request, the model may return `tool_use` content blocks that represent the model's use of those tools. You can then run those tools using the tool input generated by the model and then optionally return results back to the model using `tool_result` content blocks. There are two types of tools: **client tools** and **server tools**. The behavior described below applies to client tools. For [server tools](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#server-tools), see their individual documentation as each has its own behavior (e.g., the [web search tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool)). Each tool definition includes: - `name`: Name of the tool. - `description`: Optional, but strongly-recommended description of the tool. - `input_schema`: [JSON schema](https://json-schema.org/draft/2020-12) for the tool `input` shape that the model will produce in `tool_use` output content blocks. For example, if you defined `tools` as: ```json [ { "name": "get_stock_price", "description": "Get the current stock price for a given ticker symbol.", "input_schema": { "type": "object", "properties": { "ticker": { "type": "string", "description": "The stock ticker symbol, e.g. AAPL for Apple Inc." } }, "required": ["ticker"] } } ] ``` And then asked the model "What's the S&P 500 at today?", the model might produce `tool_use` content blocks in the response like this: ```json [ { "type": "tool_use", "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "name": "get_stock_price", "input": { "ticker": "^GSPC" } } ] ``` You might then run your `get_stock_price` tool with `{"ticker": "^GSPC"}` as an input, and return the following back to the model in a subsequent `user` message: ```json [ { "type": "tool_result", "tool_use_id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "content": "259.75 USD" } ] ``` Tools can be used for workflows that include running client-side tools and functions, or more generally whenever you want the model to produce a particular JSON structure of output. See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. top_k: Only sample from the top K options for each subsequent token. Used to remove "long tail" low probability responses. [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277). Recommended for advanced use cases only. You usually only need to use `temperature`. top_p: Use nucleus sampling. In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by `top_p`. You should either alter `temperature` or `top_p`, but not both. Recommended for advanced use cases only. You usually only need to use `temperature`. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ ... @overload async def create( self, *, max_tokens: int, messages: Iterable[BetaMessageParam], model: ModelParam, stream: Literal[True], container: Optional[str] | Omit = omit, context_management: Optional[BetaContextManagementConfigParam] | Omit = omit, mcp_servers: Iterable[BetaRequestMCPServerURLDefinitionParam] | Omit = omit, metadata: BetaMetadataParam | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, system: Union[str, Iterable[BetaTextBlockParam]] | Omit = omit, temperature: float | Omit = omit, thinking: BetaThinkingConfigParam | Omit = omit, tool_choice: BetaToolChoiceParam | Omit = omit, tools: Iterable[BetaToolUnionParam] | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncStream[BetaRawMessageStreamEvent]: """ Send a structured list of input messages with text and/or image content, and the model will generate the next message in the conversation. The Messages API can be used for either single queries or stateless multi-turn conversations. Learn more about the Messages API in our [user guide](/en/docs/initial-setup) Args: max_tokens: The maximum number of tokens to generate before stopping. Note that our models may stop _before_ reaching this maximum. This parameter only specifies the absolute maximum number of tokens to generate. Different models have different maximum values for this parameter. See [models](https://docs.anthropic.com/en/docs/models-overview) for details. messages: Input messages. Our models are trained to operate on alternating `user` and `assistant` conversational turns. When creating a new `Message`, you specify the prior conversational turns with the `messages` parameter, and the model then generates the next `Message` in the conversation. Consecutive `user` or `assistant` turns in your request will be combined into a single turn. Each input message must be an object with a `role` and `content`. You can specify a single `user`-role message, or you can include multiple `user` and `assistant` messages. If the final message uses the `assistant` role, the response content will continue immediately from the content in that message. This can be used to constrain part of the model's response. Example with a single `user` message: ```json [{ "role": "user", "content": "Hello, Claude" }] ``` Example with multiple conversational turns: ```json [ { "role": "user", "content": "Hello there." }, { "role": "assistant", "content": "Hi, I'm Claude. How can I help you?" }, { "role": "user", "content": "Can you explain LLMs in plain English?" } ] ``` Example with a partially-filled response from Claude: ```json [ { "role": "user", "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun" }, { "role": "assistant", "content": "The best answer is (" } ] ``` Each input message `content` may be either a single `string` or an array of content blocks, where each block has a specific `type`. Using a `string` for `content` is shorthand for an array of one content block of type `"text"`. The following input messages are equivalent: ```json { "role": "user", "content": "Hello, Claude" } ``` ```json { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } ``` See [input examples](https://docs.anthropic.com/en/api/messages-examples). Note that if you want to include a [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use the top-level `system` parameter — there is no `"system"` role for input messages in the Messages API. There is a limit of 100,000 messages in a single request. model: The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. stream: Whether to incrementally stream the response using server-sent events. See [streaming](https://docs.anthropic.com/en/api/messages-streaming) for details. container: Container identifier for reuse across requests. context_management: Configuration for context management operations. mcp_servers: MCP servers to be utilized in this request metadata: An object describing metadata about the request. service_tier: Determines whether to use priority capacity (if available) or standard capacity for this request. Anthropic offers different levels of service for your API requests. See [service-tiers](https://docs.anthropic.com/en/api/service-tiers) for details. stop_sequences: Custom text sequences that will cause the model to stop generating. Our models will normally stop when they have naturally completed their turn, which will result in a response `stop_reason` of `"end_turn"`. If you want the model to stop generating when it encounters custom strings of text, you can use the `stop_sequences` parameter. If the model encounters one of the custom sequences, the response `stop_reason` value will be `"stop_sequence"` and the response `stop_sequence` value will contain the matched stop sequence. system: System prompt. A system prompt is a way of providing context and instructions to Claude, such as specifying a particular goal or role. See our [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts). temperature: Amount of randomness injected into the response. Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0` for analytical / multiple choice, and closer to `1.0` for creative and generative tasks. Note that even with `temperature` of `0.0`, the results will not be fully deterministic. thinking: Configuration for enabling Claude's extended thinking. When enabled, responses include `thinking` content blocks showing Claude's thinking process before the final answer. Requires a minimum budget of 1,024 tokens and counts towards your `max_tokens` limit. See [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) for details. tool_choice: How the model should use the provided tools. The model can use a specific tool, any available tool, decide by itself, or not use tools at all. tools: Definitions of tools that the model may use. If you include `tools` in your API request, the model may return `tool_use` content blocks that represent the model's use of those tools. You can then run those tools using the tool input generated by the model and then optionally return results back to the model using `tool_result` content blocks. There are two types of tools: **client tools** and **server tools**. The behavior described below applies to client tools. For [server tools](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#server-tools), see their individual documentation as each has its own behavior (e.g., the [web search tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool)). Each tool definition includes: - `name`: Name of the tool. - `description`: Optional, but strongly-recommended description of the tool. - `input_schema`: [JSON schema](https://json-schema.org/draft/2020-12) for the tool `input` shape that the model will produce in `tool_use` output content blocks. For example, if you defined `tools` as: ```json [ { "name": "get_stock_price", "description": "Get the current stock price for a given ticker symbol.", "input_schema": { "type": "object", "properties": { "ticker": { "type": "string", "description": "The stock ticker symbol, e.g. AAPL for Apple Inc." } }, "required": ["ticker"] } } ] ``` And then asked the model "What's the S&P 500 at today?", the model might produce `tool_use` content blocks in the response like this: ```json [ { "type": "tool_use", "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "name": "get_stock_price", "input": { "ticker": "^GSPC" } } ] ``` You might then run your `get_stock_price` tool with `{"ticker": "^GSPC"}` as an input, and return the following back to the model in a subsequent `user` message: ```json [ { "type": "tool_result", "tool_use_id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "content": "259.75 USD" } ] ``` Tools can be used for workflows that include running client-side tools and functions, or more generally whenever you want the model to produce a particular JSON structure of output. See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. top_k: Only sample from the top K options for each subsequent token. Used to remove "long tail" low probability responses. [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277). Recommended for advanced use cases only. You usually only need to use `temperature`. top_p: Use nucleus sampling. In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by `top_p`. You should either alter `temperature` or `top_p`, but not both. Recommended for advanced use cases only. You usually only need to use `temperature`. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ ... @overload async def create( self, *, max_tokens: int, messages: Iterable[BetaMessageParam], model: ModelParam, stream: bool, container: Optional[str] | Omit = omit, context_management: Optional[BetaContextManagementConfigParam] | Omit = omit, mcp_servers: Iterable[BetaRequestMCPServerURLDefinitionParam] | Omit = omit, metadata: BetaMetadataParam | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, system: Union[str, Iterable[BetaTextBlockParam]] | Omit = omit, temperature: float | Omit = omit, thinking: BetaThinkingConfigParam | Omit = omit, tool_choice: BetaToolChoiceParam | Omit = omit, tools: Iterable[BetaToolUnionParam] | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BetaMessage | AsyncStream[BetaRawMessageStreamEvent]: """ Send a structured list of input messages with text and/or image content, and the model will generate the next message in the conversation. The Messages API can be used for either single queries or stateless multi-turn conversations. Learn more about the Messages API in our [user guide](/en/docs/initial-setup) Args: max_tokens: The maximum number of tokens to generate before stopping. Note that our models may stop _before_ reaching this maximum. This parameter only specifies the absolute maximum number of tokens to generate. Different models have different maximum values for this parameter. See [models](https://docs.anthropic.com/en/docs/models-overview) for details. messages: Input messages. Our models are trained to operate on alternating `user` and `assistant` conversational turns. When creating a new `Message`, you specify the prior conversational turns with the `messages` parameter, and the model then generates the next `Message` in the conversation. Consecutive `user` or `assistant` turns in your request will be combined into a single turn. Each input message must be an object with a `role` and `content`. You can specify a single `user`-role message, or you can include multiple `user` and `assistant` messages. If the final message uses the `assistant` role, the response content will continue immediately from the content in that message. This can be used to constrain part of the model's response. Example with a single `user` message: ```json [{ "role": "user", "content": "Hello, Claude" }] ``` Example with multiple conversational turns: ```json [ { "role": "user", "content": "Hello there." }, { "role": "assistant", "content": "Hi, I'm Claude. How can I help you?" }, { "role": "user", "content": "Can you explain LLMs in plain English?" } ] ``` Example with a partially-filled response from Claude: ```json [ { "role": "user", "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun" }, { "role": "assistant", "content": "The best answer is (" } ] ``` Each input message `content` may be either a single `string` or an array of content blocks, where each block has a specific `type`. Using a `string` for `content` is shorthand for an array of one content block of type `"text"`. The following input messages are equivalent: ```json { "role": "user", "content": "Hello, Claude" } ``` ```json { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } ``` See [input examples](https://docs.anthropic.com/en/api/messages-examples). Note that if you want to include a [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use the top-level `system` parameter — there is no `"system"` role for input messages in the Messages API. There is a limit of 100,000 messages in a single request. model: The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. stream: Whether to incrementally stream the response using server-sent events. See [streaming](https://docs.anthropic.com/en/api/messages-streaming) for details. container: Container identifier for reuse across requests. context_management: Configuration for context management operations. mcp_servers: MCP servers to be utilized in this request metadata: An object describing metadata about the request. service_tier: Determines whether to use priority capacity (if available) or standard capacity for this request. Anthropic offers different levels of service for your API requests. See [service-tiers](https://docs.anthropic.com/en/api/service-tiers) for details. stop_sequences: Custom text sequences that will cause the model to stop generating. Our models will normally stop when they have naturally completed their turn, which will result in a response `stop_reason` of `"end_turn"`. If you want the model to stop generating when it encounters custom strings of text, you can use the `stop_sequences` parameter. If the model encounters one of the custom sequences, the response `stop_reason` value will be `"stop_sequence"` and the response `stop_sequence` value will contain the matched stop sequence. system: System prompt. A system prompt is a way of providing context and instructions to Claude, such as specifying a particular goal or role. See our [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts). temperature: Amount of randomness injected into the response. Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0` for analytical / multiple choice, and closer to `1.0` for creative and generative tasks. Note that even with `temperature` of `0.0`, the results will not be fully deterministic. thinking: Configuration for enabling Claude's extended thinking. When enabled, responses include `thinking` content blocks showing Claude's thinking process before the final answer. Requires a minimum budget of 1,024 tokens and counts towards your `max_tokens` limit. See [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) for details. tool_choice: How the model should use the provided tools. The model can use a specific tool, any available tool, decide by itself, or not use tools at all. tools: Definitions of tools that the model may use. If you include `tools` in your API request, the model may return `tool_use` content blocks that represent the model's use of those tools. You can then run those tools using the tool input generated by the model and then optionally return results back to the model using `tool_result` content blocks. There are two types of tools: **client tools** and **server tools**. The behavior described below applies to client tools. For [server tools](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#server-tools), see their individual documentation as each has its own behavior (e.g., the [web search tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool)). Each tool definition includes: - `name`: Name of the tool. - `description`: Optional, but strongly-recommended description of the tool. - `input_schema`: [JSON schema](https://json-schema.org/draft/2020-12) for the tool `input` shape that the model will produce in `tool_use` output content blocks. For example, if you defined `tools` as: ```json [ { "name": "get_stock_price", "description": "Get the current stock price for a given ticker symbol.", "input_schema": { "type": "object", "properties": { "ticker": { "type": "string", "description": "The stock ticker symbol, e.g. AAPL for Apple Inc." } }, "required": ["ticker"] } } ] ``` And then asked the model "What's the S&P 500 at today?", the model might produce `tool_use` content blocks in the response like this: ```json [ { "type": "tool_use", "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "name": "get_stock_price", "input": { "ticker": "^GSPC" } } ] ``` You might then run your `get_stock_price` tool with `{"ticker": "^GSPC"}` as an input, and return the following back to the model in a subsequent `user` message: ```json [ { "type": "tool_result", "tool_use_id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "content": "259.75 USD" } ] ``` Tools can be used for workflows that include running client-side tools and functions, or more generally whenever you want the model to produce a particular JSON structure of output. See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. top_k: Only sample from the top K options for each subsequent token. Used to remove "long tail" low probability responses. [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277). Recommended for advanced use cases only. You usually only need to use `temperature`. top_p: Use nucleus sampling. In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by `top_p`. You should either alter `temperature` or `top_p`, but not both. Recommended for advanced use cases only. You usually only need to use `temperature`. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ ... @required_args(["max_tokens", "messages", "model"], ["max_tokens", "messages", "model", "stream"]) async def create( self, *, max_tokens: int, messages: Iterable[BetaMessageParam], model: ModelParam, container: Optional[str] | Omit = omit, context_management: Optional[BetaContextManagementConfigParam] | Omit = omit, mcp_servers: Iterable[BetaRequestMCPServerURLDefinitionParam] | Omit = omit, metadata: BetaMetadataParam | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, stream: Literal[False] | Literal[True] | Omit = omit, system: Union[str, Iterable[BetaTextBlockParam]] | Omit = omit, temperature: float | Omit = omit, thinking: BetaThinkingConfigParam | Omit = omit, tool_choice: BetaToolChoiceParam | Omit = omit, tools: Iterable[BetaToolUnionParam] | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BetaMessage | AsyncStream[BetaRawMessageStreamEvent]: if not stream and not is_given(timeout) and self._client.timeout == DEFAULT_TIMEOUT: timeout = self._client._calculate_nonstreaming_timeout( max_tokens, MODEL_NONSTREAMING_TOKENS.get(model, None) ) if model in DEPRECATED_MODELS: warnings.warn( f"The model '{model}' is deprecated and will reach end-of-life on {DEPRECATED_MODELS[model]}.\nPlease migrate to a newer model. Visit https://docs.anthropic.com/en/docs/resources/model-deprecations for more information.", DeprecationWarning, stacklevel=3, ) extra_headers = { **strip_not_given({"anthropic-beta": ",".join(str(e) for e in betas) if is_given(betas) else not_given}), **(extra_headers or {}), } return await self._post( "/v1/messages?beta=true", body=await async_maybe_transform( { "max_tokens": max_tokens, "messages": messages, "model": model, "container": container, "context_management": context_management, "mcp_servers": mcp_servers, "metadata": metadata, "service_tier": service_tier, "stop_sequences": stop_sequences, "stream": stream, "system": system, "temperature": temperature, "thinking": thinking, "tool_choice": tool_choice, "tools": tools, "top_k": top_k, "top_p": top_p, }, message_create_params.MessageCreateParamsStreaming if stream else message_create_params.MessageCreateParamsNonStreaming, ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=BetaMessage, stream=stream or False, stream_cls=AsyncStream[BetaRawMessageStreamEvent], ) @overload def tool_runner( self, *, max_tokens: int, messages: Iterable[BetaMessageParam], model: ModelParam, tools: Iterable[BetaAsyncRunnableTool], max_iterations: int | Omit = omit, container: Optional[str] | Omit = omit, context_management: Optional[BetaContextManagementConfigParam] | Omit = omit, mcp_servers: Iterable[BetaRequestMCPServerURLDefinitionParam] | Omit = omit, metadata: BetaMetadataParam | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, stream: Literal[False] | Omit = omit, system: Union[str, Iterable[BetaTextBlockParam]] | Omit = omit, temperature: float | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, thinking: BetaThinkingConfigParam | Omit = omit, tool_choice: BetaToolChoiceParam | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, ) -> BetaAsyncToolRunner: ... @overload def tool_runner( self, *, max_tokens: int, messages: Iterable[BetaMessageParam], model: ModelParam, tools: Iterable[BetaAsyncRunnableTool], stream: Literal[True], max_iterations: int | Omit = omit, container: Optional[str] | Omit = omit, context_management: Optional[BetaContextManagementConfigParam] | Omit = omit, mcp_servers: Iterable[BetaRequestMCPServerURLDefinitionParam] | Omit = omit, metadata: BetaMetadataParam | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, system: Union[str, Iterable[BetaTextBlockParam]] | Omit = omit, temperature: float | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, thinking: BetaThinkingConfigParam | Omit = omit, tool_choice: BetaToolChoiceParam | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, ) -> BetaAsyncStreamingToolRunner: ... @overload def tool_runner( self, *, max_tokens: int, messages: Iterable[BetaMessageParam], model: ModelParam, tools: Iterable[BetaAsyncRunnableTool], stream: bool, max_iterations: int | Omit = omit, container: Optional[str] | Omit = omit, context_management: Optional[BetaContextManagementConfigParam] | Omit = omit, mcp_servers: Iterable[BetaRequestMCPServerURLDefinitionParam] | Omit = omit, metadata: BetaMetadataParam | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, system: Union[str, Iterable[BetaTextBlockParam]] | Omit = omit, temperature: float | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, thinking: BetaThinkingConfigParam | Omit = omit, tool_choice: BetaToolChoiceParam | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, ) -> BetaAsyncStreamingToolRunner | BetaAsyncToolRunner: ... def tool_runner( self, *, max_tokens: int, messages: Iterable[BetaMessageParam], model: ModelParam, tools: Iterable[BetaAsyncRunnableTool], max_iterations: int | Omit = omit, container: Optional[str] | Omit = omit, context_management: Optional[BetaContextManagementConfigParam] | Omit = omit, mcp_servers: Iterable[BetaRequestMCPServerURLDefinitionParam] | Omit = omit, metadata: BetaMetadataParam | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, stream: Literal[True] | Literal[False] | Omit = False, system: Union[str, Iterable[BetaTextBlockParam]] | Omit = omit, temperature: float | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, thinking: BetaThinkingConfigParam | Omit = omit, tool_choice: BetaToolChoiceParam | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, ) -> BetaAsyncToolRunner | BetaAsyncStreamingToolRunner: """Create a Message stream""" if model in DEPRECATED_MODELS: warnings.warn( f"The model '{model}' is deprecated and will reach end-of-life on {DEPRECATED_MODELS[model]}.\nPlease migrate to a newer model. Visit https://docs.anthropic.com/en/docs/resources/model-deprecations for more information.", DeprecationWarning, stacklevel=3, ) extra_headers = { "X-Stainless-Helper": "BetaToolRunner", **strip_not_given({"anthropic-beta": ",".join(str(e) for e in betas) if is_given(betas) else NOT_GIVEN}), **(extra_headers or {}), } params = cast( message_create_params.MessageCreateParamsBase, { "max_tokens": max_tokens, "messages": messages, "model": model, "container": container, "context_management": context_management, "mcp_servers": mcp_servers, "metadata": metadata, "service_tier": service_tier, "stop_sequences": stop_sequences, "system": system, "temperature": temperature, "thinking": thinking, "tool_choice": tool_choice, "tools": [tool.to_dict() for tool in tools], "top_k": top_k, "top_p": top_p, }, ) if stream: return BetaAsyncStreamingToolRunner( tools=tools, params=params, options={ "extra_headers": extra_headers, "extra_query": extra_query, "extra_body": extra_body, "timeout": timeout, }, client=cast("AsyncAnthropic", self._client), max_iterations=max_iterations if is_given(max_iterations) else None, ) return BetaAsyncToolRunner( tools=tools, params=params, options={ "extra_headers": extra_headers, "extra_query": extra_query, "extra_body": extra_body, "timeout": timeout, }, client=cast("AsyncAnthropic", self._client), max_iterations=max_iterations if is_given(max_iterations) else None, ) def stream( self, *, max_tokens: int, messages: Iterable[BetaMessageParam], model: ModelParam, metadata: BetaMetadataParam | Omit = omit, container: Optional[str] | Omit = omit, context_management: Optional[BetaContextManagementConfigParam] | Omit = omit, mcp_servers: Iterable[BetaRequestMCPServerURLDefinitionParam] | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, system: Union[str, Iterable[BetaTextBlockParam]] | Omit = omit, temperature: float | Omit = omit, thinking: BetaThinkingConfigParam | Omit = omit, tool_choice: BetaToolChoiceParam | Omit = omit, tools: Iterable[BetaToolUnionParam] | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, ) -> BetaAsyncMessageStreamManager: if model in DEPRECATED_MODELS: warnings.warn( f"The model '{model}' is deprecated and will reach end-of-life on {DEPRECATED_MODELS[model]}.\nPlease migrate to a newer model. Visit https://docs.anthropic.com/en/docs/resources/model-deprecations for more information.", DeprecationWarning, stacklevel=3, ) extra_headers = { "X-Stainless-Stream-Helper": "beta.messages", **strip_not_given({"anthropic-beta": ",".join(str(e) for e in betas) if is_given(betas) else NOT_GIVEN}), **(extra_headers or {}), } request = self._post( "/v1/messages", body=maybe_transform( { "max_tokens": max_tokens, "messages": messages, "model": model, "metadata": metadata, "container": container, "context_management": context_management, "mcp_servers": mcp_servers, "service_tier": service_tier, "stop_sequences": stop_sequences, "system": system, "temperature": temperature, "thinking": thinking, "top_k": top_k, "top_p": top_p, "tools": tools, "tool_choice": tool_choice, "stream": True, }, message_create_params.MessageCreateParams, ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=BetaMessage, stream=True, stream_cls=AsyncStream[BetaRawMessageStreamEvent], ) return BetaAsyncMessageStreamManager(request) async def count_tokens( self, *, messages: Iterable[BetaMessageParam], model: ModelParam, context_management: Optional[BetaContextManagementConfigParam] | Omit = omit, mcp_servers: Iterable[BetaRequestMCPServerURLDefinitionParam] | Omit = omit, system: Union[str, Iterable[BetaTextBlockParam]] | Omit = omit, thinking: BetaThinkingConfigParam | Omit = omit, tool_choice: BetaToolChoiceParam | Omit = omit, tools: Iterable[message_count_tokens_params.Tool] | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BetaMessageTokensCount: """ Count the number of tokens in a Message. The Token Count API can be used to count the number of tokens in a Message, including tools, images, and documents, without creating it. Learn more about token counting in our [user guide](/en/docs/build-with-claude/token-counting) Args: messages: Input messages. Our models are trained to operate on alternating `user` and `assistant` conversational turns. When creating a new `Message`, you specify the prior conversational turns with the `messages` parameter, and the model then generates the next `Message` in the conversation. Consecutive `user` or `assistant` turns in your request will be combined into a single turn. Each input message must be an object with a `role` and `content`. You can specify a single `user`-role message, or you can include multiple `user` and `assistant` messages. If the final message uses the `assistant` role, the response content will continue immediately from the content in that message. This can be used to constrain part of the model's response. Example with a single `user` message: ```json [{ "role": "user", "content": "Hello, Claude" }] ``` Example with multiple conversational turns: ```json [ { "role": "user", "content": "Hello there." }, { "role": "assistant", "content": "Hi, I'm Claude. How can I help you?" }, { "role": "user", "content": "Can you explain LLMs in plain English?" } ] ``` Example with a partially-filled response from Claude: ```json [ { "role": "user", "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun" }, { "role": "assistant", "content": "The best answer is (" } ] ``` Each input message `content` may be either a single `string` or an array of content blocks, where each block has a specific `type`. Using a `string` for `content` is shorthand for an array of one content block of type `"text"`. The following input messages are equivalent: ```json { "role": "user", "content": "Hello, Claude" } ``` ```json { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } ``` See [input examples](https://docs.anthropic.com/en/api/messages-examples). Note that if you want to include a [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use the top-level `system` parameter — there is no `"system"` role for input messages in the Messages API. There is a limit of 100,000 messages in a single request. model: The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. context_management: Configuration for context management operations. mcp_servers: MCP servers to be utilized in this request system: System prompt. A system prompt is a way of providing context and instructions to Claude, such as specifying a particular goal or role. See our [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts). thinking: Configuration for enabling Claude's extended thinking. When enabled, responses include `thinking` content blocks showing Claude's thinking process before the final answer. Requires a minimum budget of 1,024 tokens and counts towards your `max_tokens` limit. See [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) for details. tool_choice: How the model should use the provided tools. The model can use a specific tool, any available tool, decide by itself, or not use tools at all. tools: Definitions of tools that the model may use. If you include `tools` in your API request, the model may return `tool_use` content blocks that represent the model's use of those tools. You can then run those tools using the tool input generated by the model and then optionally return results back to the model using `tool_result` content blocks. There are two types of tools: **client tools** and **server tools**. The behavior described below applies to client tools. For [server tools](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#server-tools), see their individual documentation as each has its own behavior (e.g., the [web search tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool)). Each tool definition includes: - `name`: Name of the tool. - `description`: Optional, but strongly-recommended description of the tool. - `input_schema`: [JSON schema](https://json-schema.org/draft/2020-12) for the tool `input` shape that the model will produce in `tool_use` output content blocks. For example, if you defined `tools` as: ```json [ { "name": "get_stock_price", "description": "Get the current stock price for a given ticker symbol.", "input_schema": { "type": "object", "properties": { "ticker": { "type": "string", "description": "The stock ticker symbol, e.g. AAPL for Apple Inc." } }, "required": ["ticker"] } } ] ``` And then asked the model "What's the S&P 500 at today?", the model might produce `tool_use` content blocks in the response like this: ```json [ { "type": "tool_use", "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "name": "get_stock_price", "input": { "ticker": "^GSPC" } } ] ``` You might then run your `get_stock_price` tool with `{"ticker": "^GSPC"}` as an input, and return the following back to the model in a subsequent `user` message: ```json [ { "type": "tool_result", "tool_use_id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "content": "259.75 USD" } ] ``` Tools can be used for workflows that include running client-side tools and functions, or more generally whenever you want the model to produce a particular JSON structure of output. See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ extra_headers = { **strip_not_given( { "anthropic-beta": ",".join(chain((str(e) for e in betas), ["token-counting-2024-11-01"])) if is_given(betas) else not_given } ), **(extra_headers or {}), } extra_headers = {"anthropic-beta": "token-counting-2024-11-01", **(extra_headers or {})} return await self._post( "/v1/messages/count_tokens?beta=true", body=await async_maybe_transform( { "messages": messages, "model": model, "context_management": context_management, "mcp_servers": mcp_servers, "system": system, "thinking": thinking, "tool_choice": tool_choice, "tools": tools, }, message_count_tokens_params.MessageCountTokensParams, ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=BetaMessageTokensCount, ) class MessagesWithRawResponse: def __init__(self, messages: Messages) -> None: self._messages = messages self.create = _legacy_response.to_raw_response_wrapper( messages.create, ) self.count_tokens = _legacy_response.to_raw_response_wrapper( messages.count_tokens, ) @cached_property def batches(self) -> BatchesWithRawResponse: return BatchesWithRawResponse(self._messages.batches) class AsyncMessagesWithRawResponse: def __init__(self, messages: AsyncMessages) -> None: self._messages = messages self.create = _legacy_response.async_to_raw_response_wrapper( messages.create, ) self.count_tokens = _legacy_response.async_to_raw_response_wrapper( messages.count_tokens, ) @cached_property def batches(self) -> AsyncBatchesWithRawResponse: return AsyncBatchesWithRawResponse(self._messages.batches) class MessagesWithStreamingResponse: def __init__(self, messages: Messages) -> None: self._messages = messages self.create = to_streamed_response_wrapper( messages.create, ) self.count_tokens = to_streamed_response_wrapper( messages.count_tokens, ) @cached_property def batches(self) -> BatchesWithStreamingResponse: return BatchesWithStreamingResponse(self._messages.batches) class AsyncMessagesWithStreamingResponse: def __init__(self, messages: AsyncMessages) -> None: self._messages = messages self.create = async_to_streamed_response_wrapper( messages.create, ) self.count_tokens = async_to_streamed_response_wrapper( messages.count_tokens, ) @cached_property def batches(self) -> AsyncBatchesWithStreamingResponse: return AsyncBatchesWithStreamingResponse(self._messages.batches) anthropic-sdk-python-0.69.0/src/anthropic/resources/beta/models.py000066400000000000000000000303441506653454500252540ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import List import httpx from ... import _legacy_response from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given from ..._utils import is_given, maybe_transform, strip_not_given from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper from ...pagination import SyncPage, AsyncPage from ...types.beta import model_list_params from ..._base_client import AsyncPaginator, make_request_options from ...types.anthropic_beta_param import AnthropicBetaParam from ...types.beta.beta_model_info import BetaModelInfo __all__ = ["Models", "AsyncModels"] class Models(SyncAPIResource): @cached_property def with_raw_response(self) -> ModelsWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the raw response object instead of the parsed content. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers """ return ModelsWithRawResponse(self) @cached_property def with_streaming_response(self) -> ModelsWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response """ return ModelsWithStreamingResponse(self) def retrieve( self, model_id: str, *, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BetaModelInfo: """ Get a specific model. The Models API response can be used to determine information about a specific model or resolve a model alias to a model ID. Args: model_id: Model identifier or alias. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ if not model_id: raise ValueError(f"Expected a non-empty value for `model_id` but received {model_id!r}") extra_headers = { **strip_not_given({"anthropic-beta": ",".join(str(e) for e in betas) if is_given(betas) else not_given}), **(extra_headers or {}), } return self._get( f"/v1/models/{model_id}?beta=true", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=BetaModelInfo, ) def list( self, *, after_id: str | Omit = omit, before_id: str | Omit = omit, limit: int | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncPage[BetaModelInfo]: """ List available models. The Models API response can be used to determine which models are available for use in the API. More recently released models are listed first. Args: after_id: ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately after this object. before_id: ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately before this object. limit: Number of items to return per page. Defaults to `20`. Ranges from `1` to `1000`. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ extra_headers = { **strip_not_given({"anthropic-beta": ",".join(str(e) for e in betas) if is_given(betas) else not_given}), **(extra_headers or {}), } return self._get_api_list( "/v1/models?beta=true", page=SyncPage[BetaModelInfo], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, query=maybe_transform( { "after_id": after_id, "before_id": before_id, "limit": limit, }, model_list_params.ModelListParams, ), ), model=BetaModelInfo, ) class AsyncModels(AsyncAPIResource): @cached_property def with_raw_response(self) -> AsyncModelsWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the raw response object instead of the parsed content. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers """ return AsyncModelsWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncModelsWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response """ return AsyncModelsWithStreamingResponse(self) async def retrieve( self, model_id: str, *, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BetaModelInfo: """ Get a specific model. The Models API response can be used to determine information about a specific model or resolve a model alias to a model ID. Args: model_id: Model identifier or alias. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ if not model_id: raise ValueError(f"Expected a non-empty value for `model_id` but received {model_id!r}") extra_headers = { **strip_not_given({"anthropic-beta": ",".join(str(e) for e in betas) if is_given(betas) else not_given}), **(extra_headers or {}), } return await self._get( f"/v1/models/{model_id}?beta=true", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=BetaModelInfo, ) def list( self, *, after_id: str | Omit = omit, before_id: str | Omit = omit, limit: int | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[BetaModelInfo, AsyncPage[BetaModelInfo]]: """ List available models. The Models API response can be used to determine which models are available for use in the API. More recently released models are listed first. Args: after_id: ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately after this object. before_id: ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately before this object. limit: Number of items to return per page. Defaults to `20`. Ranges from `1` to `1000`. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ extra_headers = { **strip_not_given({"anthropic-beta": ",".join(str(e) for e in betas) if is_given(betas) else not_given}), **(extra_headers or {}), } return self._get_api_list( "/v1/models?beta=true", page=AsyncPage[BetaModelInfo], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, query=maybe_transform( { "after_id": after_id, "before_id": before_id, "limit": limit, }, model_list_params.ModelListParams, ), ), model=BetaModelInfo, ) class ModelsWithRawResponse: def __init__(self, models: Models) -> None: self._models = models self.retrieve = _legacy_response.to_raw_response_wrapper( models.retrieve, ) self.list = _legacy_response.to_raw_response_wrapper( models.list, ) class AsyncModelsWithRawResponse: def __init__(self, models: AsyncModels) -> None: self._models = models self.retrieve = _legacy_response.async_to_raw_response_wrapper( models.retrieve, ) self.list = _legacy_response.async_to_raw_response_wrapper( models.list, ) class ModelsWithStreamingResponse: def __init__(self, models: Models) -> None: self._models = models self.retrieve = to_streamed_response_wrapper( models.retrieve, ) self.list = to_streamed_response_wrapper( models.list, ) class AsyncModelsWithStreamingResponse: def __init__(self, models: AsyncModels) -> None: self._models = models self.retrieve = async_to_streamed_response_wrapper( models.retrieve, ) self.list = async_to_streamed_response_wrapper( models.list, ) anthropic-sdk-python-0.69.0/src/anthropic/resources/completions.py000066400000000000000000001076441506653454500254220ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import List from typing_extensions import Literal, overload import httpx from .. import _legacy_response from ..types import completion_create_params from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given from .._utils import is_given, required_args, maybe_transform, strip_not_given, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper from .._constants import DEFAULT_TIMEOUT from .._streaming import Stream, AsyncStream from .._base_client import make_request_options from ..types.completion import Completion from ..types.model_param import ModelParam from ..types.metadata_param import MetadataParam from ..types.anthropic_beta_param import AnthropicBetaParam __all__ = ["Completions", "AsyncCompletions"] class Completions(SyncAPIResource): @cached_property def with_raw_response(self) -> CompletionsWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the raw response object instead of the parsed content. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers """ return CompletionsWithRawResponse(self) @cached_property def with_streaming_response(self) -> CompletionsWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response """ return CompletionsWithStreamingResponse(self) @overload def create( self, *, max_tokens_to_sample: int, model: ModelParam, prompt: str, metadata: MetadataParam | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, stream: Literal[False] | Omit = omit, temperature: float | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Completion: """[Legacy] Create a Text Completion. The Text Completions API is a legacy API. We recommend using the [Messages API](https://docs.anthropic.com/en/api/messages) going forward. Future models and features will not be compatible with Text Completions. See our [migration guide](https://docs.anthropic.com/en/api/migrating-from-text-completions-to-messages) for guidance in migrating from Text Completions to Messages. Args: max_tokens_to_sample: The maximum number of tokens to generate before stopping. Note that our models may stop _before_ reaching this maximum. This parameter only specifies the absolute maximum number of tokens to generate. model: The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. prompt: The prompt that you want Claude to complete. For proper response generation you will need to format your prompt using alternating `\n\nHuman:` and `\n\nAssistant:` conversational turns. For example: ``` "\n\nHuman: {userQuestion}\n\nAssistant:" ``` See [prompt validation](https://docs.anthropic.com/en/api/prompt-validation) and our guide to [prompt design](https://docs.anthropic.com/en/docs/intro-to-prompting) for more details. metadata: An object describing metadata about the request. stop_sequences: Sequences that will cause the model to stop generating. Our models stop on `"\n\nHuman:"`, and may include additional built-in stop sequences in the future. By providing the stop_sequences parameter, you may include additional strings that will cause the model to stop generating. stream: Whether to incrementally stream the response using server-sent events. See [streaming](https://docs.anthropic.com/en/api/streaming) for details. temperature: Amount of randomness injected into the response. Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0` for analytical / multiple choice, and closer to `1.0` for creative and generative tasks. Note that even with `temperature` of `0.0`, the results will not be fully deterministic. top_k: Only sample from the top K options for each subsequent token. Used to remove "long tail" low probability responses. [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277). Recommended for advanced use cases only. You usually only need to use `temperature`. top_p: Use nucleus sampling. In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by `top_p`. You should either alter `temperature` or `top_p`, but not both. Recommended for advanced use cases only. You usually only need to use `temperature`. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ ... @overload def create( self, *, max_tokens_to_sample: int, model: ModelParam, prompt: str, stream: Literal[True], metadata: MetadataParam | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, temperature: float | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Stream[Completion]: """[Legacy] Create a Text Completion. The Text Completions API is a legacy API. We recommend using the [Messages API](https://docs.anthropic.com/en/api/messages) going forward. Future models and features will not be compatible with Text Completions. See our [migration guide](https://docs.anthropic.com/en/api/migrating-from-text-completions-to-messages) for guidance in migrating from Text Completions to Messages. Args: max_tokens_to_sample: The maximum number of tokens to generate before stopping. Note that our models may stop _before_ reaching this maximum. This parameter only specifies the absolute maximum number of tokens to generate. model: The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. prompt: The prompt that you want Claude to complete. For proper response generation you will need to format your prompt using alternating `\n\nHuman:` and `\n\nAssistant:` conversational turns. For example: ``` "\n\nHuman: {userQuestion}\n\nAssistant:" ``` See [prompt validation](https://docs.anthropic.com/en/api/prompt-validation) and our guide to [prompt design](https://docs.anthropic.com/en/docs/intro-to-prompting) for more details. stream: Whether to incrementally stream the response using server-sent events. See [streaming](https://docs.anthropic.com/en/api/streaming) for details. metadata: An object describing metadata about the request. stop_sequences: Sequences that will cause the model to stop generating. Our models stop on `"\n\nHuman:"`, and may include additional built-in stop sequences in the future. By providing the stop_sequences parameter, you may include additional strings that will cause the model to stop generating. temperature: Amount of randomness injected into the response. Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0` for analytical / multiple choice, and closer to `1.0` for creative and generative tasks. Note that even with `temperature` of `0.0`, the results will not be fully deterministic. top_k: Only sample from the top K options for each subsequent token. Used to remove "long tail" low probability responses. [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277). Recommended for advanced use cases only. You usually only need to use `temperature`. top_p: Use nucleus sampling. In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by `top_p`. You should either alter `temperature` or `top_p`, but not both. Recommended for advanced use cases only. You usually only need to use `temperature`. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ ... @overload def create( self, *, max_tokens_to_sample: int, model: ModelParam, prompt: str, stream: bool, metadata: MetadataParam | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, temperature: float | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Completion | Stream[Completion]: """[Legacy] Create a Text Completion. The Text Completions API is a legacy API. We recommend using the [Messages API](https://docs.anthropic.com/en/api/messages) going forward. Future models and features will not be compatible with Text Completions. See our [migration guide](https://docs.anthropic.com/en/api/migrating-from-text-completions-to-messages) for guidance in migrating from Text Completions to Messages. Args: max_tokens_to_sample: The maximum number of tokens to generate before stopping. Note that our models may stop _before_ reaching this maximum. This parameter only specifies the absolute maximum number of tokens to generate. model: The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. prompt: The prompt that you want Claude to complete. For proper response generation you will need to format your prompt using alternating `\n\nHuman:` and `\n\nAssistant:` conversational turns. For example: ``` "\n\nHuman: {userQuestion}\n\nAssistant:" ``` See [prompt validation](https://docs.anthropic.com/en/api/prompt-validation) and our guide to [prompt design](https://docs.anthropic.com/en/docs/intro-to-prompting) for more details. stream: Whether to incrementally stream the response using server-sent events. See [streaming](https://docs.anthropic.com/en/api/streaming) for details. metadata: An object describing metadata about the request. stop_sequences: Sequences that will cause the model to stop generating. Our models stop on `"\n\nHuman:"`, and may include additional built-in stop sequences in the future. By providing the stop_sequences parameter, you may include additional strings that will cause the model to stop generating. temperature: Amount of randomness injected into the response. Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0` for analytical / multiple choice, and closer to `1.0` for creative and generative tasks. Note that even with `temperature` of `0.0`, the results will not be fully deterministic. top_k: Only sample from the top K options for each subsequent token. Used to remove "long tail" low probability responses. [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277). Recommended for advanced use cases only. You usually only need to use `temperature`. top_p: Use nucleus sampling. In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by `top_p`. You should either alter `temperature` or `top_p`, but not both. Recommended for advanced use cases only. You usually only need to use `temperature`. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ ... @required_args(["max_tokens_to_sample", "model", "prompt"], ["max_tokens_to_sample", "model", "prompt", "stream"]) def create( self, *, max_tokens_to_sample: int, model: ModelParam, prompt: str, metadata: MetadataParam | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, stream: Literal[False] | Literal[True] | Omit = omit, temperature: float | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Completion | Stream[Completion]: if not is_given(timeout) and self._client.timeout == DEFAULT_TIMEOUT: timeout = 600 extra_headers = { **strip_not_given({"anthropic-beta": ",".join(str(e) for e in betas) if is_given(betas) else not_given}), **(extra_headers or {}), } return self._post( "/v1/complete", body=maybe_transform( { "max_tokens_to_sample": max_tokens_to_sample, "model": model, "prompt": prompt, "metadata": metadata, "stop_sequences": stop_sequences, "stream": stream, "temperature": temperature, "top_k": top_k, "top_p": top_p, }, completion_create_params.CompletionCreateParamsStreaming if stream else completion_create_params.CompletionCreateParamsNonStreaming, ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=Completion, stream=stream or False, stream_cls=Stream[Completion], ) class AsyncCompletions(AsyncAPIResource): @cached_property def with_raw_response(self) -> AsyncCompletionsWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the raw response object instead of the parsed content. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers """ return AsyncCompletionsWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncCompletionsWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response """ return AsyncCompletionsWithStreamingResponse(self) @overload async def create( self, *, max_tokens_to_sample: int, model: ModelParam, prompt: str, metadata: MetadataParam | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, stream: Literal[False] | Omit = omit, temperature: float | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Completion: """[Legacy] Create a Text Completion. The Text Completions API is a legacy API. We recommend using the [Messages API](https://docs.anthropic.com/en/api/messages) going forward. Future models and features will not be compatible with Text Completions. See our [migration guide](https://docs.anthropic.com/en/api/migrating-from-text-completions-to-messages) for guidance in migrating from Text Completions to Messages. Args: max_tokens_to_sample: The maximum number of tokens to generate before stopping. Note that our models may stop _before_ reaching this maximum. This parameter only specifies the absolute maximum number of tokens to generate. model: The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. prompt: The prompt that you want Claude to complete. For proper response generation you will need to format your prompt using alternating `\n\nHuman:` and `\n\nAssistant:` conversational turns. For example: ``` "\n\nHuman: {userQuestion}\n\nAssistant:" ``` See [prompt validation](https://docs.anthropic.com/en/api/prompt-validation) and our guide to [prompt design](https://docs.anthropic.com/en/docs/intro-to-prompting) for more details. metadata: An object describing metadata about the request. stop_sequences: Sequences that will cause the model to stop generating. Our models stop on `"\n\nHuman:"`, and may include additional built-in stop sequences in the future. By providing the stop_sequences parameter, you may include additional strings that will cause the model to stop generating. stream: Whether to incrementally stream the response using server-sent events. See [streaming](https://docs.anthropic.com/en/api/streaming) for details. temperature: Amount of randomness injected into the response. Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0` for analytical / multiple choice, and closer to `1.0` for creative and generative tasks. Note that even with `temperature` of `0.0`, the results will not be fully deterministic. top_k: Only sample from the top K options for each subsequent token. Used to remove "long tail" low probability responses. [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277). Recommended for advanced use cases only. You usually only need to use `temperature`. top_p: Use nucleus sampling. In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by `top_p`. You should either alter `temperature` or `top_p`, but not both. Recommended for advanced use cases only. You usually only need to use `temperature`. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ ... @overload async def create( self, *, max_tokens_to_sample: int, model: ModelParam, prompt: str, stream: Literal[True], metadata: MetadataParam | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, temperature: float | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncStream[Completion]: """[Legacy] Create a Text Completion. The Text Completions API is a legacy API. We recommend using the [Messages API](https://docs.anthropic.com/en/api/messages) going forward. Future models and features will not be compatible with Text Completions. See our [migration guide](https://docs.anthropic.com/en/api/migrating-from-text-completions-to-messages) for guidance in migrating from Text Completions to Messages. Args: max_tokens_to_sample: The maximum number of tokens to generate before stopping. Note that our models may stop _before_ reaching this maximum. This parameter only specifies the absolute maximum number of tokens to generate. model: The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. prompt: The prompt that you want Claude to complete. For proper response generation you will need to format your prompt using alternating `\n\nHuman:` and `\n\nAssistant:` conversational turns. For example: ``` "\n\nHuman: {userQuestion}\n\nAssistant:" ``` See [prompt validation](https://docs.anthropic.com/en/api/prompt-validation) and our guide to [prompt design](https://docs.anthropic.com/en/docs/intro-to-prompting) for more details. stream: Whether to incrementally stream the response using server-sent events. See [streaming](https://docs.anthropic.com/en/api/streaming) for details. metadata: An object describing metadata about the request. stop_sequences: Sequences that will cause the model to stop generating. Our models stop on `"\n\nHuman:"`, and may include additional built-in stop sequences in the future. By providing the stop_sequences parameter, you may include additional strings that will cause the model to stop generating. temperature: Amount of randomness injected into the response. Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0` for analytical / multiple choice, and closer to `1.0` for creative and generative tasks. Note that even with `temperature` of `0.0`, the results will not be fully deterministic. top_k: Only sample from the top K options for each subsequent token. Used to remove "long tail" low probability responses. [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277). Recommended for advanced use cases only. You usually only need to use `temperature`. top_p: Use nucleus sampling. In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by `top_p`. You should either alter `temperature` or `top_p`, but not both. Recommended for advanced use cases only. You usually only need to use `temperature`. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ ... @overload async def create( self, *, max_tokens_to_sample: int, model: ModelParam, prompt: str, stream: bool, metadata: MetadataParam | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, temperature: float | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Completion | AsyncStream[Completion]: """[Legacy] Create a Text Completion. The Text Completions API is a legacy API. We recommend using the [Messages API](https://docs.anthropic.com/en/api/messages) going forward. Future models and features will not be compatible with Text Completions. See our [migration guide](https://docs.anthropic.com/en/api/migrating-from-text-completions-to-messages) for guidance in migrating from Text Completions to Messages. Args: max_tokens_to_sample: The maximum number of tokens to generate before stopping. Note that our models may stop _before_ reaching this maximum. This parameter only specifies the absolute maximum number of tokens to generate. model: The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. prompt: The prompt that you want Claude to complete. For proper response generation you will need to format your prompt using alternating `\n\nHuman:` and `\n\nAssistant:` conversational turns. For example: ``` "\n\nHuman: {userQuestion}\n\nAssistant:" ``` See [prompt validation](https://docs.anthropic.com/en/api/prompt-validation) and our guide to [prompt design](https://docs.anthropic.com/en/docs/intro-to-prompting) for more details. stream: Whether to incrementally stream the response using server-sent events. See [streaming](https://docs.anthropic.com/en/api/streaming) for details. metadata: An object describing metadata about the request. stop_sequences: Sequences that will cause the model to stop generating. Our models stop on `"\n\nHuman:"`, and may include additional built-in stop sequences in the future. By providing the stop_sequences parameter, you may include additional strings that will cause the model to stop generating. temperature: Amount of randomness injected into the response. Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0` for analytical / multiple choice, and closer to `1.0` for creative and generative tasks. Note that even with `temperature` of `0.0`, the results will not be fully deterministic. top_k: Only sample from the top K options for each subsequent token. Used to remove "long tail" low probability responses. [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277). Recommended for advanced use cases only. You usually only need to use `temperature`. top_p: Use nucleus sampling. In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by `top_p`. You should either alter `temperature` or `top_p`, but not both. Recommended for advanced use cases only. You usually only need to use `temperature`. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ ... @required_args(["max_tokens_to_sample", "model", "prompt"], ["max_tokens_to_sample", "model", "prompt", "stream"]) async def create( self, *, max_tokens_to_sample: int, model: ModelParam, prompt: str, metadata: MetadataParam | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, stream: Literal[False] | Literal[True] | Omit = omit, temperature: float | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Completion | AsyncStream[Completion]: if not is_given(timeout) and self._client.timeout == DEFAULT_TIMEOUT: timeout = 600 extra_headers = { **strip_not_given({"anthropic-beta": ",".join(str(e) for e in betas) if is_given(betas) else not_given}), **(extra_headers or {}), } return await self._post( "/v1/complete", body=await async_maybe_transform( { "max_tokens_to_sample": max_tokens_to_sample, "model": model, "prompt": prompt, "metadata": metadata, "stop_sequences": stop_sequences, "stream": stream, "temperature": temperature, "top_k": top_k, "top_p": top_p, }, completion_create_params.CompletionCreateParamsStreaming if stream else completion_create_params.CompletionCreateParamsNonStreaming, ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=Completion, stream=stream or False, stream_cls=AsyncStream[Completion], ) class CompletionsWithRawResponse: def __init__(self, completions: Completions) -> None: self._completions = completions self.create = _legacy_response.to_raw_response_wrapper( completions.create, ) class AsyncCompletionsWithRawResponse: def __init__(self, completions: AsyncCompletions) -> None: self._completions = completions self.create = _legacy_response.async_to_raw_response_wrapper( completions.create, ) class CompletionsWithStreamingResponse: def __init__(self, completions: Completions) -> None: self._completions = completions self.create = to_streamed_response_wrapper( completions.create, ) class AsyncCompletionsWithStreamingResponse: def __init__(self, completions: AsyncCompletions) -> None: self._completions = completions self.create = async_to_streamed_response_wrapper( completions.create, ) anthropic-sdk-python-0.69.0/src/anthropic/resources/messages/000077500000000000000000000000001506653454500243075ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/resources/messages/__init__.py000066400000000000000000000016011506653454500264160ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from .batches import ( Batches, AsyncBatches, BatchesWithRawResponse, AsyncBatchesWithRawResponse, BatchesWithStreamingResponse, AsyncBatchesWithStreamingResponse, ) from .messages import ( DEPRECATED_MODELS, Messages, AsyncMessages, MessagesWithRawResponse, AsyncMessagesWithRawResponse, MessagesWithStreamingResponse, AsyncMessagesWithStreamingResponse, ) __all__ = [ "Batches", "AsyncBatches", "BatchesWithRawResponse", "AsyncBatchesWithRawResponse", "BatchesWithStreamingResponse", "AsyncBatchesWithStreamingResponse", "Messages", "AsyncMessages", "MessagesWithRawResponse", "AsyncMessagesWithRawResponse", "MessagesWithStreamingResponse", "AsyncMessagesWithStreamingResponse", "DEPRECATED_MODELS", ] anthropic-sdk-python-0.69.0/src/anthropic/resources/messages/batches.py000066400000000000000000000676041506653454500263070ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Iterable import httpx from ... import _legacy_response from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given from ..._utils import maybe_transform, async_maybe_transform from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper from ...pagination import SyncPage, AsyncPage from ..._exceptions import AnthropicError from ..._base_client import AsyncPaginator, make_request_options from ...types.messages import batch_list_params, batch_create_params from ..._decoders.jsonl import JSONLDecoder, AsyncJSONLDecoder from ...types.messages.message_batch import MessageBatch from ...types.messages.deleted_message_batch import DeletedMessageBatch from ...types.messages.message_batch_individual_response import MessageBatchIndividualResponse __all__ = ["Batches", "AsyncBatches"] class Batches(SyncAPIResource): @cached_property def with_raw_response(self) -> BatchesWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the raw response object instead of the parsed content. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers """ return BatchesWithRawResponse(self) @cached_property def with_streaming_response(self) -> BatchesWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response """ return BatchesWithStreamingResponse(self) def create( self, *, requests: Iterable[batch_create_params.Request], # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> MessageBatch: """ Send a batch of Message creation requests. The Message Batches API can be used to process multiple Messages API requests at once. Once a Message Batch is created, it begins processing immediately. Batches can take up to 24 hours to complete. Learn more about the Message Batches API in our [user guide](/en/docs/build-with-claude/batch-processing) Args: requests: List of requests for prompt completion. Each is an individual request to create a Message. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ return self._post( "/v1/messages/batches", body=maybe_transform({"requests": requests}, batch_create_params.BatchCreateParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=MessageBatch, ) def retrieve( self, message_batch_id: str, *, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> MessageBatch: """This endpoint is idempotent and can be used to poll for Message Batch completion. To access the results of a Message Batch, make a request to the `results_url` field in the response. Learn more about the Message Batches API in our [user guide](/en/docs/build-with-claude/batch-processing) Args: message_batch_id: ID of the Message Batch. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ if not message_batch_id: raise ValueError(f"Expected a non-empty value for `message_batch_id` but received {message_batch_id!r}") return self._get( f"/v1/messages/batches/{message_batch_id}", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=MessageBatch, ) def list( self, *, after_id: str | Omit = omit, before_id: str | Omit = omit, limit: int | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncPage[MessageBatch]: """List all Message Batches within a Workspace. Most recently created batches are returned first. Learn more about the Message Batches API in our [user guide](/en/docs/build-with-claude/batch-processing) Args: after_id: ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately after this object. before_id: ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately before this object. limit: Number of items to return per page. Defaults to `20`. Ranges from `1` to `1000`. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ return self._get_api_list( "/v1/messages/batches", page=SyncPage[MessageBatch], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, query=maybe_transform( { "after_id": after_id, "before_id": before_id, "limit": limit, }, batch_list_params.BatchListParams, ), ), model=MessageBatch, ) def delete( self, message_batch_id: str, *, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> DeletedMessageBatch: """ Delete a Message Batch. Message Batches can only be deleted once they've finished processing. If you'd like to delete an in-progress batch, you must first cancel it. Learn more about the Message Batches API in our [user guide](/en/docs/build-with-claude/batch-processing) Args: message_batch_id: ID of the Message Batch. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ if not message_batch_id: raise ValueError(f"Expected a non-empty value for `message_batch_id` but received {message_batch_id!r}") return self._delete( f"/v1/messages/batches/{message_batch_id}", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=DeletedMessageBatch, ) def cancel( self, message_batch_id: str, *, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> MessageBatch: """Batches may be canceled any time before processing ends. Once cancellation is initiated, the batch enters a `canceling` state, at which time the system may complete any in-progress, non-interruptible requests before finalizing cancellation. The number of canceled requests is specified in `request_counts`. To determine which requests were canceled, check the individual results within the batch. Note that cancellation may not result in any canceled requests if they were non-interruptible. Learn more about the Message Batches API in our [user guide](/en/docs/build-with-claude/batch-processing) Args: message_batch_id: ID of the Message Batch. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ if not message_batch_id: raise ValueError(f"Expected a non-empty value for `message_batch_id` but received {message_batch_id!r}") return self._post( f"/v1/messages/batches/{message_batch_id}/cancel", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=MessageBatch, ) def results( self, message_batch_id: str, *, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> JSONLDecoder[MessageBatchIndividualResponse]: """ Streams the results of a Message Batch as a `.jsonl` file. Each line in the file is a JSON object containing the result of a single request in the Message Batch. Results are not guaranteed to be in the same order as requests. Use the `custom_id` field to match results to requests. Learn more about the Message Batches API in our [user guide](/en/docs/build-with-claude/batch-processing) Args: message_batch_id: ID of the Message Batch. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ if not message_batch_id: raise ValueError(f"Expected a non-empty value for `message_batch_id` but received {message_batch_id!r}") batch = self.retrieve(message_batch_id=message_batch_id) if not batch.results_url: raise AnthropicError( f"No `results_url` for the given batch; Has it finished processing? {batch.processing_status}" ) extra_headers = {"Accept": "application/binary", **(extra_headers or {})} return self._get( batch.results_url, options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=JSONLDecoder[MessageBatchIndividualResponse], stream=True, ) class AsyncBatches(AsyncAPIResource): @cached_property def with_raw_response(self) -> AsyncBatchesWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the raw response object instead of the parsed content. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers """ return AsyncBatchesWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncBatchesWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response """ return AsyncBatchesWithStreamingResponse(self) async def create( self, *, requests: Iterable[batch_create_params.Request], # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> MessageBatch: """ Send a batch of Message creation requests. The Message Batches API can be used to process multiple Messages API requests at once. Once a Message Batch is created, it begins processing immediately. Batches can take up to 24 hours to complete. Learn more about the Message Batches API in our [user guide](/en/docs/build-with-claude/batch-processing) Args: requests: List of requests for prompt completion. Each is an individual request to create a Message. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ return await self._post( "/v1/messages/batches", body=await async_maybe_transform({"requests": requests}, batch_create_params.BatchCreateParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=MessageBatch, ) async def retrieve( self, message_batch_id: str, *, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> MessageBatch: """This endpoint is idempotent and can be used to poll for Message Batch completion. To access the results of a Message Batch, make a request to the `results_url` field in the response. Learn more about the Message Batches API in our [user guide](/en/docs/build-with-claude/batch-processing) Args: message_batch_id: ID of the Message Batch. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ if not message_batch_id: raise ValueError(f"Expected a non-empty value for `message_batch_id` but received {message_batch_id!r}") return await self._get( f"/v1/messages/batches/{message_batch_id}", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=MessageBatch, ) def list( self, *, after_id: str | Omit = omit, before_id: str | Omit = omit, limit: int | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[MessageBatch, AsyncPage[MessageBatch]]: """List all Message Batches within a Workspace. Most recently created batches are returned first. Learn more about the Message Batches API in our [user guide](/en/docs/build-with-claude/batch-processing) Args: after_id: ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately after this object. before_id: ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately before this object. limit: Number of items to return per page. Defaults to `20`. Ranges from `1` to `1000`. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ return self._get_api_list( "/v1/messages/batches", page=AsyncPage[MessageBatch], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, query=maybe_transform( { "after_id": after_id, "before_id": before_id, "limit": limit, }, batch_list_params.BatchListParams, ), ), model=MessageBatch, ) async def delete( self, message_batch_id: str, *, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> DeletedMessageBatch: """ Delete a Message Batch. Message Batches can only be deleted once they've finished processing. If you'd like to delete an in-progress batch, you must first cancel it. Learn more about the Message Batches API in our [user guide](/en/docs/build-with-claude/batch-processing) Args: message_batch_id: ID of the Message Batch. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ if not message_batch_id: raise ValueError(f"Expected a non-empty value for `message_batch_id` but received {message_batch_id!r}") return await self._delete( f"/v1/messages/batches/{message_batch_id}", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=DeletedMessageBatch, ) async def cancel( self, message_batch_id: str, *, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> MessageBatch: """Batches may be canceled any time before processing ends. Once cancellation is initiated, the batch enters a `canceling` state, at which time the system may complete any in-progress, non-interruptible requests before finalizing cancellation. The number of canceled requests is specified in `request_counts`. To determine which requests were canceled, check the individual results within the batch. Note that cancellation may not result in any canceled requests if they were non-interruptible. Learn more about the Message Batches API in our [user guide](/en/docs/build-with-claude/batch-processing) Args: message_batch_id: ID of the Message Batch. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ if not message_batch_id: raise ValueError(f"Expected a non-empty value for `message_batch_id` but received {message_batch_id!r}") return await self._post( f"/v1/messages/batches/{message_batch_id}/cancel", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=MessageBatch, ) async def results( self, message_batch_id: str, *, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncJSONLDecoder[MessageBatchIndividualResponse]: """ Streams the results of a Message Batch as a `.jsonl` file. Each line in the file is a JSON object containing the result of a single request in the Message Batch. Results are not guaranteed to be in the same order as requests. Use the `custom_id` field to match results to requests. Learn more about the Message Batches API in our [user guide](/en/docs/build-with-claude/batch-processing) Args: message_batch_id: ID of the Message Batch. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ if not message_batch_id: raise ValueError(f"Expected a non-empty value for `message_batch_id` but received {message_batch_id!r}") batch = await self.retrieve(message_batch_id=message_batch_id) if not batch.results_url: raise AnthropicError( f"No `results_url` for the given batch; Has it finished processing? {batch.processing_status}" ) extra_headers = {"Accept": "application/binary", **(extra_headers or {})} return await self._get( batch.results_url, options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=AsyncJSONLDecoder[MessageBatchIndividualResponse], stream=True, ) class BatchesWithRawResponse: def __init__(self, batches: Batches) -> None: self._batches = batches self.create = _legacy_response.to_raw_response_wrapper( batches.create, ) self.retrieve = _legacy_response.to_raw_response_wrapper( batches.retrieve, ) self.list = _legacy_response.to_raw_response_wrapper( batches.list, ) self.delete = _legacy_response.to_raw_response_wrapper( batches.delete, ) self.cancel = _legacy_response.to_raw_response_wrapper( batches.cancel, ) class AsyncBatchesWithRawResponse: def __init__(self, batches: AsyncBatches) -> None: self._batches = batches self.create = _legacy_response.async_to_raw_response_wrapper( batches.create, ) self.retrieve = _legacy_response.async_to_raw_response_wrapper( batches.retrieve, ) self.list = _legacy_response.async_to_raw_response_wrapper( batches.list, ) self.delete = _legacy_response.async_to_raw_response_wrapper( batches.delete, ) self.cancel = _legacy_response.async_to_raw_response_wrapper( batches.cancel, ) class BatchesWithStreamingResponse: def __init__(self, batches: Batches) -> None: self._batches = batches self.create = to_streamed_response_wrapper( batches.create, ) self.retrieve = to_streamed_response_wrapper( batches.retrieve, ) self.list = to_streamed_response_wrapper( batches.list, ) self.delete = to_streamed_response_wrapper( batches.delete, ) self.cancel = to_streamed_response_wrapper( batches.cancel, ) class AsyncBatchesWithStreamingResponse: def __init__(self, batches: AsyncBatches) -> None: self._batches = batches self.create = async_to_streamed_response_wrapper( batches.create, ) self.retrieve = async_to_streamed_response_wrapper( batches.retrieve, ) self.list = async_to_streamed_response_wrapper( batches.list, ) self.delete = async_to_streamed_response_wrapper( batches.delete, ) self.cancel = async_to_streamed_response_wrapper( batches.cancel, ) anthropic-sdk-python-0.69.0/src/anthropic/resources/messages/messages.py000066400000000000000000003244341506653454500265020ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations import warnings from typing import Union, Iterable, Optional from functools import partial from typing_extensions import Literal, overload import httpx from ... import _legacy_response from ...types import ( ThinkingConfigParam, message_create_params, message_count_tokens_params, ) from .batches import ( Batches, AsyncBatches, BatchesWithRawResponse, AsyncBatchesWithRawResponse, BatchesWithStreamingResponse, AsyncBatchesWithStreamingResponse, ) from ..._types import NOT_GIVEN, Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given from ..._utils import is_given, required_args, maybe_transform, async_maybe_transform from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper from ..._constants import DEFAULT_TIMEOUT, MODEL_NONSTREAMING_TOKENS from ..._streaming import Stream, AsyncStream from ..._base_client import make_request_options from ...lib.streaming import MessageStreamManager, AsyncMessageStreamManager from ...types.message import Message from ...types.model_param import ModelParam from ...types.message_param import MessageParam from ...types.metadata_param import MetadataParam from ...types.text_block_param import TextBlockParam from ...types.tool_union_param import ToolUnionParam from ...types.tool_choice_param import ToolChoiceParam from ...types.message_tokens_count import MessageTokensCount from ...types.thinking_config_param import ThinkingConfigParam from ...types.raw_message_stream_event import RawMessageStreamEvent from ...types.message_count_tokens_tool_param import MessageCountTokensToolParam __all__ = ["Messages", "AsyncMessages"] DEPRECATED_MODELS = { "claude-1.3": "November 6th, 2024", "claude-1.3-100k": "November 6th, 2024", "claude-instant-1.1": "November 6th, 2024", "claude-instant-1.1-100k": "November 6th, 2024", "claude-instant-1.2": "November 6th, 2024", "claude-3-sonnet-20240229": "July 21st, 2025", "claude-3-opus-20240229": "January 5th, 2026", "claude-2.1": "July 21st, 2025", "claude-2.0": "July 21st, 2025", "claude-3-5-sonnet-20241022": "October 22, 2025", "claude-3-5-sonnet-20240620": "October 22, 2025", } class Messages(SyncAPIResource): @cached_property def batches(self) -> Batches: return Batches(self._client) @cached_property def with_raw_response(self) -> MessagesWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the raw response object instead of the parsed content. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers """ return MessagesWithRawResponse(self) @cached_property def with_streaming_response(self) -> MessagesWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response """ return MessagesWithStreamingResponse(self) @overload def create( self, *, max_tokens: int, messages: Iterable[MessageParam], model: ModelParam, metadata: MetadataParam | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, stream: Literal[False] | Omit = omit, system: Union[str, Iterable[TextBlockParam]] | Omit = omit, temperature: float | Omit = omit, thinking: ThinkingConfigParam | Omit = omit, tool_choice: ToolChoiceParam | Omit = omit, tools: Iterable[ToolUnionParam] | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Message: """ Send a structured list of input messages with text and/or image content, and the model will generate the next message in the conversation. The Messages API can be used for either single queries or stateless multi-turn conversations. Learn more about the Messages API in our [user guide](/en/docs/initial-setup) Args: max_tokens: The maximum number of tokens to generate before stopping. Note that our models may stop _before_ reaching this maximum. This parameter only specifies the absolute maximum number of tokens to generate. Different models have different maximum values for this parameter. See [models](https://docs.anthropic.com/en/docs/models-overview) for details. messages: Input messages. Our models are trained to operate on alternating `user` and `assistant` conversational turns. When creating a new `Message`, you specify the prior conversational turns with the `messages` parameter, and the model then generates the next `Message` in the conversation. Consecutive `user` or `assistant` turns in your request will be combined into a single turn. Each input message must be an object with a `role` and `content`. You can specify a single `user`-role message, or you can include multiple `user` and `assistant` messages. If the final message uses the `assistant` role, the response content will continue immediately from the content in that message. This can be used to constrain part of the model's response. Example with a single `user` message: ```json [{ "role": "user", "content": "Hello, Claude" }] ``` Example with multiple conversational turns: ```json [ { "role": "user", "content": "Hello there." }, { "role": "assistant", "content": "Hi, I'm Claude. How can I help you?" }, { "role": "user", "content": "Can you explain LLMs in plain English?" } ] ``` Example with a partially-filled response from Claude: ```json [ { "role": "user", "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun" }, { "role": "assistant", "content": "The best answer is (" } ] ``` Each input message `content` may be either a single `string` or an array of content blocks, where each block has a specific `type`. Using a `string` for `content` is shorthand for an array of one content block of type `"text"`. The following input messages are equivalent: ```json { "role": "user", "content": "Hello, Claude" } ``` ```json { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } ``` See [input examples](https://docs.anthropic.com/en/api/messages-examples). Note that if you want to include a [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use the top-level `system` parameter — there is no `"system"` role for input messages in the Messages API. There is a limit of 100,000 messages in a single request. model: The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. metadata: An object describing metadata about the request. service_tier: Determines whether to use priority capacity (if available) or standard capacity for this request. Anthropic offers different levels of service for your API requests. See [service-tiers](https://docs.anthropic.com/en/api/service-tiers) for details. stop_sequences: Custom text sequences that will cause the model to stop generating. Our models will normally stop when they have naturally completed their turn, which will result in a response `stop_reason` of `"end_turn"`. If you want the model to stop generating when it encounters custom strings of text, you can use the `stop_sequences` parameter. If the model encounters one of the custom sequences, the response `stop_reason` value will be `"stop_sequence"` and the response `stop_sequence` value will contain the matched stop sequence. stream: Whether to incrementally stream the response using server-sent events. See [streaming](https://docs.anthropic.com/en/api/messages-streaming) for details. system: System prompt. A system prompt is a way of providing context and instructions to Claude, such as specifying a particular goal or role. See our [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts). temperature: Amount of randomness injected into the response. Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0` for analytical / multiple choice, and closer to `1.0` for creative and generative tasks. Note that even with `temperature` of `0.0`, the results will not be fully deterministic. thinking: Configuration for enabling Claude's extended thinking. When enabled, responses include `thinking` content blocks showing Claude's thinking process before the final answer. Requires a minimum budget of 1,024 tokens and counts towards your `max_tokens` limit. See [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) for details. tool_choice: How the model should use the provided tools. The model can use a specific tool, any available tool, decide by itself, or not use tools at all. tools: Definitions of tools that the model may use. If you include `tools` in your API request, the model may return `tool_use` content blocks that represent the model's use of those tools. You can then run those tools using the tool input generated by the model and then optionally return results back to the model using `tool_result` content blocks. There are two types of tools: **client tools** and **server tools**. The behavior described below applies to client tools. For [server tools](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#server-tools), see their individual documentation as each has its own behavior (e.g., the [web search tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool)). Each tool definition includes: - `name`: Name of the tool. - `description`: Optional, but strongly-recommended description of the tool. - `input_schema`: [JSON schema](https://json-schema.org/draft/2020-12) for the tool `input` shape that the model will produce in `tool_use` output content blocks. For example, if you defined `tools` as: ```json [ { "name": "get_stock_price", "description": "Get the current stock price for a given ticker symbol.", "input_schema": { "type": "object", "properties": { "ticker": { "type": "string", "description": "The stock ticker symbol, e.g. AAPL for Apple Inc." } }, "required": ["ticker"] } } ] ``` And then asked the model "What's the S&P 500 at today?", the model might produce `tool_use` content blocks in the response like this: ```json [ { "type": "tool_use", "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "name": "get_stock_price", "input": { "ticker": "^GSPC" } } ] ``` You might then run your `get_stock_price` tool with `{"ticker": "^GSPC"}` as an input, and return the following back to the model in a subsequent `user` message: ```json [ { "type": "tool_result", "tool_use_id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "content": "259.75 USD" } ] ``` Tools can be used for workflows that include running client-side tools and functions, or more generally whenever you want the model to produce a particular JSON structure of output. See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. top_k: Only sample from the top K options for each subsequent token. Used to remove "long tail" low probability responses. [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277). Recommended for advanced use cases only. You usually only need to use `temperature`. top_p: Use nucleus sampling. In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by `top_p`. You should either alter `temperature` or `top_p`, but not both. Recommended for advanced use cases only. You usually only need to use `temperature`. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ ... @overload def create( self, *, max_tokens: int, messages: Iterable[MessageParam], model: ModelParam, stream: Literal[True], metadata: MetadataParam | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, system: Union[str, Iterable[TextBlockParam]] | Omit = omit, temperature: float | Omit = omit, thinking: ThinkingConfigParam | Omit = omit, tool_choice: ToolChoiceParam | Omit = omit, tools: Iterable[ToolUnionParam] | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Stream[RawMessageStreamEvent]: """ Send a structured list of input messages with text and/or image content, and the model will generate the next message in the conversation. The Messages API can be used for either single queries or stateless multi-turn conversations. Learn more about the Messages API in our [user guide](/en/docs/initial-setup) Args: max_tokens: The maximum number of tokens to generate before stopping. Note that our models may stop _before_ reaching this maximum. This parameter only specifies the absolute maximum number of tokens to generate. Different models have different maximum values for this parameter. See [models](https://docs.anthropic.com/en/docs/models-overview) for details. messages: Input messages. Our models are trained to operate on alternating `user` and `assistant` conversational turns. When creating a new `Message`, you specify the prior conversational turns with the `messages` parameter, and the model then generates the next `Message` in the conversation. Consecutive `user` or `assistant` turns in your request will be combined into a single turn. Each input message must be an object with a `role` and `content`. You can specify a single `user`-role message, or you can include multiple `user` and `assistant` messages. If the final message uses the `assistant` role, the response content will continue immediately from the content in that message. This can be used to constrain part of the model's response. Example with a single `user` message: ```json [{ "role": "user", "content": "Hello, Claude" }] ``` Example with multiple conversational turns: ```json [ { "role": "user", "content": "Hello there." }, { "role": "assistant", "content": "Hi, I'm Claude. How can I help you?" }, { "role": "user", "content": "Can you explain LLMs in plain English?" } ] ``` Example with a partially-filled response from Claude: ```json [ { "role": "user", "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun" }, { "role": "assistant", "content": "The best answer is (" } ] ``` Each input message `content` may be either a single `string` or an array of content blocks, where each block has a specific `type`. Using a `string` for `content` is shorthand for an array of one content block of type `"text"`. The following input messages are equivalent: ```json { "role": "user", "content": "Hello, Claude" } ``` ```json { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } ``` See [input examples](https://docs.anthropic.com/en/api/messages-examples). Note that if you want to include a [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use the top-level `system` parameter — there is no `"system"` role for input messages in the Messages API. There is a limit of 100,000 messages in a single request. model: The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. stream: Whether to incrementally stream the response using server-sent events. See [streaming](https://docs.anthropic.com/en/api/messages-streaming) for details. metadata: An object describing metadata about the request. service_tier: Determines whether to use priority capacity (if available) or standard capacity for this request. Anthropic offers different levels of service for your API requests. See [service-tiers](https://docs.anthropic.com/en/api/service-tiers) for details. stop_sequences: Custom text sequences that will cause the model to stop generating. Our models will normally stop when they have naturally completed their turn, which will result in a response `stop_reason` of `"end_turn"`. If you want the model to stop generating when it encounters custom strings of text, you can use the `stop_sequences` parameter. If the model encounters one of the custom sequences, the response `stop_reason` value will be `"stop_sequence"` and the response `stop_sequence` value will contain the matched stop sequence. system: System prompt. A system prompt is a way of providing context and instructions to Claude, such as specifying a particular goal or role. See our [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts). temperature: Amount of randomness injected into the response. Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0` for analytical / multiple choice, and closer to `1.0` for creative and generative tasks. Note that even with `temperature` of `0.0`, the results will not be fully deterministic. thinking: Configuration for enabling Claude's extended thinking. When enabled, responses include `thinking` content blocks showing Claude's thinking process before the final answer. Requires a minimum budget of 1,024 tokens and counts towards your `max_tokens` limit. See [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) for details. tool_choice: How the model should use the provided tools. The model can use a specific tool, any available tool, decide by itself, or not use tools at all. tools: Definitions of tools that the model may use. If you include `tools` in your API request, the model may return `tool_use` content blocks that represent the model's use of those tools. You can then run those tools using the tool input generated by the model and then optionally return results back to the model using `tool_result` content blocks. There are two types of tools: **client tools** and **server tools**. The behavior described below applies to client tools. For [server tools](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#server-tools), see their individual documentation as each has its own behavior (e.g., the [web search tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool)). Each tool definition includes: - `name`: Name of the tool. - `description`: Optional, but strongly-recommended description of the tool. - `input_schema`: [JSON schema](https://json-schema.org/draft/2020-12) for the tool `input` shape that the model will produce in `tool_use` output content blocks. For example, if you defined `tools` as: ```json [ { "name": "get_stock_price", "description": "Get the current stock price for a given ticker symbol.", "input_schema": { "type": "object", "properties": { "ticker": { "type": "string", "description": "The stock ticker symbol, e.g. AAPL for Apple Inc." } }, "required": ["ticker"] } } ] ``` And then asked the model "What's the S&P 500 at today?", the model might produce `tool_use` content blocks in the response like this: ```json [ { "type": "tool_use", "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "name": "get_stock_price", "input": { "ticker": "^GSPC" } } ] ``` You might then run your `get_stock_price` tool with `{"ticker": "^GSPC"}` as an input, and return the following back to the model in a subsequent `user` message: ```json [ { "type": "tool_result", "tool_use_id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "content": "259.75 USD" } ] ``` Tools can be used for workflows that include running client-side tools and functions, or more generally whenever you want the model to produce a particular JSON structure of output. See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. top_k: Only sample from the top K options for each subsequent token. Used to remove "long tail" low probability responses. [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277). Recommended for advanced use cases only. You usually only need to use `temperature`. top_p: Use nucleus sampling. In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by `top_p`. You should either alter `temperature` or `top_p`, but not both. Recommended for advanced use cases only. You usually only need to use `temperature`. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ ... @overload def create( self, *, max_tokens: int, messages: Iterable[MessageParam], model: ModelParam, stream: bool, metadata: MetadataParam | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, system: Union[str, Iterable[TextBlockParam]] | Omit = omit, temperature: float | Omit = omit, thinking: ThinkingConfigParam | Omit = omit, tool_choice: ToolChoiceParam | Omit = omit, tools: Iterable[ToolUnionParam] | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Message | Stream[RawMessageStreamEvent]: """ Send a structured list of input messages with text and/or image content, and the model will generate the next message in the conversation. The Messages API can be used for either single queries or stateless multi-turn conversations. Learn more about the Messages API in our [user guide](/en/docs/initial-setup) Args: max_tokens: The maximum number of tokens to generate before stopping. Note that our models may stop _before_ reaching this maximum. This parameter only specifies the absolute maximum number of tokens to generate. Different models have different maximum values for this parameter. See [models](https://docs.anthropic.com/en/docs/models-overview) for details. messages: Input messages. Our models are trained to operate on alternating `user` and `assistant` conversational turns. When creating a new `Message`, you specify the prior conversational turns with the `messages` parameter, and the model then generates the next `Message` in the conversation. Consecutive `user` or `assistant` turns in your request will be combined into a single turn. Each input message must be an object with a `role` and `content`. You can specify a single `user`-role message, or you can include multiple `user` and `assistant` messages. If the final message uses the `assistant` role, the response content will continue immediately from the content in that message. This can be used to constrain part of the model's response. Example with a single `user` message: ```json [{ "role": "user", "content": "Hello, Claude" }] ``` Example with multiple conversational turns: ```json [ { "role": "user", "content": "Hello there." }, { "role": "assistant", "content": "Hi, I'm Claude. How can I help you?" }, { "role": "user", "content": "Can you explain LLMs in plain English?" } ] ``` Example with a partially-filled response from Claude: ```json [ { "role": "user", "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun" }, { "role": "assistant", "content": "The best answer is (" } ] ``` Each input message `content` may be either a single `string` or an array of content blocks, where each block has a specific `type`. Using a `string` for `content` is shorthand for an array of one content block of type `"text"`. The following input messages are equivalent: ```json { "role": "user", "content": "Hello, Claude" } ``` ```json { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } ``` See [input examples](https://docs.anthropic.com/en/api/messages-examples). Note that if you want to include a [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use the top-level `system` parameter — there is no `"system"` role for input messages in the Messages API. There is a limit of 100,000 messages in a single request. model: The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. stream: Whether to incrementally stream the response using server-sent events. See [streaming](https://docs.anthropic.com/en/api/messages-streaming) for details. metadata: An object describing metadata about the request. service_tier: Determines whether to use priority capacity (if available) or standard capacity for this request. Anthropic offers different levels of service for your API requests. See [service-tiers](https://docs.anthropic.com/en/api/service-tiers) for details. stop_sequences: Custom text sequences that will cause the model to stop generating. Our models will normally stop when they have naturally completed their turn, which will result in a response `stop_reason` of `"end_turn"`. If you want the model to stop generating when it encounters custom strings of text, you can use the `stop_sequences` parameter. If the model encounters one of the custom sequences, the response `stop_reason` value will be `"stop_sequence"` and the response `stop_sequence` value will contain the matched stop sequence. system: System prompt. A system prompt is a way of providing context and instructions to Claude, such as specifying a particular goal or role. See our [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts). temperature: Amount of randomness injected into the response. Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0` for analytical / multiple choice, and closer to `1.0` for creative and generative tasks. Note that even with `temperature` of `0.0`, the results will not be fully deterministic. thinking: Configuration for enabling Claude's extended thinking. When enabled, responses include `thinking` content blocks showing Claude's thinking process before the final answer. Requires a minimum budget of 1,024 tokens and counts towards your `max_tokens` limit. See [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) for details. tool_choice: How the model should use the provided tools. The model can use a specific tool, any available tool, decide by itself, or not use tools at all. tools: Definitions of tools that the model may use. If you include `tools` in your API request, the model may return `tool_use` content blocks that represent the model's use of those tools. You can then run those tools using the tool input generated by the model and then optionally return results back to the model using `tool_result` content blocks. There are two types of tools: **client tools** and **server tools**. The behavior described below applies to client tools. For [server tools](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#server-tools), see their individual documentation as each has its own behavior (e.g., the [web search tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool)). Each tool definition includes: - `name`: Name of the tool. - `description`: Optional, but strongly-recommended description of the tool. - `input_schema`: [JSON schema](https://json-schema.org/draft/2020-12) for the tool `input` shape that the model will produce in `tool_use` output content blocks. For example, if you defined `tools` as: ```json [ { "name": "get_stock_price", "description": "Get the current stock price for a given ticker symbol.", "input_schema": { "type": "object", "properties": { "ticker": { "type": "string", "description": "The stock ticker symbol, e.g. AAPL for Apple Inc." } }, "required": ["ticker"] } } ] ``` And then asked the model "What's the S&P 500 at today?", the model might produce `tool_use` content blocks in the response like this: ```json [ { "type": "tool_use", "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "name": "get_stock_price", "input": { "ticker": "^GSPC" } } ] ``` You might then run your `get_stock_price` tool with `{"ticker": "^GSPC"}` as an input, and return the following back to the model in a subsequent `user` message: ```json [ { "type": "tool_result", "tool_use_id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "content": "259.75 USD" } ] ``` Tools can be used for workflows that include running client-side tools and functions, or more generally whenever you want the model to produce a particular JSON structure of output. See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. top_k: Only sample from the top K options for each subsequent token. Used to remove "long tail" low probability responses. [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277). Recommended for advanced use cases only. You usually only need to use `temperature`. top_p: Use nucleus sampling. In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by `top_p`. You should either alter `temperature` or `top_p`, but not both. Recommended for advanced use cases only. You usually only need to use `temperature`. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ ... @required_args(["max_tokens", "messages", "model"], ["max_tokens", "messages", "model", "stream"]) def create( self, *, max_tokens: int, messages: Iterable[MessageParam], model: ModelParam, metadata: MetadataParam | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, stream: Literal[False] | Literal[True] | Omit = omit, system: Union[str, Iterable[TextBlockParam]] | Omit = omit, temperature: float | Omit = omit, thinking: ThinkingConfigParam | Omit = omit, tool_choice: ToolChoiceParam | Omit = omit, tools: Iterable[ToolUnionParam] | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Message | Stream[RawMessageStreamEvent]: if not stream and not is_given(timeout) and self._client.timeout == DEFAULT_TIMEOUT: timeout = self._client._calculate_nonstreaming_timeout( max_tokens, MODEL_NONSTREAMING_TOKENS.get(model, None) ) if model in DEPRECATED_MODELS: warnings.warn( f"The model '{model}' is deprecated and will reach end-of-life on {DEPRECATED_MODELS[model]}.\nPlease migrate to a newer model. Visit https://docs.anthropic.com/en/docs/resources/model-deprecations for more information.", DeprecationWarning, stacklevel=3, ) return self._post( "/v1/messages", body=maybe_transform( { "max_tokens": max_tokens, "messages": messages, "model": model, "metadata": metadata, "service_tier": service_tier, "stop_sequences": stop_sequences, "stream": stream, "system": system, "temperature": temperature, "thinking": thinking, "tool_choice": tool_choice, "tools": tools, "top_k": top_k, "top_p": top_p, }, message_create_params.MessageCreateParamsStreaming if stream else message_create_params.MessageCreateParamsNonStreaming, ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=Message, stream=stream or False, stream_cls=Stream[RawMessageStreamEvent], ) def stream( self, *, max_tokens: int, messages: Iterable[MessageParam], model: ModelParam, metadata: MetadataParam | Omit = omit, container: Optional[str] | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, system: Union[str, Iterable[TextBlockParam]] | Omit = omit, temperature: float | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, thinking: ThinkingConfigParam | Omit = omit, tool_choice: ToolChoiceParam | Omit = omit, tools: Iterable[ToolUnionParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, ) -> MessageStreamManager: """Create a Message stream""" if model in DEPRECATED_MODELS: warnings.warn( f"The model '{model}' is deprecated and will reach end-of-life on {DEPRECATED_MODELS[model]}.\nPlease migrate to a newer model. Visit https://docs.anthropic.com/en/docs/resources/model-deprecations for more information.", DeprecationWarning, stacklevel=3, ) extra_headers = { "X-Stainless-Stream-Helper": "messages", **(extra_headers or {}), } make_request = partial( self._post, "/v1/messages", body=maybe_transform( { "max_tokens": max_tokens, "messages": messages, "model": model, "metadata": metadata, "container": container, "service_tier": service_tier, "stop_sequences": stop_sequences, "system": system, "temperature": temperature, "top_k": top_k, "top_p": top_p, "tools": tools, "thinking": thinking, "tool_choice": tool_choice, "stream": True, }, message_create_params.MessageCreateParams, ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=Message, stream=True, stream_cls=Stream[RawMessageStreamEvent], ) return MessageStreamManager(make_request) def count_tokens( self, *, messages: Iterable[MessageParam], model: ModelParam, system: Union[str, Iterable[TextBlockParam]] | Omit = omit, thinking: ThinkingConfigParam | Omit = omit, tool_choice: ToolChoiceParam | Omit = omit, tools: Iterable[MessageCountTokensToolParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> MessageTokensCount: """ Count the number of tokens in a Message. The Token Count API can be used to count the number of tokens in a Message, including tools, images, and documents, without creating it. Learn more about token counting in our [user guide](/en/docs/build-with-claude/token-counting) Args: messages: Input messages. Our models are trained to operate on alternating `user` and `assistant` conversational turns. When creating a new `Message`, you specify the prior conversational turns with the `messages` parameter, and the model then generates the next `Message` in the conversation. Consecutive `user` or `assistant` turns in your request will be combined into a single turn. Each input message must be an object with a `role` and `content`. You can specify a single `user`-role message, or you can include multiple `user` and `assistant` messages. If the final message uses the `assistant` role, the response content will continue immediately from the content in that message. This can be used to constrain part of the model's response. Example with a single `user` message: ```json [{ "role": "user", "content": "Hello, Claude" }] ``` Example with multiple conversational turns: ```json [ { "role": "user", "content": "Hello there." }, { "role": "assistant", "content": "Hi, I'm Claude. How can I help you?" }, { "role": "user", "content": "Can you explain LLMs in plain English?" } ] ``` Example with a partially-filled response from Claude: ```json [ { "role": "user", "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun" }, { "role": "assistant", "content": "The best answer is (" } ] ``` Each input message `content` may be either a single `string` or an array of content blocks, where each block has a specific `type`. Using a `string` for `content` is shorthand for an array of one content block of type `"text"`. The following input messages are equivalent: ```json { "role": "user", "content": "Hello, Claude" } ``` ```json { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } ``` See [input examples](https://docs.anthropic.com/en/api/messages-examples). Note that if you want to include a [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use the top-level `system` parameter — there is no `"system"` role for input messages in the Messages API. There is a limit of 100,000 messages in a single request. model: The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. system: System prompt. A system prompt is a way of providing context and instructions to Claude, such as specifying a particular goal or role. See our [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts). thinking: Configuration for enabling Claude's extended thinking. When enabled, responses include `thinking` content blocks showing Claude's thinking process before the final answer. Requires a minimum budget of 1,024 tokens and counts towards your `max_tokens` limit. See [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) for details. tool_choice: How the model should use the provided tools. The model can use a specific tool, any available tool, decide by itself, or not use tools at all. tools: Definitions of tools that the model may use. If you include `tools` in your API request, the model may return `tool_use` content blocks that represent the model's use of those tools. You can then run those tools using the tool input generated by the model and then optionally return results back to the model using `tool_result` content blocks. There are two types of tools: **client tools** and **server tools**. The behavior described below applies to client tools. For [server tools](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#server-tools), see their individual documentation as each has its own behavior (e.g., the [web search tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool)). Each tool definition includes: - `name`: Name of the tool. - `description`: Optional, but strongly-recommended description of the tool. - `input_schema`: [JSON schema](https://json-schema.org/draft/2020-12) for the tool `input` shape that the model will produce in `tool_use` output content blocks. For example, if you defined `tools` as: ```json [ { "name": "get_stock_price", "description": "Get the current stock price for a given ticker symbol.", "input_schema": { "type": "object", "properties": { "ticker": { "type": "string", "description": "The stock ticker symbol, e.g. AAPL for Apple Inc." } }, "required": ["ticker"] } } ] ``` And then asked the model "What's the S&P 500 at today?", the model might produce `tool_use` content blocks in the response like this: ```json [ { "type": "tool_use", "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "name": "get_stock_price", "input": { "ticker": "^GSPC" } } ] ``` You might then run your `get_stock_price` tool with `{"ticker": "^GSPC"}` as an input, and return the following back to the model in a subsequent `user` message: ```json [ { "type": "tool_result", "tool_use_id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "content": "259.75 USD" } ] ``` Tools can be used for workflows that include running client-side tools and functions, or more generally whenever you want the model to produce a particular JSON structure of output. See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ return self._post( "/v1/messages/count_tokens", body=maybe_transform( { "messages": messages, "model": model, "system": system, "thinking": thinking, "tool_choice": tool_choice, "tools": tools, }, message_count_tokens_params.MessageCountTokensParams, ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=MessageTokensCount, ) class AsyncMessages(AsyncAPIResource): @cached_property def batches(self) -> AsyncBatches: return AsyncBatches(self._client) @cached_property def with_raw_response(self) -> AsyncMessagesWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the raw response object instead of the parsed content. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers """ return AsyncMessagesWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncMessagesWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response """ return AsyncMessagesWithStreamingResponse(self) @overload async def create( self, *, max_tokens: int, messages: Iterable[MessageParam], model: ModelParam, metadata: MetadataParam | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, stream: Literal[False] | Omit = omit, system: Union[str, Iterable[TextBlockParam]] | Omit = omit, temperature: float | Omit = omit, thinking: ThinkingConfigParam | Omit = omit, tool_choice: ToolChoiceParam | Omit = omit, tools: Iterable[ToolUnionParam] | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Message: """ Send a structured list of input messages with text and/or image content, and the model will generate the next message in the conversation. The Messages API can be used for either single queries or stateless multi-turn conversations. Learn more about the Messages API in our [user guide](/en/docs/initial-setup) Args: max_tokens: The maximum number of tokens to generate before stopping. Note that our models may stop _before_ reaching this maximum. This parameter only specifies the absolute maximum number of tokens to generate. Different models have different maximum values for this parameter. See [models](https://docs.anthropic.com/en/docs/models-overview) for details. messages: Input messages. Our models are trained to operate on alternating `user` and `assistant` conversational turns. When creating a new `Message`, you specify the prior conversational turns with the `messages` parameter, and the model then generates the next `Message` in the conversation. Consecutive `user` or `assistant` turns in your request will be combined into a single turn. Each input message must be an object with a `role` and `content`. You can specify a single `user`-role message, or you can include multiple `user` and `assistant` messages. If the final message uses the `assistant` role, the response content will continue immediately from the content in that message. This can be used to constrain part of the model's response. Example with a single `user` message: ```json [{ "role": "user", "content": "Hello, Claude" }] ``` Example with multiple conversational turns: ```json [ { "role": "user", "content": "Hello there." }, { "role": "assistant", "content": "Hi, I'm Claude. How can I help you?" }, { "role": "user", "content": "Can you explain LLMs in plain English?" } ] ``` Example with a partially-filled response from Claude: ```json [ { "role": "user", "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun" }, { "role": "assistant", "content": "The best answer is (" } ] ``` Each input message `content` may be either a single `string` or an array of content blocks, where each block has a specific `type`. Using a `string` for `content` is shorthand for an array of one content block of type `"text"`. The following input messages are equivalent: ```json { "role": "user", "content": "Hello, Claude" } ``` ```json { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } ``` See [input examples](https://docs.anthropic.com/en/api/messages-examples). Note that if you want to include a [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use the top-level `system` parameter — there is no `"system"` role for input messages in the Messages API. There is a limit of 100,000 messages in a single request. model: The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. metadata: An object describing metadata about the request. service_tier: Determines whether to use priority capacity (if available) or standard capacity for this request. Anthropic offers different levels of service for your API requests. See [service-tiers](https://docs.anthropic.com/en/api/service-tiers) for details. stop_sequences: Custom text sequences that will cause the model to stop generating. Our models will normally stop when they have naturally completed their turn, which will result in a response `stop_reason` of `"end_turn"`. If you want the model to stop generating when it encounters custom strings of text, you can use the `stop_sequences` parameter. If the model encounters one of the custom sequences, the response `stop_reason` value will be `"stop_sequence"` and the response `stop_sequence` value will contain the matched stop sequence. stream: Whether to incrementally stream the response using server-sent events. See [streaming](https://docs.anthropic.com/en/api/messages-streaming) for details. system: System prompt. A system prompt is a way of providing context and instructions to Claude, such as specifying a particular goal or role. See our [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts). temperature: Amount of randomness injected into the response. Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0` for analytical / multiple choice, and closer to `1.0` for creative and generative tasks. Note that even with `temperature` of `0.0`, the results will not be fully deterministic. thinking: Configuration for enabling Claude's extended thinking. When enabled, responses include `thinking` content blocks showing Claude's thinking process before the final answer. Requires a minimum budget of 1,024 tokens and counts towards your `max_tokens` limit. See [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) for details. tool_choice: How the model should use the provided tools. The model can use a specific tool, any available tool, decide by itself, or not use tools at all. tools: Definitions of tools that the model may use. If you include `tools` in your API request, the model may return `tool_use` content blocks that represent the model's use of those tools. You can then run those tools using the tool input generated by the model and then optionally return results back to the model using `tool_result` content blocks. There are two types of tools: **client tools** and **server tools**. The behavior described below applies to client tools. For [server tools](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#server-tools), see their individual documentation as each has its own behavior (e.g., the [web search tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool)). Each tool definition includes: - `name`: Name of the tool. - `description`: Optional, but strongly-recommended description of the tool. - `input_schema`: [JSON schema](https://json-schema.org/draft/2020-12) for the tool `input` shape that the model will produce in `tool_use` output content blocks. For example, if you defined `tools` as: ```json [ { "name": "get_stock_price", "description": "Get the current stock price for a given ticker symbol.", "input_schema": { "type": "object", "properties": { "ticker": { "type": "string", "description": "The stock ticker symbol, e.g. AAPL for Apple Inc." } }, "required": ["ticker"] } } ] ``` And then asked the model "What's the S&P 500 at today?", the model might produce `tool_use` content blocks in the response like this: ```json [ { "type": "tool_use", "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "name": "get_stock_price", "input": { "ticker": "^GSPC" } } ] ``` You might then run your `get_stock_price` tool with `{"ticker": "^GSPC"}` as an input, and return the following back to the model in a subsequent `user` message: ```json [ { "type": "tool_result", "tool_use_id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "content": "259.75 USD" } ] ``` Tools can be used for workflows that include running client-side tools and functions, or more generally whenever you want the model to produce a particular JSON structure of output. See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. top_k: Only sample from the top K options for each subsequent token. Used to remove "long tail" low probability responses. [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277). Recommended for advanced use cases only. You usually only need to use `temperature`. top_p: Use nucleus sampling. In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by `top_p`. You should either alter `temperature` or `top_p`, but not both. Recommended for advanced use cases only. You usually only need to use `temperature`. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ ... @overload async def create( self, *, max_tokens: int, messages: Iterable[MessageParam], model: ModelParam, stream: Literal[True], metadata: MetadataParam | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, system: Union[str, Iterable[TextBlockParam]] | Omit = omit, temperature: float | Omit = omit, thinking: ThinkingConfigParam | Omit = omit, tool_choice: ToolChoiceParam | Omit = omit, tools: Iterable[ToolUnionParam] | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncStream[RawMessageStreamEvent]: """ Send a structured list of input messages with text and/or image content, and the model will generate the next message in the conversation. The Messages API can be used for either single queries or stateless multi-turn conversations. Learn more about the Messages API in our [user guide](/en/docs/initial-setup) Args: max_tokens: The maximum number of tokens to generate before stopping. Note that our models may stop _before_ reaching this maximum. This parameter only specifies the absolute maximum number of tokens to generate. Different models have different maximum values for this parameter. See [models](https://docs.anthropic.com/en/docs/models-overview) for details. messages: Input messages. Our models are trained to operate on alternating `user` and `assistant` conversational turns. When creating a new `Message`, you specify the prior conversational turns with the `messages` parameter, and the model then generates the next `Message` in the conversation. Consecutive `user` or `assistant` turns in your request will be combined into a single turn. Each input message must be an object with a `role` and `content`. You can specify a single `user`-role message, or you can include multiple `user` and `assistant` messages. If the final message uses the `assistant` role, the response content will continue immediately from the content in that message. This can be used to constrain part of the model's response. Example with a single `user` message: ```json [{ "role": "user", "content": "Hello, Claude" }] ``` Example with multiple conversational turns: ```json [ { "role": "user", "content": "Hello there." }, { "role": "assistant", "content": "Hi, I'm Claude. How can I help you?" }, { "role": "user", "content": "Can you explain LLMs in plain English?" } ] ``` Example with a partially-filled response from Claude: ```json [ { "role": "user", "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun" }, { "role": "assistant", "content": "The best answer is (" } ] ``` Each input message `content` may be either a single `string` or an array of content blocks, where each block has a specific `type`. Using a `string` for `content` is shorthand for an array of one content block of type `"text"`. The following input messages are equivalent: ```json { "role": "user", "content": "Hello, Claude" } ``` ```json { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } ``` See [input examples](https://docs.anthropic.com/en/api/messages-examples). Note that if you want to include a [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use the top-level `system` parameter — there is no `"system"` role for input messages in the Messages API. There is a limit of 100,000 messages in a single request. model: The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. stream: Whether to incrementally stream the response using server-sent events. See [streaming](https://docs.anthropic.com/en/api/messages-streaming) for details. metadata: An object describing metadata about the request. service_tier: Determines whether to use priority capacity (if available) or standard capacity for this request. Anthropic offers different levels of service for your API requests. See [service-tiers](https://docs.anthropic.com/en/api/service-tiers) for details. stop_sequences: Custom text sequences that will cause the model to stop generating. Our models will normally stop when they have naturally completed their turn, which will result in a response `stop_reason` of `"end_turn"`. If you want the model to stop generating when it encounters custom strings of text, you can use the `stop_sequences` parameter. If the model encounters one of the custom sequences, the response `stop_reason` value will be `"stop_sequence"` and the response `stop_sequence` value will contain the matched stop sequence. system: System prompt. A system prompt is a way of providing context and instructions to Claude, such as specifying a particular goal or role. See our [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts). temperature: Amount of randomness injected into the response. Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0` for analytical / multiple choice, and closer to `1.0` for creative and generative tasks. Note that even with `temperature` of `0.0`, the results will not be fully deterministic. thinking: Configuration for enabling Claude's extended thinking. When enabled, responses include `thinking` content blocks showing Claude's thinking process before the final answer. Requires a minimum budget of 1,024 tokens and counts towards your `max_tokens` limit. See [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) for details. tool_choice: How the model should use the provided tools. The model can use a specific tool, any available tool, decide by itself, or not use tools at all. tools: Definitions of tools that the model may use. If you include `tools` in your API request, the model may return `tool_use` content blocks that represent the model's use of those tools. You can then run those tools using the tool input generated by the model and then optionally return results back to the model using `tool_result` content blocks. There are two types of tools: **client tools** and **server tools**. The behavior described below applies to client tools. For [server tools](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#server-tools), see their individual documentation as each has its own behavior (e.g., the [web search tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool)). Each tool definition includes: - `name`: Name of the tool. - `description`: Optional, but strongly-recommended description of the tool. - `input_schema`: [JSON schema](https://json-schema.org/draft/2020-12) for the tool `input` shape that the model will produce in `tool_use` output content blocks. For example, if you defined `tools` as: ```json [ { "name": "get_stock_price", "description": "Get the current stock price for a given ticker symbol.", "input_schema": { "type": "object", "properties": { "ticker": { "type": "string", "description": "The stock ticker symbol, e.g. AAPL for Apple Inc." } }, "required": ["ticker"] } } ] ``` And then asked the model "What's the S&P 500 at today?", the model might produce `tool_use` content blocks in the response like this: ```json [ { "type": "tool_use", "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "name": "get_stock_price", "input": { "ticker": "^GSPC" } } ] ``` You might then run your `get_stock_price` tool with `{"ticker": "^GSPC"}` as an input, and return the following back to the model in a subsequent `user` message: ```json [ { "type": "tool_result", "tool_use_id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "content": "259.75 USD" } ] ``` Tools can be used for workflows that include running client-side tools and functions, or more generally whenever you want the model to produce a particular JSON structure of output. See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. top_k: Only sample from the top K options for each subsequent token. Used to remove "long tail" low probability responses. [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277). Recommended for advanced use cases only. You usually only need to use `temperature`. top_p: Use nucleus sampling. In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by `top_p`. You should either alter `temperature` or `top_p`, but not both. Recommended for advanced use cases only. You usually only need to use `temperature`. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ ... @overload async def create( self, *, max_tokens: int, messages: Iterable[MessageParam], model: ModelParam, stream: bool, metadata: MetadataParam | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, system: Union[str, Iterable[TextBlockParam]] | Omit = omit, temperature: float | Omit = omit, thinking: ThinkingConfigParam | Omit = omit, tool_choice: ToolChoiceParam | Omit = omit, tools: Iterable[ToolUnionParam] | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Message | AsyncStream[RawMessageStreamEvent]: """ Send a structured list of input messages with text and/or image content, and the model will generate the next message in the conversation. The Messages API can be used for either single queries or stateless multi-turn conversations. Learn more about the Messages API in our [user guide](/en/docs/initial-setup) Args: max_tokens: The maximum number of tokens to generate before stopping. Note that our models may stop _before_ reaching this maximum. This parameter only specifies the absolute maximum number of tokens to generate. Different models have different maximum values for this parameter. See [models](https://docs.anthropic.com/en/docs/models-overview) for details. messages: Input messages. Our models are trained to operate on alternating `user` and `assistant` conversational turns. When creating a new `Message`, you specify the prior conversational turns with the `messages` parameter, and the model then generates the next `Message` in the conversation. Consecutive `user` or `assistant` turns in your request will be combined into a single turn. Each input message must be an object with a `role` and `content`. You can specify a single `user`-role message, or you can include multiple `user` and `assistant` messages. If the final message uses the `assistant` role, the response content will continue immediately from the content in that message. This can be used to constrain part of the model's response. Example with a single `user` message: ```json [{ "role": "user", "content": "Hello, Claude" }] ``` Example with multiple conversational turns: ```json [ { "role": "user", "content": "Hello there." }, { "role": "assistant", "content": "Hi, I'm Claude. How can I help you?" }, { "role": "user", "content": "Can you explain LLMs in plain English?" } ] ``` Example with a partially-filled response from Claude: ```json [ { "role": "user", "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun" }, { "role": "assistant", "content": "The best answer is (" } ] ``` Each input message `content` may be either a single `string` or an array of content blocks, where each block has a specific `type`. Using a `string` for `content` is shorthand for an array of one content block of type `"text"`. The following input messages are equivalent: ```json { "role": "user", "content": "Hello, Claude" } ``` ```json { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } ``` See [input examples](https://docs.anthropic.com/en/api/messages-examples). Note that if you want to include a [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use the top-level `system` parameter — there is no `"system"` role for input messages in the Messages API. There is a limit of 100,000 messages in a single request. model: The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. stream: Whether to incrementally stream the response using server-sent events. See [streaming](https://docs.anthropic.com/en/api/messages-streaming) for details. metadata: An object describing metadata about the request. service_tier: Determines whether to use priority capacity (if available) or standard capacity for this request. Anthropic offers different levels of service for your API requests. See [service-tiers](https://docs.anthropic.com/en/api/service-tiers) for details. stop_sequences: Custom text sequences that will cause the model to stop generating. Our models will normally stop when they have naturally completed their turn, which will result in a response `stop_reason` of `"end_turn"`. If you want the model to stop generating when it encounters custom strings of text, you can use the `stop_sequences` parameter. If the model encounters one of the custom sequences, the response `stop_reason` value will be `"stop_sequence"` and the response `stop_sequence` value will contain the matched stop sequence. system: System prompt. A system prompt is a way of providing context and instructions to Claude, such as specifying a particular goal or role. See our [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts). temperature: Amount of randomness injected into the response. Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0` for analytical / multiple choice, and closer to `1.0` for creative and generative tasks. Note that even with `temperature` of `0.0`, the results will not be fully deterministic. thinking: Configuration for enabling Claude's extended thinking. When enabled, responses include `thinking` content blocks showing Claude's thinking process before the final answer. Requires a minimum budget of 1,024 tokens and counts towards your `max_tokens` limit. See [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) for details. tool_choice: How the model should use the provided tools. The model can use a specific tool, any available tool, decide by itself, or not use tools at all. tools: Definitions of tools that the model may use. If you include `tools` in your API request, the model may return `tool_use` content blocks that represent the model's use of those tools. You can then run those tools using the tool input generated by the model and then optionally return results back to the model using `tool_result` content blocks. There are two types of tools: **client tools** and **server tools**. The behavior described below applies to client tools. For [server tools](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#server-tools), see their individual documentation as each has its own behavior (e.g., the [web search tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool)). Each tool definition includes: - `name`: Name of the tool. - `description`: Optional, but strongly-recommended description of the tool. - `input_schema`: [JSON schema](https://json-schema.org/draft/2020-12) for the tool `input` shape that the model will produce in `tool_use` output content blocks. For example, if you defined `tools` as: ```json [ { "name": "get_stock_price", "description": "Get the current stock price for a given ticker symbol.", "input_schema": { "type": "object", "properties": { "ticker": { "type": "string", "description": "The stock ticker symbol, e.g. AAPL for Apple Inc." } }, "required": ["ticker"] } } ] ``` And then asked the model "What's the S&P 500 at today?", the model might produce `tool_use` content blocks in the response like this: ```json [ { "type": "tool_use", "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "name": "get_stock_price", "input": { "ticker": "^GSPC" } } ] ``` You might then run your `get_stock_price` tool with `{"ticker": "^GSPC"}` as an input, and return the following back to the model in a subsequent `user` message: ```json [ { "type": "tool_result", "tool_use_id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "content": "259.75 USD" } ] ``` Tools can be used for workflows that include running client-side tools and functions, or more generally whenever you want the model to produce a particular JSON structure of output. See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. top_k: Only sample from the top K options for each subsequent token. Used to remove "long tail" low probability responses. [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277). Recommended for advanced use cases only. You usually only need to use `temperature`. top_p: Use nucleus sampling. In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by `top_p`. You should either alter `temperature` or `top_p`, but not both. Recommended for advanced use cases only. You usually only need to use `temperature`. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ ... @required_args(["max_tokens", "messages", "model"], ["max_tokens", "messages", "model", "stream"]) async def create( self, *, max_tokens: int, messages: Iterable[MessageParam], model: ModelParam, metadata: MetadataParam | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, stream: Literal[False] | Literal[True] | Omit = omit, system: Union[str, Iterable[TextBlockParam]] | Omit = omit, temperature: float | Omit = omit, thinking: ThinkingConfigParam | Omit = omit, tool_choice: ToolChoiceParam | Omit = omit, tools: Iterable[ToolUnionParam] | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Message | AsyncStream[RawMessageStreamEvent]: if not stream and not is_given(timeout) and self._client.timeout == DEFAULT_TIMEOUT: timeout = self._client._calculate_nonstreaming_timeout( max_tokens, MODEL_NONSTREAMING_TOKENS.get(model, None) ) if model in DEPRECATED_MODELS: warnings.warn( f"The model '{model}' is deprecated and will reach end-of-life on {DEPRECATED_MODELS[model]}.\nPlease migrate to a newer model. Visit https://docs.anthropic.com/en/docs/resources/model-deprecations for more information.", DeprecationWarning, stacklevel=3, ) return await self._post( "/v1/messages", body=await async_maybe_transform( { "max_tokens": max_tokens, "messages": messages, "model": model, "metadata": metadata, "service_tier": service_tier, "stop_sequences": stop_sequences, "stream": stream, "system": system, "temperature": temperature, "thinking": thinking, "tool_choice": tool_choice, "tools": tools, "top_k": top_k, "top_p": top_p, }, message_create_params.MessageCreateParamsStreaming if stream else message_create_params.MessageCreateParamsNonStreaming, ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=Message, stream=stream or False, stream_cls=AsyncStream[RawMessageStreamEvent], ) def stream( self, *, max_tokens: int, messages: Iterable[MessageParam], model: ModelParam, metadata: MetadataParam | Omit = omit, container: Optional[str] | Omit = omit, service_tier: Literal["auto", "standard_only"] | Omit = omit, stop_sequences: SequenceNotStr[str] | Omit = omit, system: Union[str, Iterable[TextBlockParam]] | Omit = omit, temperature: float | Omit = omit, top_k: int | Omit = omit, top_p: float | Omit = omit, thinking: ThinkingConfigParam | Omit = omit, tool_choice: ToolChoiceParam | Omit = omit, tools: Iterable[ToolUnionParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, ) -> AsyncMessageStreamManager: """Create a Message stream""" if model in DEPRECATED_MODELS: warnings.warn( f"The model '{model}' is deprecated and will reach end-of-life on {DEPRECATED_MODELS[model]}.\nPlease migrate to a newer model. Visit https://docs.anthropic.com/en/docs/resources/model-deprecations for more information.", DeprecationWarning, stacklevel=3, ) extra_headers = { "X-Stainless-Stream-Helper": "messages", **(extra_headers or {}), } request = self._post( "/v1/messages", body=maybe_transform( { "max_tokens": max_tokens, "messages": messages, "model": model, "metadata": metadata, "container": container, "service_tier": service_tier, "stop_sequences": stop_sequences, "system": system, "temperature": temperature, "top_k": top_k, "top_p": top_p, "tools": tools, "thinking": thinking, "tool_choice": tool_choice, "stream": True, }, message_create_params.MessageCreateParams, ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=Message, stream=True, stream_cls=AsyncStream[RawMessageStreamEvent], ) return AsyncMessageStreamManager(request) async def count_tokens( self, *, messages: Iterable[MessageParam], model: ModelParam, system: Union[str, Iterable[TextBlockParam]] | Omit = omit, thinking: ThinkingConfigParam | Omit = omit, tool_choice: ToolChoiceParam | Omit = omit, tools: Iterable[MessageCountTokensToolParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> MessageTokensCount: """ Count the number of tokens in a Message. The Token Count API can be used to count the number of tokens in a Message, including tools, images, and documents, without creating it. Learn more about token counting in our [user guide](/en/docs/build-with-claude/token-counting) Args: messages: Input messages. Our models are trained to operate on alternating `user` and `assistant` conversational turns. When creating a new `Message`, you specify the prior conversational turns with the `messages` parameter, and the model then generates the next `Message` in the conversation. Consecutive `user` or `assistant` turns in your request will be combined into a single turn. Each input message must be an object with a `role` and `content`. You can specify a single `user`-role message, or you can include multiple `user` and `assistant` messages. If the final message uses the `assistant` role, the response content will continue immediately from the content in that message. This can be used to constrain part of the model's response. Example with a single `user` message: ```json [{ "role": "user", "content": "Hello, Claude" }] ``` Example with multiple conversational turns: ```json [ { "role": "user", "content": "Hello there." }, { "role": "assistant", "content": "Hi, I'm Claude. How can I help you?" }, { "role": "user", "content": "Can you explain LLMs in plain English?" } ] ``` Example with a partially-filled response from Claude: ```json [ { "role": "user", "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun" }, { "role": "assistant", "content": "The best answer is (" } ] ``` Each input message `content` may be either a single `string` or an array of content blocks, where each block has a specific `type`. Using a `string` for `content` is shorthand for an array of one content block of type `"text"`. The following input messages are equivalent: ```json { "role": "user", "content": "Hello, Claude" } ``` ```json { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } ``` See [input examples](https://docs.anthropic.com/en/api/messages-examples). Note that if you want to include a [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use the top-level `system` parameter — there is no `"system"` role for input messages in the Messages API. There is a limit of 100,000 messages in a single request. model: The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. system: System prompt. A system prompt is a way of providing context and instructions to Claude, such as specifying a particular goal or role. See our [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts). thinking: Configuration for enabling Claude's extended thinking. When enabled, responses include `thinking` content blocks showing Claude's thinking process before the final answer. Requires a minimum budget of 1,024 tokens and counts towards your `max_tokens` limit. See [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) for details. tool_choice: How the model should use the provided tools. The model can use a specific tool, any available tool, decide by itself, or not use tools at all. tools: Definitions of tools that the model may use. If you include `tools` in your API request, the model may return `tool_use` content blocks that represent the model's use of those tools. You can then run those tools using the tool input generated by the model and then optionally return results back to the model using `tool_result` content blocks. There are two types of tools: **client tools** and **server tools**. The behavior described below applies to client tools. For [server tools](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#server-tools), see their individual documentation as each has its own behavior (e.g., the [web search tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool)). Each tool definition includes: - `name`: Name of the tool. - `description`: Optional, but strongly-recommended description of the tool. - `input_schema`: [JSON schema](https://json-schema.org/draft/2020-12) for the tool `input` shape that the model will produce in `tool_use` output content blocks. For example, if you defined `tools` as: ```json [ { "name": "get_stock_price", "description": "Get the current stock price for a given ticker symbol.", "input_schema": { "type": "object", "properties": { "ticker": { "type": "string", "description": "The stock ticker symbol, e.g. AAPL for Apple Inc." } }, "required": ["ticker"] } } ] ``` And then asked the model "What's the S&P 500 at today?", the model might produce `tool_use` content blocks in the response like this: ```json [ { "type": "tool_use", "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "name": "get_stock_price", "input": { "ticker": "^GSPC" } } ] ``` You might then run your `get_stock_price` tool with `{"ticker": "^GSPC"}` as an input, and return the following back to the model in a subsequent `user` message: ```json [ { "type": "tool_result", "tool_use_id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "content": "259.75 USD" } ] ``` Tools can be used for workflows that include running client-side tools and functions, or more generally whenever you want the model to produce a particular JSON structure of output. See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ return await self._post( "/v1/messages/count_tokens", body=await async_maybe_transform( { "messages": messages, "model": model, "system": system, "thinking": thinking, "tool_choice": tool_choice, "tools": tools, }, message_count_tokens_params.MessageCountTokensParams, ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=MessageTokensCount, ) class MessagesWithRawResponse: def __init__(self, messages: Messages) -> None: self._messages = messages self.create = _legacy_response.to_raw_response_wrapper( messages.create, ) self.count_tokens = _legacy_response.to_raw_response_wrapper( messages.count_tokens, ) @cached_property def batches(self) -> BatchesWithRawResponse: return BatchesWithRawResponse(self._messages.batches) class AsyncMessagesWithRawResponse: def __init__(self, messages: AsyncMessages) -> None: self._messages = messages self.create = _legacy_response.async_to_raw_response_wrapper( messages.create, ) self.count_tokens = _legacy_response.async_to_raw_response_wrapper( messages.count_tokens, ) @cached_property def batches(self) -> AsyncBatchesWithRawResponse: return AsyncBatchesWithRawResponse(self._messages.batches) class MessagesWithStreamingResponse: def __init__(self, messages: Messages) -> None: self._messages = messages self.create = to_streamed_response_wrapper( messages.create, ) self.count_tokens = to_streamed_response_wrapper( messages.count_tokens, ) @cached_property def batches(self) -> BatchesWithStreamingResponse: return BatchesWithStreamingResponse(self._messages.batches) class AsyncMessagesWithStreamingResponse: def __init__(self, messages: AsyncMessages) -> None: self._messages = messages self.create = async_to_streamed_response_wrapper( messages.create, ) self.count_tokens = async_to_streamed_response_wrapper( messages.count_tokens, ) @cached_property def batches(self) -> AsyncBatchesWithStreamingResponse: return AsyncBatchesWithStreamingResponse(self._messages.batches) anthropic-sdk-python-0.69.0/src/anthropic/resources/models.py000066400000000000000000000301621506653454500243370ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import List import httpx from .. import _legacy_response from ..types import model_list_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given from .._utils import is_given, maybe_transform, strip_not_given from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper from ..pagination import SyncPage, AsyncPage from .._base_client import AsyncPaginator, make_request_options from ..types.model_info import ModelInfo from ..types.anthropic_beta_param import AnthropicBetaParam __all__ = ["Models", "AsyncModels"] class Models(SyncAPIResource): @cached_property def with_raw_response(self) -> ModelsWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the raw response object instead of the parsed content. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers """ return ModelsWithRawResponse(self) @cached_property def with_streaming_response(self) -> ModelsWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response """ return ModelsWithStreamingResponse(self) def retrieve( self, model_id: str, *, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ModelInfo: """ Get a specific model. The Models API response can be used to determine information about a specific model or resolve a model alias to a model ID. Args: model_id: Model identifier or alias. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ if not model_id: raise ValueError(f"Expected a non-empty value for `model_id` but received {model_id!r}") extra_headers = { **strip_not_given({"anthropic-beta": ",".join(str(e) for e in betas) if is_given(betas) else not_given}), **(extra_headers or {}), } return self._get( f"/v1/models/{model_id}", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=ModelInfo, ) def list( self, *, after_id: str | Omit = omit, before_id: str | Omit = omit, limit: int | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncPage[ModelInfo]: """ List available models. The Models API response can be used to determine which models are available for use in the API. More recently released models are listed first. Args: after_id: ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately after this object. before_id: ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately before this object. limit: Number of items to return per page. Defaults to `20`. Ranges from `1` to `1000`. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ extra_headers = { **strip_not_given({"anthropic-beta": ",".join(str(e) for e in betas) if is_given(betas) else not_given}), **(extra_headers or {}), } return self._get_api_list( "/v1/models", page=SyncPage[ModelInfo], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, query=maybe_transform( { "after_id": after_id, "before_id": before_id, "limit": limit, }, model_list_params.ModelListParams, ), ), model=ModelInfo, ) class AsyncModels(AsyncAPIResource): @cached_property def with_raw_response(self) -> AsyncModelsWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the raw response object instead of the parsed content. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers """ return AsyncModelsWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncModelsWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response """ return AsyncModelsWithStreamingResponse(self) async def retrieve( self, model_id: str, *, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ModelInfo: """ Get a specific model. The Models API response can be used to determine information about a specific model or resolve a model alias to a model ID. Args: model_id: Model identifier or alias. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ if not model_id: raise ValueError(f"Expected a non-empty value for `model_id` but received {model_id!r}") extra_headers = { **strip_not_given({"anthropic-beta": ",".join(str(e) for e in betas) if is_given(betas) else not_given}), **(extra_headers or {}), } return await self._get( f"/v1/models/{model_id}", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), cast_to=ModelInfo, ) def list( self, *, after_id: str | Omit = omit, before_id: str | Omit = omit, limit: int | Omit = omit, betas: List[AnthropicBetaParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[ModelInfo, AsyncPage[ModelInfo]]: """ List available models. The Models API response can be used to determine which models are available for use in the API. More recently released models are listed first. Args: after_id: ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately after this object. before_id: ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately before this object. limit: Number of items to return per page. Defaults to `20`. Ranges from `1` to `1000`. betas: Optional header to specify the beta version(s) you want to use. extra_headers: Send extra headers extra_query: Add additional query parameters to the request extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds """ extra_headers = { **strip_not_given({"anthropic-beta": ",".join(str(e) for e in betas) if is_given(betas) else not_given}), **(extra_headers or {}), } return self._get_api_list( "/v1/models", page=AsyncPage[ModelInfo], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, query=maybe_transform( { "after_id": after_id, "before_id": before_id, "limit": limit, }, model_list_params.ModelListParams, ), ), model=ModelInfo, ) class ModelsWithRawResponse: def __init__(self, models: Models) -> None: self._models = models self.retrieve = _legacy_response.to_raw_response_wrapper( models.retrieve, ) self.list = _legacy_response.to_raw_response_wrapper( models.list, ) class AsyncModelsWithRawResponse: def __init__(self, models: AsyncModels) -> None: self._models = models self.retrieve = _legacy_response.async_to_raw_response_wrapper( models.retrieve, ) self.list = _legacy_response.async_to_raw_response_wrapper( models.list, ) class ModelsWithStreamingResponse: def __init__(self, models: Models) -> None: self._models = models self.retrieve = to_streamed_response_wrapper( models.retrieve, ) self.list = to_streamed_response_wrapper( models.list, ) class AsyncModelsWithStreamingResponse: def __init__(self, models: AsyncModels) -> None: self._models = models self.retrieve = async_to_streamed_response_wrapper( models.retrieve, ) self.list = async_to_streamed_response_wrapper( models.list, ) anthropic-sdk-python-0.69.0/src/anthropic/types/000077500000000000000000000000001506653454500216325ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/types/__init__.py000066400000000000000000000223621506653454500237500ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from .model import Model as Model from .usage import Usage as Usage from .shared import ( ErrorObject as ErrorObject, BillingError as BillingError, ErrorResponse as ErrorResponse, NotFoundError as NotFoundError, APIErrorObject as APIErrorObject, RateLimitError as RateLimitError, OverloadedError as OverloadedError, PermissionError as PermissionError, AuthenticationError as AuthenticationError, GatewayTimeoutError as GatewayTimeoutError, InvalidRequestError as InvalidRequestError, ) from .message import Message as Message from .beta_error import BetaError as BetaError from .completion import Completion as Completion from .model_info import ModelInfo as ModelInfo from .text_block import TextBlock as TextBlock from .text_delta import TextDelta as TextDelta from .tool_param import ToolParam as ToolParam from .model_param import ModelParam as ModelParam from .stop_reason import StopReason as StopReason from .content_block import ContentBlock as ContentBlock from .message_param import MessageParam as MessageParam from .text_citation import TextCitation as TextCitation from .beta_api_error import BetaAPIError as BetaAPIError from .cache_creation import CacheCreation as CacheCreation from .metadata_param import MetadataParam as MetadataParam from .thinking_block import ThinkingBlock as ThinkingBlock from .thinking_delta import ThinkingDelta as ThinkingDelta from .tool_use_block import ToolUseBlock as ToolUseBlock from .citations_delta import CitationsDelta as CitationsDelta from .signature_delta import SignatureDelta as SignatureDelta from .input_json_delta import InputJSONDelta as InputJSONDelta from .text_block_param import TextBlockParam as TextBlockParam from .tool_union_param import ToolUnionParam as ToolUnionParam from .image_block_param import ImageBlockParam as ImageBlockParam from .model_list_params import ModelListParams as ModelListParams from .server_tool_usage import ServerToolUsage as ServerToolUsage from .tool_choice_param import ToolChoiceParam as ToolChoiceParam from .beta_billing_error import BetaBillingError as BetaBillingError from .message_stop_event import MessageStopEvent as MessageStopEvent from .beta_error_response import BetaErrorResponse as BetaErrorResponse from .content_block_param import ContentBlockParam as ContentBlockParam from .message_delta_event import MessageDeltaEvent as MessageDeltaEvent from .message_delta_usage import MessageDeltaUsage as MessageDeltaUsage from .message_start_event import MessageStartEvent as MessageStartEvent from .text_citation_param import TextCitationParam as TextCitationParam from .anthropic_beta_param import AnthropicBetaParam as AnthropicBetaParam from .beta_not_found_error import BetaNotFoundError as BetaNotFoundError from .document_block_param import DocumentBlockParam as DocumentBlockParam from .message_stream_event import MessageStreamEvent as MessageStreamEvent from .message_tokens_count import MessageTokensCount as MessageTokensCount from .thinking_block_param import ThinkingBlockParam as ThinkingBlockParam from .tool_use_block_param import ToolUseBlockParam as ToolUseBlockParam from .url_pdf_source_param import URLPDFSourceParam as URLPDFSourceParam from .beta_overloaded_error import BetaOverloadedError as BetaOverloadedError from .beta_permission_error import BetaPermissionError as BetaPermissionError from .beta_rate_limit_error import BetaRateLimitError as BetaRateLimitError from .message_create_params import MessageCreateParams as MessageCreateParams from .server_tool_use_block import ServerToolUseBlock as ServerToolUseBlock from .thinking_config_param import ThinkingConfigParam as ThinkingConfigParam from .tool_choice_any_param import ToolChoiceAnyParam as ToolChoiceAnyParam from .citation_char_location import CitationCharLocation as CitationCharLocation from .citation_page_location import CitationPageLocation as CitationPageLocation from .citations_config_param import CitationsConfigParam as CitationsConfigParam from .raw_message_stop_event import RawMessageStopEvent as RawMessageStopEvent from .tool_choice_auto_param import ToolChoiceAutoParam as ToolChoiceAutoParam from .tool_choice_none_param import ToolChoiceNoneParam as ToolChoiceNoneParam from .tool_choice_tool_param import ToolChoiceToolParam as ToolChoiceToolParam from .url_image_source_param import URLImageSourceParam as URLImageSourceParam from .base64_pdf_source_param import Base64PDFSourceParam as Base64PDFSourceParam from .plain_text_source_param import PlainTextSourceParam as PlainTextSourceParam from .raw_content_block_delta import RawContentBlockDelta as RawContentBlockDelta from .raw_message_delta_event import RawMessageDeltaEvent as RawMessageDeltaEvent from .raw_message_start_event import RawMessageStartEvent as RawMessageStartEvent from .redacted_thinking_block import RedactedThinkingBlock as RedactedThinkingBlock from .tool_result_block_param import ToolResultBlockParam as ToolResultBlockParam from .web_search_result_block import WebSearchResultBlock as WebSearchResultBlock from .completion_create_params import CompletionCreateParams as CompletionCreateParams from .content_block_stop_event import ContentBlockStopEvent as ContentBlockStopEvent from .raw_message_stream_event import RawMessageStreamEvent as RawMessageStreamEvent from .tool_bash_20250124_param import ToolBash20250124Param as ToolBash20250124Param from .base64_image_source_param import Base64ImageSourceParam as Base64ImageSourceParam from .beta_authentication_error import BetaAuthenticationError as BetaAuthenticationError from .content_block_delta_event import ContentBlockDeltaEvent as ContentBlockDeltaEvent from .content_block_start_event import ContentBlockStartEvent as ContentBlockStartEvent from .search_result_block_param import SearchResultBlockParam as SearchResultBlockParam from .beta_gateway_timeout_error import BetaGatewayTimeoutError as BetaGatewayTimeoutError from .beta_invalid_request_error import BetaInvalidRequestError as BetaInvalidRequestError from .content_block_source_param import ContentBlockSourceParam as ContentBlockSourceParam from .message_count_tokens_params import MessageCountTokensParams as MessageCountTokensParams from .server_tool_use_block_param import ServerToolUseBlockParam as ServerToolUseBlockParam from .citation_char_location_param import CitationCharLocationParam as CitationCharLocationParam from .citation_page_location_param import CitationPageLocationParam as CitationPageLocationParam from .raw_content_block_stop_event import RawContentBlockStopEvent as RawContentBlockStopEvent from .web_search_tool_result_block import WebSearchToolResultBlock as WebSearchToolResultBlock from .web_search_tool_result_error import WebSearchToolResultError as WebSearchToolResultError from .cache_control_ephemeral_param import CacheControlEphemeralParam as CacheControlEphemeralParam from .raw_content_block_delta_event import RawContentBlockDeltaEvent as RawContentBlockDeltaEvent from .raw_content_block_start_event import RawContentBlockStartEvent as RawContentBlockStartEvent from .redacted_thinking_block_param import RedactedThinkingBlockParam as RedactedThinkingBlockParam from .thinking_config_enabled_param import ThinkingConfigEnabledParam as ThinkingConfigEnabledParam from .web_search_result_block_param import WebSearchResultBlockParam as WebSearchResultBlockParam from .thinking_config_disabled_param import ThinkingConfigDisabledParam as ThinkingConfigDisabledParam from .web_search_tool_20250305_param import WebSearchTool20250305Param as WebSearchTool20250305Param from .citation_content_block_location import CitationContentBlockLocation as CitationContentBlockLocation from .message_count_tokens_tool_param import MessageCountTokensToolParam as MessageCountTokensToolParam from .tool_text_editor_20250124_param import ToolTextEditor20250124Param as ToolTextEditor20250124Param from .tool_text_editor_20250429_param import ToolTextEditor20250429Param as ToolTextEditor20250429Param from .tool_text_editor_20250728_param import ToolTextEditor20250728Param as ToolTextEditor20250728Param from .citations_search_result_location import CitationsSearchResultLocation as CitationsSearchResultLocation from .content_block_source_content_param import ContentBlockSourceContentParam as ContentBlockSourceContentParam from .web_search_tool_result_block_param import WebSearchToolResultBlockParam as WebSearchToolResultBlockParam from .web_search_tool_request_error_param import WebSearchToolRequestErrorParam as WebSearchToolRequestErrorParam from .citations_web_search_result_location import CitationsWebSearchResultLocation as CitationsWebSearchResultLocation from .web_search_tool_result_block_content import WebSearchToolResultBlockContent as WebSearchToolResultBlockContent from .citation_content_block_location_param import ( CitationContentBlockLocationParam as CitationContentBlockLocationParam, ) from .citation_search_result_location_param import ( CitationSearchResultLocationParam as CitationSearchResultLocationParam, ) from .citation_web_search_result_location_param import ( CitationWebSearchResultLocationParam as CitationWebSearchResultLocationParam, ) from .web_search_tool_result_block_param_content_param import ( WebSearchToolResultBlockParamContentParam as WebSearchToolResultBlockParamContentParam, ) anthropic-sdk-python-0.69.0/src/anthropic/types/anthropic_beta_param.py000066400000000000000000000015201506653454500263440ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union from typing_extensions import Literal, TypeAlias __all__ = ["AnthropicBetaParam"] AnthropicBetaParam: TypeAlias = Union[ str, Literal[ "message-batches-2024-09-24", "prompt-caching-2024-07-31", "computer-use-2024-10-22", "computer-use-2025-01-24", "pdfs-2024-09-25", "token-counting-2024-11-01", "token-efficient-tools-2025-02-19", "output-128k-2025-02-19", "files-api-2025-04-14", "mcp-client-2025-04-04", "dev-full-thinking-2025-05-14", "interleaved-thinking-2025-05-14", "code-execution-2025-05-22", "extended-cache-ttl-2025-04-11", "context-1m-2025-08-07", ], ] anthropic-sdk-python-0.69.0/src/anthropic/types/base64_image_source_param.py000066400000000000000000000013251506653454500271730ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union from typing_extensions import Literal, Required, Annotated, TypedDict from .._types import Base64FileInput from .._utils import PropertyInfo from .._models import set_pydantic_config __all__ = ["Base64ImageSourceParam"] class Base64ImageSourceParam(TypedDict, total=False): data: Required[Annotated[Union[str, Base64FileInput], PropertyInfo(format="base64")]] media_type: Required[Literal["image/jpeg", "image/png", "image/gif", "image/webp"]] type: Required[Literal["base64"]] set_pydantic_config(Base64ImageSourceParam, {"arbitrary_types_allowed": True}) anthropic-sdk-python-0.69.0/src/anthropic/types/base64_pdf_source_param.py000066400000000000000000000012541506653454500266630ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union from typing_extensions import Literal, Required, Annotated, TypedDict from .._types import Base64FileInput from .._utils import PropertyInfo from .._models import set_pydantic_config __all__ = ["Base64PDFSourceParam"] class Base64PDFSourceParam(TypedDict, total=False): data: Required[Annotated[Union[str, Base64FileInput], PropertyInfo(format="base64")]] media_type: Required[Literal["application/pdf"]] type: Required[Literal["base64"]] set_pydantic_config(Base64PDFSourceParam, {"arbitrary_types_allowed": True}) anthropic-sdk-python-0.69.0/src/anthropic/types/beta/000077500000000000000000000000001506653454500225455ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/types/beta/__init__.py000066400000000000000000000437131506653454500246660ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from .beta_usage import BetaUsage as BetaUsage from .beta_message import BetaMessage as BetaMessage from .deleted_file import DeletedFile as DeletedFile from .file_metadata import FileMetadata as FileMetadata from .beta_container import BetaContainer as BetaContainer from .beta_model_info import BetaModelInfo as BetaModelInfo from .beta_text_block import BetaTextBlock as BetaTextBlock from .beta_text_delta import BetaTextDelta as BetaTextDelta from .beta_tool_param import BetaToolParam as BetaToolParam from .beta_stop_reason import BetaStopReason as BetaStopReason from .file_list_params import FileListParams as FileListParams from .model_list_params import ModelListParams as ModelListParams from .beta_content_block import BetaContentBlock as BetaContentBlock from .beta_message_param import BetaMessageParam as BetaMessageParam from .beta_text_citation import BetaTextCitation as BetaTextCitation from .file_upload_params import FileUploadParams as FileUploadParams from .beta_cache_creation import BetaCacheCreation as BetaCacheCreation from .beta_document_block import BetaDocumentBlock as BetaDocumentBlock from .beta_metadata_param import BetaMetadataParam as BetaMetadataParam from .beta_thinking_block import BetaThinkingBlock as BetaThinkingBlock from .beta_thinking_delta import BetaThinkingDelta as BetaThinkingDelta from .beta_tool_use_block import BetaToolUseBlock as BetaToolUseBlock from .beta_citation_config import BetaCitationConfig as BetaCitationConfig from .beta_citations_delta import BetaCitationsDelta as BetaCitationsDelta from .beta_signature_delta import BetaSignatureDelta as BetaSignatureDelta from .beta_web_fetch_block import BetaWebFetchBlock as BetaWebFetchBlock from .beta_input_json_delta import BetaInputJSONDelta as BetaInputJSONDelta from .beta_text_block_param import BetaTextBlockParam as BetaTextBlockParam from .beta_tool_union_param import BetaToolUnionParam as BetaToolUnionParam from .message_create_params import MessageCreateParams as MessageCreateParams from .beta_base64_pdf_source import BetaBase64PDFSource as BetaBase64PDFSource from .beta_image_block_param import BetaImageBlockParam as BetaImageBlockParam from .beta_plain_text_source import BetaPlainTextSource as BetaPlainTextSource from .beta_server_tool_usage import BetaServerToolUsage as BetaServerToolUsage from .beta_tool_choice_param import BetaToolChoiceParam as BetaToolChoiceParam from .beta_mcp_tool_use_block import BetaMCPToolUseBlock as BetaMCPToolUseBlock from .beta_content_block_param import BetaContentBlockParam as BetaContentBlockParam from .beta_message_delta_usage import BetaMessageDeltaUsage as BetaMessageDeltaUsage from .beta_text_citation_param import BetaTextCitationParam as BetaTextCitationParam from .beta_message_tokens_count import BetaMessageTokensCount as BetaMessageTokensCount from .beta_thinking_block_param import BetaThinkingBlockParam as BetaThinkingBlockParam from .beta_tool_use_block_param import BetaToolUseBlockParam as BetaToolUseBlockParam from .beta_tool_uses_keep_param import BetaToolUsesKeepParam as BetaToolUsesKeepParam from .beta_url_pdf_source_param import BetaURLPDFSourceParam as BetaURLPDFSourceParam from .beta_mcp_tool_result_block import BetaMCPToolResultBlock as BetaMCPToolResultBlock from .beta_server_tool_use_block import BetaServerToolUseBlock as BetaServerToolUseBlock from .beta_thinking_config_param import BetaThinkingConfigParam as BetaThinkingConfigParam from .beta_tool_choice_any_param import BetaToolChoiceAnyParam as BetaToolChoiceAnyParam from .beta_web_fetch_block_param import BetaWebFetchBlockParam as BetaWebFetchBlockParam from .beta_base64_pdf_block_param import BetaBase64PDFBlockParam as BetaBase64PDFBlockParam from .beta_citation_char_location import BetaCitationCharLocation as BetaCitationCharLocation from .beta_citation_page_location import BetaCitationPageLocation as BetaCitationPageLocation from .beta_citations_config_param import BetaCitationsConfigParam as BetaCitationsConfigParam from .beta_container_upload_block import BetaContainerUploadBlock as BetaContainerUploadBlock from .beta_raw_message_stop_event import BetaRawMessageStopEvent as BetaRawMessageStopEvent from .beta_tool_choice_auto_param import BetaToolChoiceAutoParam as BetaToolChoiceAutoParam from .beta_tool_choice_none_param import BetaToolChoiceNoneParam as BetaToolChoiceNoneParam from .beta_tool_choice_tool_param import BetaToolChoiceToolParam as BetaToolChoiceToolParam from .beta_url_image_source_param import BetaURLImageSourceParam as BetaURLImageSourceParam from .message_count_tokens_params import MessageCountTokensParams as MessageCountTokensParams from .beta_base64_pdf_source_param import BetaBase64PDFSourceParam as BetaBase64PDFSourceParam from .beta_file_image_source_param import BetaFileImageSourceParam as BetaFileImageSourceParam from .beta_plain_text_source_param import BetaPlainTextSourceParam as BetaPlainTextSourceParam from .beta_raw_content_block_delta import BetaRawContentBlockDelta as BetaRawContentBlockDelta from .beta_raw_message_delta_event import BetaRawMessageDeltaEvent as BetaRawMessageDeltaEvent from .beta_raw_message_start_event import BetaRawMessageStartEvent as BetaRawMessageStartEvent from .beta_redacted_thinking_block import BetaRedactedThinkingBlock as BetaRedactedThinkingBlock from .beta_tool_result_block_param import BetaToolResultBlockParam as BetaToolResultBlockParam from .beta_tool_uses_trigger_param import BetaToolUsesTriggerParam as BetaToolUsesTriggerParam from .beta_web_search_result_block import BetaWebSearchResultBlock as BetaWebSearchResultBlock from .beta_mcp_tool_use_block_param import BetaMCPToolUseBlockParam as BetaMCPToolUseBlockParam from .beta_raw_message_stream_event import BetaRawMessageStreamEvent as BetaRawMessageStreamEvent from .beta_tool_bash_20241022_param import BetaToolBash20241022Param as BetaToolBash20241022Param from .beta_tool_bash_20250124_param import BetaToolBash20250124Param as BetaToolBash20250124Param from .beta_base64_image_source_param import BetaBase64ImageSourceParam as BetaBase64ImageSourceParam from .beta_search_result_block_param import BetaSearchResultBlockParam as BetaSearchResultBlockParam from .beta_content_block_source_param import BetaContentBlockSourceParam as BetaContentBlockSourceParam from .beta_file_document_source_param import BetaFileDocumentSourceParam as BetaFileDocumentSourceParam from .beta_input_tokens_trigger_param import BetaInputTokensTriggerParam as BetaInputTokensTriggerParam from .beta_memory_tool_20250818_param import BetaMemoryTool20250818Param as BetaMemoryTool20250818Param from .beta_code_execution_output_block import BetaCodeExecutionOutputBlock as BetaCodeExecutionOutputBlock from .beta_code_execution_result_block import BetaCodeExecutionResultBlock as BetaCodeExecutionResultBlock from .beta_context_management_response import BetaContextManagementResponse as BetaContextManagementResponse from .beta_server_tool_use_block_param import BetaServerToolUseBlockParam as BetaServerToolUseBlockParam from .beta_web_fetch_tool_result_block import BetaWebFetchToolResultBlock as BetaWebFetchToolResultBlock from .beta_citation_char_location_param import BetaCitationCharLocationParam as BetaCitationCharLocationParam from .beta_citation_page_location_param import BetaCitationPageLocationParam as BetaCitationPageLocationParam from .beta_container_upload_block_param import BetaContainerUploadBlockParam as BetaContainerUploadBlockParam from .beta_memory_tool_20250818_command import BetaMemoryTool20250818Command as BetaMemoryTool20250818Command from .beta_raw_content_block_stop_event import BetaRawContentBlockStopEvent as BetaRawContentBlockStopEvent from .beta_request_document_block_param import BetaRequestDocumentBlockParam as BetaRequestDocumentBlockParam from .beta_web_search_tool_result_block import BetaWebSearchToolResultBlock as BetaWebSearchToolResultBlock from .beta_web_search_tool_result_error import BetaWebSearchToolResultError as BetaWebSearchToolResultError from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam as BetaCacheControlEphemeralParam from .beta_raw_content_block_delta_event import BetaRawContentBlockDeltaEvent as BetaRawContentBlockDeltaEvent from .beta_raw_content_block_start_event import BetaRawContentBlockStartEvent as BetaRawContentBlockStartEvent from .beta_redacted_thinking_block_param import BetaRedactedThinkingBlockParam as BetaRedactedThinkingBlockParam from .beta_thinking_config_enabled_param import BetaThinkingConfigEnabledParam as BetaThinkingConfigEnabledParam from .beta_web_fetch_tool_20250910_param import BetaWebFetchTool20250910Param as BetaWebFetchTool20250910Param from .beta_web_search_result_block_param import BetaWebSearchResultBlockParam as BetaWebSearchResultBlockParam from .beta_thinking_config_disabled_param import BetaThinkingConfigDisabledParam as BetaThinkingConfigDisabledParam from .beta_web_search_tool_20250305_param import BetaWebSearchTool20250305Param as BetaWebSearchTool20250305Param from .beta_citation_content_block_location import BetaCitationContentBlockLocation as BetaCitationContentBlockLocation from .beta_citation_search_result_location import BetaCitationSearchResultLocation as BetaCitationSearchResultLocation from .beta_context_management_config_param import BetaContextManagementConfigParam as BetaContextManagementConfigParam from .beta_tool_text_editor_20241022_param import BetaToolTextEditor20241022Param as BetaToolTextEditor20241022Param from .beta_tool_text_editor_20250124_param import BetaToolTextEditor20250124Param as BetaToolTextEditor20250124Param from .beta_tool_text_editor_20250429_param import BetaToolTextEditor20250429Param as BetaToolTextEditor20250429Param from .beta_tool_text_editor_20250728_param import BetaToolTextEditor20250728Param as BetaToolTextEditor20250728Param from .beta_bash_code_execution_output_block import BetaBashCodeExecutionOutputBlock as BetaBashCodeExecutionOutputBlock from .beta_bash_code_execution_result_block import BetaBashCodeExecutionResultBlock as BetaBashCodeExecutionResultBlock from .beta_code_execution_tool_result_block import BetaCodeExecutionToolResultBlock as BetaCodeExecutionToolResultBlock from .beta_code_execution_tool_result_error import BetaCodeExecutionToolResultError as BetaCodeExecutionToolResultError from .beta_tool_computer_use_20241022_param import BetaToolComputerUse20241022Param as BetaToolComputerUse20241022Param from .beta_tool_computer_use_20250124_param import BetaToolComputerUse20250124Param as BetaToolComputerUse20250124Param from .beta_web_fetch_tool_result_error_code import BetaWebFetchToolResultErrorCode as BetaWebFetchToolResultErrorCode from .beta_code_execution_output_block_param import ( BetaCodeExecutionOutputBlockParam as BetaCodeExecutionOutputBlockParam, ) from .beta_code_execution_result_block_param import ( BetaCodeExecutionResultBlockParam as BetaCodeExecutionResultBlockParam, ) from .beta_input_tokens_clear_at_least_param import BetaInputTokensClearAtLeastParam as BetaInputTokensClearAtLeastParam from .beta_memory_tool_20250818_view_command import ( BetaMemoryTool20250818ViewCommand as BetaMemoryTool20250818ViewCommand, ) from .beta_web_fetch_tool_result_block_param import BetaWebFetchToolResultBlockParam as BetaWebFetchToolResultBlockParam from .beta_web_fetch_tool_result_error_block import BetaWebFetchToolResultErrorBlock as BetaWebFetchToolResultErrorBlock from .beta_web_search_tool_result_error_code import BetaWebSearchToolResultErrorCode as BetaWebSearchToolResultErrorCode from .beta_code_execution_tool_20250522_param import ( BetaCodeExecutionTool20250522Param as BetaCodeExecutionTool20250522Param, ) from .beta_code_execution_tool_20250825_param import ( BetaCodeExecutionTool20250825Param as BetaCodeExecutionTool20250825Param, ) from .beta_content_block_source_content_param import ( BetaContentBlockSourceContentParam as BetaContentBlockSourceContentParam, ) from .beta_web_search_tool_result_block_param import ( BetaWebSearchToolResultBlockParam as BetaWebSearchToolResultBlockParam, ) from .beta_clear_tool_uses_20250919_edit_param import ( BetaClearToolUses20250919EditParam as BetaClearToolUses20250919EditParam, ) from .beta_memory_tool_20250818_create_command import ( BetaMemoryTool20250818CreateCommand as BetaMemoryTool20250818CreateCommand, ) from .beta_memory_tool_20250818_delete_command import ( BetaMemoryTool20250818DeleteCommand as BetaMemoryTool20250818DeleteCommand, ) from .beta_memory_tool_20250818_insert_command import ( BetaMemoryTool20250818InsertCommand as BetaMemoryTool20250818InsertCommand, ) from .beta_memory_tool_20250818_rename_command import ( BetaMemoryTool20250818RenameCommand as BetaMemoryTool20250818RenameCommand, ) from .beta_request_mcp_tool_result_block_param import ( BetaRequestMCPToolResultBlockParam as BetaRequestMCPToolResultBlockParam, ) from .beta_web_search_tool_request_error_param import ( BetaWebSearchToolRequestErrorParam as BetaWebSearchToolRequestErrorParam, ) from .beta_citations_web_search_result_location import ( BetaCitationsWebSearchResultLocation as BetaCitationsWebSearchResultLocation, ) from .beta_web_search_tool_result_block_content import ( BetaWebSearchToolResultBlockContent as BetaWebSearchToolResultBlockContent, ) from .beta_bash_code_execution_tool_result_block import ( BetaBashCodeExecutionToolResultBlock as BetaBashCodeExecutionToolResultBlock, ) from .beta_bash_code_execution_tool_result_error import ( BetaBashCodeExecutionToolResultError as BetaBashCodeExecutionToolResultError, ) from .beta_citation_content_block_location_param import ( BetaCitationContentBlockLocationParam as BetaCitationContentBlockLocationParam, ) from .beta_citation_search_result_location_param import ( BetaCitationSearchResultLocationParam as BetaCitationSearchResultLocationParam, ) from .beta_code_execution_tool_result_error_code import ( BetaCodeExecutionToolResultErrorCode as BetaCodeExecutionToolResultErrorCode, ) from .beta_bash_code_execution_output_block_param import ( BetaBashCodeExecutionOutputBlockParam as BetaBashCodeExecutionOutputBlockParam, ) from .beta_bash_code_execution_result_block_param import ( BetaBashCodeExecutionResultBlockParam as BetaBashCodeExecutionResultBlockParam, ) from .beta_clear_tool_uses_20250919_edit_response import ( BetaClearToolUses20250919EditResponse as BetaClearToolUses20250919EditResponse, ) from .beta_code_execution_tool_result_block_param import ( BetaCodeExecutionToolResultBlockParam as BetaCodeExecutionToolResultBlockParam, ) from .beta_code_execution_tool_result_error_param import ( BetaCodeExecutionToolResultErrorParam as BetaCodeExecutionToolResultErrorParam, ) from .beta_request_mcp_server_url_definition_param import ( BetaRequestMCPServerURLDefinitionParam as BetaRequestMCPServerURLDefinitionParam, ) from .beta_web_fetch_tool_result_error_block_param import ( BetaWebFetchToolResultErrorBlockParam as BetaWebFetchToolResultErrorBlockParam, ) from .beta_code_execution_tool_result_block_content import ( BetaCodeExecutionToolResultBlockContent as BetaCodeExecutionToolResultBlockContent, ) from .beta_count_tokens_context_management_response import ( BetaCountTokensContextManagementResponse as BetaCountTokensContextManagementResponse, ) from .beta_memory_tool_20250818_str_replace_command import ( BetaMemoryTool20250818StrReplaceCommand as BetaMemoryTool20250818StrReplaceCommand, ) from .beta_citation_web_search_result_location_param import ( BetaCitationWebSearchResultLocationParam as BetaCitationWebSearchResultLocationParam, ) from .beta_bash_code_execution_tool_result_block_param import ( BetaBashCodeExecutionToolResultBlockParam as BetaBashCodeExecutionToolResultBlockParam, ) from .beta_bash_code_execution_tool_result_error_param import ( BetaBashCodeExecutionToolResultErrorParam as BetaBashCodeExecutionToolResultErrorParam, ) from .beta_request_mcp_server_tool_configuration_param import ( BetaRequestMCPServerToolConfigurationParam as BetaRequestMCPServerToolConfigurationParam, ) from .beta_text_editor_code_execution_tool_result_block import ( BetaTextEditorCodeExecutionToolResultBlock as BetaTextEditorCodeExecutionToolResultBlock, ) from .beta_text_editor_code_execution_tool_result_error import ( BetaTextEditorCodeExecutionToolResultError as BetaTextEditorCodeExecutionToolResultError, ) from .beta_text_editor_code_execution_view_result_block import ( BetaTextEditorCodeExecutionViewResultBlock as BetaTextEditorCodeExecutionViewResultBlock, ) from .beta_text_editor_code_execution_create_result_block import ( BetaTextEditorCodeExecutionCreateResultBlock as BetaTextEditorCodeExecutionCreateResultBlock, ) from .beta_web_search_tool_result_block_param_content_param import ( BetaWebSearchToolResultBlockParamContentParam as BetaWebSearchToolResultBlockParamContentParam, ) from .beta_text_editor_code_execution_tool_result_block_param import ( BetaTextEditorCodeExecutionToolResultBlockParam as BetaTextEditorCodeExecutionToolResultBlockParam, ) from .beta_text_editor_code_execution_tool_result_error_param import ( BetaTextEditorCodeExecutionToolResultErrorParam as BetaTextEditorCodeExecutionToolResultErrorParam, ) from .beta_text_editor_code_execution_view_result_block_param import ( BetaTextEditorCodeExecutionViewResultBlockParam as BetaTextEditorCodeExecutionViewResultBlockParam, ) from .beta_text_editor_code_execution_str_replace_result_block import ( BetaTextEditorCodeExecutionStrReplaceResultBlock as BetaTextEditorCodeExecutionStrReplaceResultBlock, ) from .beta_code_execution_tool_result_block_param_content_param import ( BetaCodeExecutionToolResultBlockParamContentParam as BetaCodeExecutionToolResultBlockParamContentParam, ) from .beta_text_editor_code_execution_create_result_block_param import ( BetaTextEditorCodeExecutionCreateResultBlockParam as BetaTextEditorCodeExecutionCreateResultBlockParam, ) from .beta_text_editor_code_execution_str_replace_result_block_param import ( BetaTextEditorCodeExecutionStrReplaceResultBlockParam as BetaTextEditorCodeExecutionStrReplaceResultBlockParam, ) anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_base64_image_source_param.py000066400000000000000000000013441506653454500311020ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union from typing_extensions import Literal, Required, Annotated, TypedDict from ..._types import Base64FileInput from ..._utils import PropertyInfo from ..._models import set_pydantic_config __all__ = ["BetaBase64ImageSourceParam"] class BetaBase64ImageSourceParam(TypedDict, total=False): data: Required[Annotated[Union[str, Base64FileInput], PropertyInfo(format="base64")]] media_type: Required[Literal["image/jpeg", "image/png", "image/gif", "image/webp"]] type: Required[Literal["base64"]] set_pydantic_config(BetaBase64ImageSourceParam, {"arbitrary_types_allowed": True}) anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_base64_pdf_block_param.py000066400000000000000000000004011506653454500303540ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from .beta_request_document_block_param import BetaRequestDocumentBlockParam BetaBase64PDFBlockParam = BetaRequestDocumentBlockParam anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_base64_pdf_source.py000066400000000000000000000005011506653454500274030ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaBase64PDFSource"] class BetaBase64PDFSource(BaseModel): data: str media_type: Literal["application/pdf"] type: Literal["base64"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_base64_pdf_source_param.py000066400000000000000000000012731506653454500305720ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union from typing_extensions import Literal, Required, Annotated, TypedDict from ..._types import Base64FileInput from ..._utils import PropertyInfo from ..._models import set_pydantic_config __all__ = ["BetaBase64PDFSourceParam"] class BetaBase64PDFSourceParam(TypedDict, total=False): data: Required[Annotated[Union[str, Base64FileInput], PropertyInfo(format="base64")]] media_type: Required[Literal["application/pdf"]] type: Required[Literal["base64"]] set_pydantic_config(BetaBase64PDFSourceParam, {"arbitrary_types_allowed": True}) anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_bash_code_execution_output_block.py000066400000000000000000000005061506653454500326770ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaBashCodeExecutionOutputBlock"] class BetaBashCodeExecutionOutputBlock(BaseModel): file_id: str type: Literal["bash_code_execution_output"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_bash_code_execution_output_block_param.py000066400000000000000000000006101506653454500340530ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaBashCodeExecutionOutputBlockParam"] class BetaBashCodeExecutionOutputBlockParam(TypedDict, total=False): file_id: Required[str] type: Required[Literal["bash_code_execution_output"]] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_bash_code_execution_result_block.py000066400000000000000000000010151506653454500326510ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import List from typing_extensions import Literal from ..._models import BaseModel from .beta_bash_code_execution_output_block import BetaBashCodeExecutionOutputBlock __all__ = ["BetaBashCodeExecutionResultBlock"] class BetaBashCodeExecutionResultBlock(BaseModel): content: List[BetaBashCodeExecutionOutputBlock] return_code: int stderr: str stdout: str type: Literal["bash_code_execution_result"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_bash_code_execution_result_block_param.py000066400000000000000000000012061506653454500340330ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Iterable from typing_extensions import Literal, Required, TypedDict from .beta_bash_code_execution_output_block_param import BetaBashCodeExecutionOutputBlockParam __all__ = ["BetaBashCodeExecutionResultBlockParam"] class BetaBashCodeExecutionResultBlockParam(TypedDict, total=False): content: Required[Iterable[BetaBashCodeExecutionOutputBlockParam]] return_code: Required[int] stderr: Required[str] stdout: Required[str] type: Required[Literal["bash_code_execution_result"]] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_bash_code_execution_tool_result_block.py000066400000000000000000000012611506653454500337110ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Union from typing_extensions import Literal, TypeAlias from ..._models import BaseModel from .beta_bash_code_execution_result_block import BetaBashCodeExecutionResultBlock from .beta_bash_code_execution_tool_result_error import BetaBashCodeExecutionToolResultError __all__ = ["BetaBashCodeExecutionToolResultBlock", "Content"] Content: TypeAlias = Union[BetaBashCodeExecutionToolResultError, BetaBashCodeExecutionResultBlock] class BetaBashCodeExecutionToolResultBlock(BaseModel): content: Content tool_use_id: str type: Literal["bash_code_execution_tool_result"] beta_bash_code_execution_tool_result_block_param.py000066400000000000000000000017671506653454500350250ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/types/beta# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union, Optional from typing_extensions import Literal, Required, TypeAlias, TypedDict from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam from .beta_bash_code_execution_result_block_param import BetaBashCodeExecutionResultBlockParam from .beta_bash_code_execution_tool_result_error_param import BetaBashCodeExecutionToolResultErrorParam __all__ = ["BetaBashCodeExecutionToolResultBlockParam", "Content"] Content: TypeAlias = Union[BetaBashCodeExecutionToolResultErrorParam, BetaBashCodeExecutionResultBlockParam] class BetaBashCodeExecutionToolResultBlockParam(TypedDict, total=False): content: Required[Content] tool_use_id: Required[str] type: Required[Literal["bash_code_execution_tool_result"]] cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_bash_code_execution_tool_result_error.py000066400000000000000000000007341506653454500337540ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaBashCodeExecutionToolResultError"] class BetaBashCodeExecutionToolResultError(BaseModel): error_code: Literal[ "invalid_tool_input", "unavailable", "too_many_requests", "execution_time_exceeded", "output_file_too_large" ] type: Literal["bash_code_execution_tool_result_error"] beta_bash_code_execution_tool_result_error_param.py000066400000000000000000000010641506653454500350520ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/types/beta# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaBashCodeExecutionToolResultErrorParam"] class BetaBashCodeExecutionToolResultErrorParam(TypedDict, total=False): error_code: Required[ Literal[ "invalid_tool_input", "unavailable", "too_many_requests", "execution_time_exceeded", "output_file_too_large" ] ] type: Required[Literal["bash_code_execution_tool_result_error"]] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_cache_control_ephemeral_param.py000066400000000000000000000010311506653454500321120ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaCacheControlEphemeralParam"] class BetaCacheControlEphemeralParam(TypedDict, total=False): type: Required[Literal["ephemeral"]] ttl: Literal["5m", "1h"] """The time-to-live for the cache control breakpoint. This may be one the following values: - `5m`: 5 minutes - `1h`: 1 hour Defaults to `5m`. """ anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_cache_creation.py000066400000000000000000000006401506653454500270410ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from ..._models import BaseModel __all__ = ["BetaCacheCreation"] class BetaCacheCreation(BaseModel): ephemeral_1h_input_tokens: int """The number of input tokens used to create the 1 hour cache entry.""" ephemeral_5m_input_tokens: int """The number of input tokens used to create the 5 minute cache entry.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_citation_char_location.py000066400000000000000000000007421506653454500306140ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaCitationCharLocation"] class BetaCitationCharLocation(BaseModel): cited_text: str document_index: int document_title: Optional[str] = None end_char_index: int file_id: Optional[str] = None start_char_index: int type: Literal["char_location"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_citation_char_location_param.py000066400000000000000000000010421506653454500317660ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaCitationCharLocationParam"] class BetaCitationCharLocationParam(TypedDict, total=False): cited_text: Required[str] document_index: Required[int] document_title: Required[Optional[str]] end_char_index: Required[int] start_char_index: Required[int] type: Required[Literal["char_location"]] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_citation_config.py000066400000000000000000000003231506653454500272470ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from ..._models import BaseModel __all__ = ["BetaCitationConfig"] class BetaCitationConfig(BaseModel): enabled: bool anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_citation_content_block_location.py000066400000000000000000000007751506653454500325310ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaCitationContentBlockLocation"] class BetaCitationContentBlockLocation(BaseModel): cited_text: str document_index: int document_title: Optional[str] = None end_block_index: int file_id: Optional[str] = None start_block_index: int type: Literal["content_block_location"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_citation_content_block_location_param.py000066400000000000000000000010751506653454500337030ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaCitationContentBlockLocationParam"] class BetaCitationContentBlockLocationParam(TypedDict, total=False): cited_text: Required[str] document_index: Required[int] document_title: Required[Optional[str]] end_block_index: Required[int] start_block_index: Required[int] type: Required[Literal["content_block_location"]] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_citation_page_location.py000066400000000000000000000007441506653454500306150ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaCitationPageLocation"] class BetaCitationPageLocation(BaseModel): cited_text: str document_index: int document_title: Optional[str] = None end_page_number: int file_id: Optional[str] = None start_page_number: int type: Literal["page_location"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_citation_page_location_param.py000066400000000000000000000010441506653454500317670ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaCitationPageLocationParam"] class BetaCitationPageLocationParam(TypedDict, total=False): cited_text: Required[str] document_index: Required[int] document_title: Required[Optional[str]] end_page_number: Required[int] start_page_number: Required[int] type: Required[Literal["page_location"]] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_citation_search_result_location.py000066400000000000000000000007471506653454500325470ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaCitationSearchResultLocation"] class BetaCitationSearchResultLocation(BaseModel): cited_text: str end_block_index: int search_result_index: int source: str start_block_index: int title: Optional[str] = None type: Literal["search_result_location"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_citation_search_result_location_param.py000066400000000000000000000011241506653454500337150ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaCitationSearchResultLocationParam"] class BetaCitationSearchResultLocationParam(TypedDict, total=False): cited_text: Required[str] end_block_index: Required[int] search_result_index: Required[int] source: Required[str] start_block_index: Required[int] title: Required[Optional[str]] type: Required[Literal["search_result_location"]] beta_citation_web_search_result_location_param.py000066400000000000000000000010151506653454500344720ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/types/beta# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaCitationWebSearchResultLocationParam"] class BetaCitationWebSearchResultLocationParam(TypedDict, total=False): cited_text: Required[str] encrypted_index: Required[str] title: Required[Optional[str]] type: Required[Literal["web_search_result_location"]] url: Required[str] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_citations_config_param.py000066400000000000000000000004271506653454500306170ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import TypedDict __all__ = ["BetaCitationsConfigParam"] class BetaCitationsConfigParam(TypedDict, total=False): enabled: bool anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_citations_delta.py000066400000000000000000000020551506653454500272620ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Union from typing_extensions import Literal, Annotated, TypeAlias from ..._utils import PropertyInfo from ..._models import BaseModel from .beta_citation_char_location import BetaCitationCharLocation from .beta_citation_page_location import BetaCitationPageLocation from .beta_citation_content_block_location import BetaCitationContentBlockLocation from .beta_citation_search_result_location import BetaCitationSearchResultLocation from .beta_citations_web_search_result_location import BetaCitationsWebSearchResultLocation __all__ = ["BetaCitationsDelta", "Citation"] Citation: TypeAlias = Annotated[ Union[ BetaCitationCharLocation, BetaCitationPageLocation, BetaCitationContentBlockLocation, BetaCitationsWebSearchResultLocation, BetaCitationSearchResultLocation, ], PropertyInfo(discriminator="type"), ] class BetaCitationsDelta(BaseModel): citation: Citation type: Literal["citations_delta"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_citations_web_search_result_location.py000066400000000000000000000006661506653454500335670ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaCitationsWebSearchResultLocation"] class BetaCitationsWebSearchResultLocation(BaseModel): cited_text: str encrypted_index: str title: Optional[str] = None type: Literal["web_search_result_location"] url: str anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_clear_tool_uses_20250919_edit_param.py000066400000000000000000000027151506653454500324610ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union, Optional from typing_extensions import Literal, Required, TypeAlias, TypedDict from ..._types import SequenceNotStr from .beta_tool_uses_keep_param import BetaToolUsesKeepParam from .beta_tool_uses_trigger_param import BetaToolUsesTriggerParam from .beta_input_tokens_trigger_param import BetaInputTokensTriggerParam from .beta_input_tokens_clear_at_least_param import BetaInputTokensClearAtLeastParam __all__ = ["BetaClearToolUses20250919EditParam", "Trigger"] Trigger: TypeAlias = Union[BetaInputTokensTriggerParam, BetaToolUsesTriggerParam] class BetaClearToolUses20250919EditParam(TypedDict, total=False): type: Required[Literal["clear_tool_uses_20250919"]] clear_at_least: Optional[BetaInputTokensClearAtLeastParam] """Minimum number of tokens that must be cleared when triggered. Context will only be modified if at least this many tokens can be removed. """ clear_tool_inputs: Union[bool, SequenceNotStr[str], None] """Whether to clear all tool inputs (bool) or specific tool inputs to clear (list)""" exclude_tools: Optional[SequenceNotStr[str]] """Tool names whose uses are preserved from clearing""" keep: BetaToolUsesKeepParam """Number of tool uses to retain in the conversation""" trigger: Trigger """Condition that triggers the context management strategy""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_clear_tool_uses_20250919_edit_response.py000066400000000000000000000010261506653454500332110ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaClearToolUses20250919EditResponse"] class BetaClearToolUses20250919EditResponse(BaseModel): cleared_input_tokens: int """Number of input tokens cleared by this edit.""" cleared_tool_uses: int """Number of tool uses that were cleared.""" type: Literal["clear_tool_uses_20250919"] """The type of context management edit applied.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_code_execution_output_block.py000066400000000000000000000004711506653454500317030ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaCodeExecutionOutputBlock"] class BetaCodeExecutionOutputBlock(BaseModel): file_id: str type: Literal["code_execution_output"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_code_execution_output_block_param.py000066400000000000000000000005731506653454500330660ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaCodeExecutionOutputBlockParam"] class BetaCodeExecutionOutputBlockParam(TypedDict, total=False): file_id: Required[str] type: Required[Literal["code_execution_output"]] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_code_execution_result_block.py000066400000000000000000000007631506653454500316650ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import List from typing_extensions import Literal from ..._models import BaseModel from .beta_code_execution_output_block import BetaCodeExecutionOutputBlock __all__ = ["BetaCodeExecutionResultBlock"] class BetaCodeExecutionResultBlock(BaseModel): content: List[BetaCodeExecutionOutputBlock] return_code: int stderr: str stdout: str type: Literal["code_execution_result"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_code_execution_result_block_param.py000066400000000000000000000011541506653454500330400ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Iterable from typing_extensions import Literal, Required, TypedDict from .beta_code_execution_output_block_param import BetaCodeExecutionOutputBlockParam __all__ = ["BetaCodeExecutionResultBlockParam"] class BetaCodeExecutionResultBlockParam(TypedDict, total=False): content: Required[Iterable[BetaCodeExecutionOutputBlockParam]] return_code: Required[int] stderr: Required[str] stdout: Required[str] type: Required[Literal["code_execution_result"]] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_code_execution_tool_20250522_param.py000066400000000000000000000013571506653454500323130ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam __all__ = ["BetaCodeExecutionTool20250522Param"] class BetaCodeExecutionTool20250522Param(TypedDict, total=False): name: Required[Literal["code_execution"]] """Name of the tool. This is how the tool will be called by the model and in `tool_use` blocks. """ type: Required[Literal["code_execution_20250522"]] cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_code_execution_tool_20250825_param.py000066400000000000000000000013571506653454500323210ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam __all__ = ["BetaCodeExecutionTool20250825Param"] class BetaCodeExecutionTool20250825Param(TypedDict, total=False): name: Required[Literal["code_execution"]] """Name of the tool. This is how the tool will be called by the model and in `tool_use` blocks. """ type: Required[Literal["code_execution_20250825"]] cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_code_execution_tool_result_block.py000066400000000000000000000007431506653454500327200ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel from .beta_code_execution_tool_result_block_content import BetaCodeExecutionToolResultBlockContent __all__ = ["BetaCodeExecutionToolResultBlock"] class BetaCodeExecutionToolResultBlock(BaseModel): content: BetaCodeExecutionToolResultBlockContent tool_use_id: str type: Literal["code_execution_tool_result"] beta_code_execution_tool_result_block_content.py000066400000000000000000000007611506653454500343730ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/types/beta# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Union from typing_extensions import TypeAlias from .beta_code_execution_result_block import BetaCodeExecutionResultBlock from .beta_code_execution_tool_result_error import BetaCodeExecutionToolResultError __all__ = ["BetaCodeExecutionToolResultBlockContent"] BetaCodeExecutionToolResultBlockContent: TypeAlias = Union[ BetaCodeExecutionToolResultError, BetaCodeExecutionResultBlock ] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_code_execution_tool_result_block_param.py000066400000000000000000000014731506653454500341010ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam from .beta_code_execution_tool_result_block_param_content_param import BetaCodeExecutionToolResultBlockParamContentParam __all__ = ["BetaCodeExecutionToolResultBlockParam"] class BetaCodeExecutionToolResultBlockParam(TypedDict, total=False): content: Required[BetaCodeExecutionToolResultBlockParamContentParam] tool_use_id: Required[str] type: Required[Literal["code_execution_tool_result"]] cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" beta_code_execution_tool_result_block_param_content_param.py000066400000000000000000000011111506653454500367210ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/types/beta# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union from typing_extensions import TypeAlias from .beta_code_execution_result_block_param import BetaCodeExecutionResultBlockParam from .beta_code_execution_tool_result_error_param import BetaCodeExecutionToolResultErrorParam __all__ = ["BetaCodeExecutionToolResultBlockParamContentParam"] BetaCodeExecutionToolResultBlockParamContentParam: TypeAlias = Union[ BetaCodeExecutionToolResultErrorParam, BetaCodeExecutionResultBlockParam ] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_code_execution_tool_result_error.py000066400000000000000000000007151506653454500327560ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel from .beta_code_execution_tool_result_error_code import BetaCodeExecutionToolResultErrorCode __all__ = ["BetaCodeExecutionToolResultError"] class BetaCodeExecutionToolResultError(BaseModel): error_code: BetaCodeExecutionToolResultErrorCode type: Literal["code_execution_tool_result_error"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_code_execution_tool_result_error_code.py000066400000000000000000000005221506653454500337440ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal, TypeAlias __all__ = ["BetaCodeExecutionToolResultErrorCode"] BetaCodeExecutionToolResultErrorCode: TypeAlias = Literal[ "invalid_tool_input", "unavailable", "too_many_requests", "execution_time_exceeded" ] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_code_execution_tool_result_error_param.py000066400000000000000000000010201506653454500341240ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict from .beta_code_execution_tool_result_error_code import BetaCodeExecutionToolResultErrorCode __all__ = ["BetaCodeExecutionToolResultErrorParam"] class BetaCodeExecutionToolResultErrorParam(TypedDict, total=False): error_code: Required[BetaCodeExecutionToolResultErrorCode] type: Required[Literal["code_execution_tool_result_error"]] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_container.py000066400000000000000000000005571506653454500261030ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from datetime import datetime from ..._models import BaseModel __all__ = ["BetaContainer"] class BetaContainer(BaseModel): id: str """Identifier for the container used in this request""" expires_at: datetime """The time at which the container will expire.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_container_upload_block.py000066400000000000000000000004541506653454500306150ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaContainerUploadBlock"] class BetaContainerUploadBlock(BaseModel): file_id: str type: Literal["container_upload"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_container_upload_block_param.py000066400000000000000000000011321506653454500317670ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam __all__ = ["BetaContainerUploadBlockParam"] class BetaContainerUploadBlockParam(TypedDict, total=False): file_id: Required[str] type: Required[Literal["container_upload"]] cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_content_block.py000066400000000000000000000032201506653454500267330ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Union from typing_extensions import Annotated, TypeAlias from ..._utils import PropertyInfo from .beta_text_block import BetaTextBlock from .beta_thinking_block import BetaThinkingBlock from .beta_tool_use_block import BetaToolUseBlock from .beta_mcp_tool_use_block import BetaMCPToolUseBlock from .beta_mcp_tool_result_block import BetaMCPToolResultBlock from .beta_server_tool_use_block import BetaServerToolUseBlock from .beta_container_upload_block import BetaContainerUploadBlock from .beta_redacted_thinking_block import BetaRedactedThinkingBlock from .beta_web_fetch_tool_result_block import BetaWebFetchToolResultBlock from .beta_web_search_tool_result_block import BetaWebSearchToolResultBlock from .beta_code_execution_tool_result_block import BetaCodeExecutionToolResultBlock from .beta_bash_code_execution_tool_result_block import BetaBashCodeExecutionToolResultBlock from .beta_text_editor_code_execution_tool_result_block import BetaTextEditorCodeExecutionToolResultBlock __all__ = ["BetaContentBlock"] BetaContentBlock: TypeAlias = Annotated[ Union[ BetaTextBlock, BetaThinkingBlock, BetaRedactedThinkingBlock, BetaToolUseBlock, BetaServerToolUseBlock, BetaWebSearchToolResultBlock, BetaWebFetchToolResultBlock, BetaCodeExecutionToolResultBlock, BetaBashCodeExecutionToolResultBlock, BetaTextEditorCodeExecutionToolResultBlock, BetaMCPToolUseBlock, BetaMCPToolResultBlock, BetaContainerUploadBlock, ], PropertyInfo(discriminator="type"), ] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_content_block_param.py000066400000000000000000000043241506653454500301210ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union from typing_extensions import TypeAlias from .beta_content_block import BetaContentBlock from .beta_text_block_param import BetaTextBlockParam from .beta_image_block_param import BetaImageBlockParam from .beta_thinking_block_param import BetaThinkingBlockParam from .beta_tool_use_block_param import BetaToolUseBlockParam from .beta_tool_result_block_param import BetaToolResultBlockParam from .beta_mcp_tool_use_block_param import BetaMCPToolUseBlockParam from .beta_search_result_block_param import BetaSearchResultBlockParam from .beta_server_tool_use_block_param import BetaServerToolUseBlockParam from .beta_container_upload_block_param import BetaContainerUploadBlockParam from .beta_request_document_block_param import BetaRequestDocumentBlockParam from .beta_redacted_thinking_block_param import BetaRedactedThinkingBlockParam from .beta_web_fetch_tool_result_block_param import BetaWebFetchToolResultBlockParam from .beta_web_search_tool_result_block_param import BetaWebSearchToolResultBlockParam from .beta_request_mcp_tool_result_block_param import BetaRequestMCPToolResultBlockParam from .beta_code_execution_tool_result_block_param import BetaCodeExecutionToolResultBlockParam from .beta_bash_code_execution_tool_result_block_param import BetaBashCodeExecutionToolResultBlockParam from .beta_text_editor_code_execution_tool_result_block_param import BetaTextEditorCodeExecutionToolResultBlockParam __all__ = ["BetaContentBlockParam"] BetaContentBlockParam: TypeAlias = Union[ BetaTextBlockParam, BetaImageBlockParam, BetaRequestDocumentBlockParam, BetaSearchResultBlockParam, BetaThinkingBlockParam, BetaRedactedThinkingBlockParam, BetaToolUseBlockParam, BetaToolResultBlockParam, BetaServerToolUseBlockParam, BetaWebSearchToolResultBlockParam, BetaWebFetchToolResultBlockParam, BetaCodeExecutionToolResultBlockParam, BetaBashCodeExecutionToolResultBlockParam, BetaTextEditorCodeExecutionToolResultBlockParam, BetaMCPToolUseBlockParam, BetaRequestMCPToolResultBlockParam, BetaContainerUploadBlockParam, BetaContentBlock, ] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_content_block_source_content_param.py000066400000000000000000000006751506653454500332400ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union from typing_extensions import TypeAlias from .beta_text_block_param import BetaTextBlockParam from .beta_image_block_param import BetaImageBlockParam __all__ = ["BetaContentBlockSourceContentParam"] BetaContentBlockSourceContentParam: TypeAlias = Union[BetaTextBlockParam, BetaImageBlockParam] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_content_block_source_param.py000066400000000000000000000010221506653454500314710ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union, Iterable from typing_extensions import Literal, Required, TypedDict from .beta_content_block_source_content_param import BetaContentBlockSourceContentParam __all__ = ["BetaContentBlockSourceParam"] class BetaContentBlockSourceParam(TypedDict, total=False): content: Required[Union[str, Iterable[BetaContentBlockSourceContentParam]]] type: Required[Literal["content"]] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_context_management_config_param.py000066400000000000000000000007671506653454500325110ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Iterable from typing_extensions import TypedDict from .beta_clear_tool_uses_20250919_edit_param import BetaClearToolUses20250919EditParam __all__ = ["BetaContextManagementConfigParam"] class BetaContextManagementConfigParam(TypedDict, total=False): edits: Iterable[BetaClearToolUses20250919EditParam] """List of context management edits to apply""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_context_management_response.py000066400000000000000000000007141506653454500317120ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import List from ..._models import BaseModel from .beta_clear_tool_uses_20250919_edit_response import BetaClearToolUses20250919EditResponse __all__ = ["BetaContextManagementResponse"] class BetaContextManagementResponse(BaseModel): applied_edits: List[BetaClearToolUses20250919EditResponse] """List of context management edits that were applied.""" beta_count_tokens_context_management_response.py000066400000000000000000000005251506653454500344260ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/types/beta# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from ..._models import BaseModel __all__ = ["BetaCountTokensContextManagementResponse"] class BetaCountTokensContextManagementResponse(BaseModel): original_input_tokens: int """The original token count before context management was applied""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_document_block.py000066400000000000000000000015021506653454500271000ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Union, Optional from typing_extensions import Literal, Annotated, TypeAlias from ..._utils import PropertyInfo from ..._models import BaseModel from .beta_citation_config import BetaCitationConfig from .beta_base64_pdf_source import BetaBase64PDFSource from .beta_plain_text_source import BetaPlainTextSource __all__ = ["BetaDocumentBlock", "Source"] Source: TypeAlias = Annotated[Union[BetaBase64PDFSource, BetaPlainTextSource], PropertyInfo(discriminator="type")] class BetaDocumentBlock(BaseModel): citations: Optional[BetaCitationConfig] = None """Citation configuration for the document""" source: Source title: Optional[str] = None """The title of the document""" type: Literal["document"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_file_document_source_param.py000066400000000000000000000005361506653454500314730ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaFileDocumentSourceParam"] class BetaFileDocumentSourceParam(TypedDict, total=False): file_id: Required[str] type: Required[Literal["file"]] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_file_image_source_param.py000066400000000000000000000005301506653454500307310ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaFileImageSourceParam"] class BetaFileImageSourceParam(TypedDict, total=False): file_id: Required[str] type: Required[Literal["file"]] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_image_block_param.py000066400000000000000000000016161506653454500275320ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union, Optional from typing_extensions import Literal, Required, TypeAlias, TypedDict from .beta_url_image_source_param import BetaURLImageSourceParam from .beta_file_image_source_param import BetaFileImageSourceParam from .beta_base64_image_source_param import BetaBase64ImageSourceParam from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam __all__ = ["BetaImageBlockParam", "Source"] Source: TypeAlias = Union[BetaBase64ImageSourceParam, BetaURLImageSourceParam, BetaFileImageSourceParam] class BetaImageBlockParam(TypedDict, total=False): source: Required[Source] type: Required[Literal["image"]] cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_input_json_delta.py000066400000000000000000000004451506653454500274560ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaInputJSONDelta"] class BetaInputJSONDelta(BaseModel): partial_json: str type: Literal["input_json_delta"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_input_tokens_clear_at_least_param.py000066400000000000000000000005561506653454500330440ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaInputTokensClearAtLeastParam"] class BetaInputTokensClearAtLeastParam(TypedDict, total=False): type: Required[Literal["input_tokens"]] value: Required[int] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_input_tokens_trigger_param.py000066400000000000000000000005441506653454500315420ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaInputTokensTriggerParam"] class BetaInputTokensTriggerParam(TypedDict, total=False): type: Required[Literal["input_tokens"]] value: Required[int] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_mcp_tool_result_block.py000066400000000000000000000006671506653454500305070ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import List, Union from typing_extensions import Literal from ..._models import BaseModel from .beta_text_block import BetaTextBlock __all__ = ["BetaMCPToolResultBlock"] class BetaMCPToolResultBlock(BaseModel): content: Union[str, List[BetaTextBlock]] is_error: bool tool_use_id: str type: Literal["mcp_tool_result"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_mcp_tool_use_block.py000066400000000000000000000006311506653454500277540ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaMCPToolUseBlock"] class BetaMCPToolUseBlock(BaseModel): id: str input: object name: str """The name of the MCP tool""" server_name: str """The name of the MCP server""" type: Literal["mcp_tool_use"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_mcp_tool_use_block_param.py000066400000000000000000000013021506653454500311300ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam __all__ = ["BetaMCPToolUseBlockParam"] class BetaMCPToolUseBlockParam(TypedDict, total=False): id: Required[str] input: Required[object] name: Required[str] server_name: Required[str] """The name of the MCP server""" type: Required[Literal["mcp_tool_use"]] cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_memory_tool_20250818_command.py000066400000000000000000000022331506653454500311460ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Union from typing_extensions import Annotated, TypeAlias from ..._utils import PropertyInfo from .beta_memory_tool_20250818_view_command import BetaMemoryTool20250818ViewCommand from .beta_memory_tool_20250818_create_command import BetaMemoryTool20250818CreateCommand from .beta_memory_tool_20250818_delete_command import BetaMemoryTool20250818DeleteCommand from .beta_memory_tool_20250818_insert_command import BetaMemoryTool20250818InsertCommand from .beta_memory_tool_20250818_rename_command import BetaMemoryTool20250818RenameCommand from .beta_memory_tool_20250818_str_replace_command import BetaMemoryTool20250818StrReplaceCommand __all__ = ["BetaMemoryTool20250818Command"] BetaMemoryTool20250818Command: TypeAlias = Annotated[ Union[ BetaMemoryTool20250818ViewCommand, BetaMemoryTool20250818CreateCommand, BetaMemoryTool20250818StrReplaceCommand, BetaMemoryTool20250818InsertCommand, BetaMemoryTool20250818DeleteCommand, BetaMemoryTool20250818RenameCommand, ], PropertyInfo(discriminator="command"), ] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_memory_tool_20250818_create_command.py000066400000000000000000000007051506653454500324730ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaMemoryTool20250818CreateCommand"] class BetaMemoryTool20250818CreateCommand(BaseModel): command: Literal["create"] """Command type identifier""" file_text: str """Content to write to the file""" path: str """Path where the file should be created""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_memory_tool_20250818_delete_command.py000066400000000000000000000006141506653454500324710ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaMemoryTool20250818DeleteCommand"] class BetaMemoryTool20250818DeleteCommand(BaseModel): command: Literal["delete"] """Command type identifier""" path: str """Path to the file or directory to delete""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_memory_tool_20250818_insert_command.py000066400000000000000000000010421506653454500325270ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaMemoryTool20250818InsertCommand"] class BetaMemoryTool20250818InsertCommand(BaseModel): command: Literal["insert"] """Command type identifier""" insert_line: int """Line number where text should be inserted""" insert_text: str """Text to insert at the specified line""" path: str """Path to the file where text should be inserted""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_memory_tool_20250818_param.py000066400000000000000000000013211506653454500306250ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam __all__ = ["BetaMemoryTool20250818Param"] class BetaMemoryTool20250818Param(TypedDict, total=False): name: Required[Literal["memory"]] """Name of the tool. This is how the tool will be called by the model and in `tool_use` blocks. """ type: Required[Literal["memory_20250818"]] cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_memory_tool_20250818_rename_command.py000066400000000000000000000007161506653454500325010ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaMemoryTool20250818RenameCommand"] class BetaMemoryTool20250818RenameCommand(BaseModel): command: Literal["rename"] """Command type identifier""" new_path: str """New path for the file or directory""" old_path: str """Current path of the file or directory""" beta_memory_tool_20250818_str_replace_command.py000066400000000000000000000010141506653454500334460ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/types/beta# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaMemoryTool20250818StrReplaceCommand"] class BetaMemoryTool20250818StrReplaceCommand(BaseModel): command: Literal["str_replace"] """Command type identifier""" new_str: str """Text to replace with""" old_str: str """Text to search for and replace""" path: str """Path to the file where text should be replaced""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_memory_tool_20250818_view_command.py000066400000000000000000000010071506653454500321760ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import List, Optional from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaMemoryTool20250818ViewCommand"] class BetaMemoryTool20250818ViewCommand(BaseModel): command: Literal["view"] """Command type identifier""" path: str """Path to directory or file to view""" view_range: Optional[List[int]] = None """Optional line range for viewing specific lines""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_message.py000066400000000000000000000076601506653454500255470ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import List, Optional from typing_extensions import Literal from ..model import Model from ..._models import BaseModel from .beta_usage import BetaUsage from .beta_container import BetaContainer from .beta_stop_reason import BetaStopReason from .beta_content_block import BetaContentBlock, BetaContentBlock as BetaContentBlock from .beta_context_management_response import BetaContextManagementResponse __all__ = ["BetaMessage"] class BetaMessage(BaseModel): id: str """Unique object identifier. The format and length of IDs may change over time. """ container: Optional[BetaContainer] = None """ Information about the container used in the request (for the code execution tool) """ content: List[BetaContentBlock] """Content generated by the model. This is an array of content blocks, each of which has a `type` that determines its shape. Example: ```json [{ "type": "text", "text": "Hi, I'm Claude." }] ``` If the request input `messages` ended with an `assistant` turn, then the response `content` will continue directly from that last turn. You can use this to constrain the model's output. For example, if the input `messages` were: ```json [ { "role": "user", "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun" }, { "role": "assistant", "content": "The best answer is (" } ] ``` Then the response `content` might be: ```json [{ "type": "text", "text": "B)" }] ``` """ context_management: Optional[BetaContextManagementResponse] = None """Information about context management operations applied during the request.""" model: Model """ The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. """ role: Literal["assistant"] """Conversational role of the generated message. This will always be `"assistant"`. """ stop_reason: Optional[BetaStopReason] = None """The reason that we stopped. This may be one the following values: - `"end_turn"`: the model reached a natural stopping point - `"max_tokens"`: we exceeded the requested `max_tokens` or the model's maximum - `"stop_sequence"`: one of your provided custom `stop_sequences` was generated - `"tool_use"`: the model invoked one or more tools - `"pause_turn"`: we paused a long-running turn. You may provide the response back as-is in a subsequent request to let the model continue. - `"refusal"`: when streaming classifiers intervene to handle potential policy violations In non-streaming mode this value is always non-null. In streaming mode, it is null in the `message_start` event and non-null otherwise. """ stop_sequence: Optional[str] = None """Which custom stop sequence was generated, if any. This value will be a non-null string if one of your custom stop sequences was generated. """ type: Literal["message"] """Object type. For Messages, this is always `"message"`. """ usage: BetaUsage """Billing and rate-limit usage. Anthropic's API bills and rate-limits by token counts, as tokens represent the underlying cost to our systems. Under the hood, the API transforms requests into a format suitable for the model. The model's output then goes through a parsing stage before becoming an API response. As a result, the token counts in `usage` will not match one-to-one with the exact visible content of an API request or response. For example, `output_tokens` will be non-zero, even for an empty string response from Claude. Total input tokens in a request is the summation of `input_tokens`, `cache_creation_input_tokens`, and `cache_read_input_tokens`. """ anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_message_delta_usage.py000066400000000000000000000015061506653454500300750ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from ..._models import BaseModel from .beta_server_tool_usage import BetaServerToolUsage __all__ = ["BetaMessageDeltaUsage"] class BetaMessageDeltaUsage(BaseModel): cache_creation_input_tokens: Optional[int] = None """The cumulative number of input tokens used to create the cache entry.""" cache_read_input_tokens: Optional[int] = None """The cumulative number of input tokens read from the cache.""" input_tokens: Optional[int] = None """The cumulative number of input tokens which were used.""" output_tokens: int """The cumulative number of output tokens which were used.""" server_tool_use: Optional[BetaServerToolUsage] = None """The number of server tool requests.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_message_param.py000066400000000000000000000007351506653454500267230ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union, Iterable from typing_extensions import Literal, Required, TypedDict from .beta_content_block_param import BetaContentBlockParam __all__ = ["BetaMessageParam"] class BetaMessageParam(TypedDict, total=False): content: Required[Union[str, Iterable[BetaContentBlockParam]]] role: Required[Literal["user", "assistant"]] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_message_tokens_count.py000066400000000000000000000011551506653454500303330ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from ..._models import BaseModel from .beta_count_tokens_context_management_response import BetaCountTokensContextManagementResponse __all__ = ["BetaMessageTokensCount"] class BetaMessageTokensCount(BaseModel): context_management: Optional[BetaCountTokensContextManagementResponse] = None """Information about context management applied to the message.""" input_tokens: int """ The total number of tokens across the provided list of messages, system prompt, and tools. """ anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_metadata_param.py000066400000000000000000000011321506653454500270470ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import TypedDict __all__ = ["BetaMetadataParam"] class BetaMetadataParam(TypedDict, total=False): user_id: Optional[str] """An external identifier for the user who is associated with the request. This should be a uuid, hash value, or other opaque identifier. Anthropic may use this id to help detect abuse. Do not include any identifying information such as name, email address, or phone number. """ anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_model_info.py000066400000000000000000000012171506653454500262260ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaModelInfo"] class BetaModelInfo(BaseModel): id: str """Unique model identifier.""" created_at: datetime """RFC 3339 datetime string representing the time at which the model was released. May be set to an epoch value if the release date is unknown. """ display_name: str """A human-readable name for the model.""" type: Literal["model"] """Object type. For Models, this is always `"model"`. """ anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_plain_text_source.py000066400000000000000000000004721506653454500276440ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaPlainTextSource"] class BetaPlainTextSource(BaseModel): data: str media_type: Literal["text/plain"] type: Literal["text"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_plain_text_source_param.py000066400000000000000000000006061506653454500310230ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaPlainTextSourceParam"] class BetaPlainTextSourceParam(TypedDict, total=False): data: Required[str] media_type: Required[Literal["text/plain"]] type: Required[Literal["text"]] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_raw_content_block_delta.py000066400000000000000000000012621506653454500307610ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Union from typing_extensions import Annotated, TypeAlias from ..._utils import PropertyInfo from .beta_text_delta import BetaTextDelta from .beta_thinking_delta import BetaThinkingDelta from .beta_citations_delta import BetaCitationsDelta from .beta_signature_delta import BetaSignatureDelta from .beta_input_json_delta import BetaInputJSONDelta __all__ = ["BetaRawContentBlockDelta"] BetaRawContentBlockDelta: TypeAlias = Annotated[ Union[BetaTextDelta, BetaInputJSONDelta, BetaCitationsDelta, BetaThinkingDelta, BetaSignatureDelta], PropertyInfo(discriminator="type"), ] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_raw_content_block_delta_event.py000066400000000000000000000006371506653454500321670ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel from .beta_raw_content_block_delta import BetaRawContentBlockDelta __all__ = ["BetaRawContentBlockDeltaEvent"] class BetaRawContentBlockDeltaEvent(BaseModel): delta: BetaRawContentBlockDelta index: int type: Literal["content_block_delta"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_raw_content_block_start_event.py000066400000000000000000000036361506653454500322350ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Union from typing_extensions import Literal, Annotated, TypeAlias from ..._utils import PropertyInfo from ..._models import BaseModel from .beta_text_block import BetaTextBlock from .beta_thinking_block import BetaThinkingBlock from .beta_tool_use_block import BetaToolUseBlock from .beta_mcp_tool_use_block import BetaMCPToolUseBlock from .beta_mcp_tool_result_block import BetaMCPToolResultBlock from .beta_server_tool_use_block import BetaServerToolUseBlock from .beta_container_upload_block import BetaContainerUploadBlock from .beta_redacted_thinking_block import BetaRedactedThinkingBlock from .beta_web_fetch_tool_result_block import BetaWebFetchToolResultBlock from .beta_web_search_tool_result_block import BetaWebSearchToolResultBlock from .beta_code_execution_tool_result_block import BetaCodeExecutionToolResultBlock from .beta_bash_code_execution_tool_result_block import BetaBashCodeExecutionToolResultBlock from .beta_text_editor_code_execution_tool_result_block import BetaTextEditorCodeExecutionToolResultBlock __all__ = ["BetaRawContentBlockStartEvent", "ContentBlock"] ContentBlock: TypeAlias = Annotated[ Union[ BetaTextBlock, BetaThinkingBlock, BetaRedactedThinkingBlock, BetaToolUseBlock, BetaServerToolUseBlock, BetaWebSearchToolResultBlock, BetaWebFetchToolResultBlock, BetaCodeExecutionToolResultBlock, BetaBashCodeExecutionToolResultBlock, BetaTextEditorCodeExecutionToolResultBlock, BetaMCPToolUseBlock, BetaMCPToolResultBlock, BetaContainerUploadBlock, ], PropertyInfo(discriminator="type"), ] class BetaRawContentBlockStartEvent(BaseModel): content_block: ContentBlock """Response model for a file uploaded to the container.""" index: int type: Literal["content_block_start"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_raw_content_block_stop_event.py000066400000000000000000000004641506653454500320610ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaRawContentBlockStopEvent"] class BetaRawContentBlockStopEvent(BaseModel): index: int type: Literal["content_block_stop"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_raw_message_delta_event.py000066400000000000000000000033131506653454500307610ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from typing_extensions import Literal from ..._models import BaseModel from .beta_container import BetaContainer from .beta_stop_reason import BetaStopReason from .beta_message_delta_usage import BetaMessageDeltaUsage from .beta_context_management_response import BetaContextManagementResponse __all__ = ["BetaRawMessageDeltaEvent", "Delta"] class Delta(BaseModel): container: Optional[BetaContainer] = None """ Information about the container used in the request (for the code execution tool) """ stop_reason: Optional[BetaStopReason] = None stop_sequence: Optional[str] = None class BetaRawMessageDeltaEvent(BaseModel): context_management: Optional[BetaContextManagementResponse] = None """Information about context management operations applied during the request.""" delta: Delta type: Literal["message_delta"] usage: BetaMessageDeltaUsage """Billing and rate-limit usage. Anthropic's API bills and rate-limits by token counts, as tokens represent the underlying cost to our systems. Under the hood, the API transforms requests into a format suitable for the model. The model's output then goes through a parsing stage before becoming an API response. As a result, the token counts in `usage` will not match one-to-one with the exact visible content of an API request or response. For example, `output_tokens` will be non-zero, even for an empty string response from Claude. Total input tokens in a request is the summation of `input_tokens`, `cache_creation_input_tokens`, and `cache_read_input_tokens`. """ anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_raw_message_start_event.py000066400000000000000000000005271506653454500310310ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel from .beta_message import BetaMessage __all__ = ["BetaRawMessageStartEvent"] class BetaRawMessageStartEvent(BaseModel): message: BetaMessage type: Literal["message_start"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_raw_message_stop_event.py000066400000000000000000000004241506653454500306550ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaRawMessageStopEvent"] class BetaRawMessageStopEvent(BaseModel): type: Literal["message_stop"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_raw_message_stream_event.py000066400000000000000000000017471506653454500311740ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Union from typing_extensions import Annotated, TypeAlias from ..._utils import PropertyInfo from .beta_raw_message_stop_event import BetaRawMessageStopEvent from .beta_raw_message_delta_event import BetaRawMessageDeltaEvent from .beta_raw_message_start_event import BetaRawMessageStartEvent from .beta_raw_content_block_stop_event import BetaRawContentBlockStopEvent from .beta_raw_content_block_delta_event import BetaRawContentBlockDeltaEvent from .beta_raw_content_block_start_event import BetaRawContentBlockStartEvent __all__ = ["BetaRawMessageStreamEvent"] BetaRawMessageStreamEvent: TypeAlias = Annotated[ Union[ BetaRawMessageStartEvent, BetaRawMessageDeltaEvent, BetaRawMessageStopEvent, BetaRawContentBlockStartEvent, BetaRawContentBlockDeltaEvent, BetaRawContentBlockStopEvent, ], PropertyInfo(discriminator="type"), ] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_redacted_thinking_block.py000066400000000000000000000004541506653454500307350ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaRedactedThinkingBlock"] class BetaRedactedThinkingBlock(BaseModel): data: str type: Literal["redacted_thinking"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_redacted_thinking_block_param.py000066400000000000000000000005561506653454500321200ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaRedactedThinkingBlockParam"] class BetaRedactedThinkingBlockParam(TypedDict, total=False): data: Required[str] type: Required[Literal["redacted_thinking"]] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_request_document_block_param.py000066400000000000000000000024471506653454500320410ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union, Optional from typing_extensions import Literal, Required, TypeAlias, TypedDict from .beta_url_pdf_source_param import BetaURLPDFSourceParam from .beta_citations_config_param import BetaCitationsConfigParam from .beta_base64_pdf_source_param import BetaBase64PDFSourceParam from .beta_plain_text_source_param import BetaPlainTextSourceParam from .beta_content_block_source_param import BetaContentBlockSourceParam from .beta_file_document_source_param import BetaFileDocumentSourceParam from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam __all__ = ["BetaRequestDocumentBlockParam", "Source"] Source: TypeAlias = Union[ BetaBase64PDFSourceParam, BetaPlainTextSourceParam, BetaContentBlockSourceParam, BetaURLPDFSourceParam, BetaFileDocumentSourceParam, ] class BetaRequestDocumentBlockParam(TypedDict, total=False): source: Required[Source] type: Required[Literal["document"]] cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" citations: Optional[BetaCitationsConfigParam] context: Optional[str] title: Optional[str] beta_request_mcp_server_tool_configuration_param.py000066400000000000000000000006711506653454500351200ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/types/beta# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import TypedDict from ..._types import SequenceNotStr __all__ = ["BetaRequestMCPServerToolConfigurationParam"] class BetaRequestMCPServerToolConfigurationParam(TypedDict, total=False): allowed_tools: Optional[SequenceNotStr[str]] enabled: Optional[bool] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_request_mcp_server_url_definition_param.py000066400000000000000000000012041506653454500342760ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from .beta_request_mcp_server_tool_configuration_param import BetaRequestMCPServerToolConfigurationParam __all__ = ["BetaRequestMCPServerURLDefinitionParam"] class BetaRequestMCPServerURLDefinitionParam(TypedDict, total=False): name: Required[str] type: Required[Literal["url"]] url: Required[str] authorization_token: Optional[str] tool_configuration: Optional[BetaRequestMCPServerToolConfigurationParam] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_request_mcp_tool_result_block_param.py000066400000000000000000000013711506653454500334300ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union, Iterable, Optional from typing_extensions import Literal, Required, TypedDict from .beta_text_block_param import BetaTextBlockParam from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam __all__ = ["BetaRequestMCPToolResultBlockParam"] class BetaRequestMCPToolResultBlockParam(TypedDict, total=False): tool_use_id: Required[str] type: Required[Literal["mcp_tool_result"]] cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" content: Union[str, Iterable[BetaTextBlockParam]] is_error: bool anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_search_result_block_param.py000066400000000000000000000015121506653454500313060ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Iterable, Optional from typing_extensions import Literal, Required, TypedDict from .beta_text_block_param import BetaTextBlockParam from .beta_citations_config_param import BetaCitationsConfigParam from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam __all__ = ["BetaSearchResultBlockParam"] class BetaSearchResultBlockParam(TypedDict, total=False): content: Required[Iterable[BetaTextBlockParam]] source: Required[str] title: Required[str] type: Required[Literal["search_result"]] cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" citations: BetaCitationsConfigParam anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_server_tool_usage.py000066400000000000000000000005401506653454500276400ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from ..._models import BaseModel __all__ = ["BetaServerToolUsage"] class BetaServerToolUsage(BaseModel): web_fetch_requests: int """The number of web fetch tool requests.""" web_search_requests: int """The number of web search tool requests.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_server_tool_use_block.py000066400000000000000000000006521506653454500305060ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaServerToolUseBlock"] class BetaServerToolUseBlock(BaseModel): id: str input: object name: Literal["web_search", "web_fetch", "code_execution", "bash_code_execution", "text_editor_code_execution"] type: Literal["server_tool_use"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_server_tool_use_block_param.py000066400000000000000000000013721506653454500316660ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam __all__ = ["BetaServerToolUseBlockParam"] class BetaServerToolUseBlockParam(TypedDict, total=False): id: Required[str] input: Required[object] name: Required[ Literal["web_search", "web_fetch", "code_execution", "bash_code_execution", "text_editor_code_execution"] ] type: Required[Literal["server_tool_use"]] cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_signature_delta.py000066400000000000000000000004411506653454500272630ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaSignatureDelta"] class BetaSignatureDelta(BaseModel): signature: str type: Literal["signature_delta"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_stop_reason.py000066400000000000000000000005021506653454500264430ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal, TypeAlias __all__ = ["BetaStopReason"] BetaStopReason: TypeAlias = Literal[ "end_turn", "max_tokens", "stop_sequence", "tool_use", "pause_turn", "refusal", "model_context_window_exceeded" ] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_text_block.py000066400000000000000000000012541506653454500262520ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import List, Optional from typing_extensions import Literal from ..._models import BaseModel from .beta_text_citation import BetaTextCitation __all__ = ["BetaTextBlock"] class BetaTextBlock(BaseModel): citations: Optional[List[BetaTextCitation]] = None """Citations supporting the text block. The type of citation returned will depend on the type of document being cited. Citing a PDF results in `page_location`, plain text results in `char_location`, and content document results in `content_block_location`. """ text: str type: Literal["text"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_text_block_param.py000066400000000000000000000012651506653454500274340ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Iterable, Optional from typing_extensions import Literal, Required, TypedDict from .beta_text_citation_param import BetaTextCitationParam from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam __all__ = ["BetaTextBlockParam"] class BetaTextBlockParam(TypedDict, total=False): text: Required[str] type: Required[Literal["text"]] cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" citations: Optional[Iterable[BetaTextCitationParam]] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_text_citation.py000066400000000000000000000016311506653454500267710ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Union from typing_extensions import Annotated, TypeAlias from ..._utils import PropertyInfo from .beta_citation_char_location import BetaCitationCharLocation from .beta_citation_page_location import BetaCitationPageLocation from .beta_citation_content_block_location import BetaCitationContentBlockLocation from .beta_citation_search_result_location import BetaCitationSearchResultLocation from .beta_citations_web_search_result_location import BetaCitationsWebSearchResultLocation __all__ = ["BetaTextCitation"] BetaTextCitation: TypeAlias = Annotated[ Union[ BetaCitationCharLocation, BetaCitationPageLocation, BetaCitationContentBlockLocation, BetaCitationsWebSearchResultLocation, BetaCitationSearchResultLocation, ], PropertyInfo(discriminator="type"), ] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_text_citation_param.py000066400000000000000000000016241506653454500301530ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union from typing_extensions import TypeAlias from .beta_citation_char_location_param import BetaCitationCharLocationParam from .beta_citation_page_location_param import BetaCitationPageLocationParam from .beta_citation_content_block_location_param import BetaCitationContentBlockLocationParam from .beta_citation_search_result_location_param import BetaCitationSearchResultLocationParam from .beta_citation_web_search_result_location_param import BetaCitationWebSearchResultLocationParam __all__ = ["BetaTextCitationParam"] BetaTextCitationParam: TypeAlias = Union[ BetaCitationCharLocationParam, BetaCitationPageLocationParam, BetaCitationContentBlockLocationParam, BetaCitationWebSearchResultLocationParam, BetaCitationSearchResultLocationParam, ] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_text_delta.py000066400000000000000000000004151506653454500262470ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaTextDelta"] class BetaTextDelta(BaseModel): text: str type: Literal["text_delta"] beta_text_editor_code_execution_create_result_block.py000066400000000000000000000005641506653454500355420ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/types/beta# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaTextEditorCodeExecutionCreateResultBlock"] class BetaTextEditorCodeExecutionCreateResultBlock(BaseModel): is_file_update: bool type: Literal["text_editor_code_execution_create_result"] beta_text_editor_code_execution_create_result_block_param.py000066400000000000000000000006661506653454500367250ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/types/beta# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaTextEditorCodeExecutionCreateResultBlockParam"] class BetaTextEditorCodeExecutionCreateResultBlockParam(TypedDict, total=False): is_file_update: Required[bool] type: Required[Literal["text_editor_code_execution_create_result"]] beta_text_editor_code_execution_str_replace_result_block.py000066400000000000000000000011041506653454500365710ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/types/beta# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import List, Optional from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaTextEditorCodeExecutionStrReplaceResultBlock"] class BetaTextEditorCodeExecutionStrReplaceResultBlock(BaseModel): lines: Optional[List[str]] = None new_lines: Optional[int] = None new_start: Optional[int] = None old_lines: Optional[int] = None old_start: Optional[int] = None type: Literal["text_editor_code_execution_str_replace_result"] beta_text_editor_code_execution_str_replace_result_block_param.py000066400000000000000000000012031506653454500377510ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/types/beta# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from ..._types import SequenceNotStr __all__ = ["BetaTextEditorCodeExecutionStrReplaceResultBlockParam"] class BetaTextEditorCodeExecutionStrReplaceResultBlockParam(TypedDict, total=False): type: Required[Literal["text_editor_code_execution_str_replace_result"]] lines: Optional[SequenceNotStr[str]] new_lines: Optional[int] new_start: Optional[int] old_lines: Optional[int] old_start: Optional[int] beta_text_editor_code_execution_tool_result_block.py000066400000000000000000000021171506653454500352500ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/types/beta# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Union from typing_extensions import Literal, TypeAlias from ..._models import BaseModel from .beta_text_editor_code_execution_tool_result_error import BetaTextEditorCodeExecutionToolResultError from .beta_text_editor_code_execution_view_result_block import BetaTextEditorCodeExecutionViewResultBlock from .beta_text_editor_code_execution_create_result_block import BetaTextEditorCodeExecutionCreateResultBlock from .beta_text_editor_code_execution_str_replace_result_block import BetaTextEditorCodeExecutionStrReplaceResultBlock __all__ = ["BetaTextEditorCodeExecutionToolResultBlock", "Content"] Content: TypeAlias = Union[ BetaTextEditorCodeExecutionToolResultError, BetaTextEditorCodeExecutionViewResultBlock, BetaTextEditorCodeExecutionCreateResultBlock, BetaTextEditorCodeExecutionStrReplaceResultBlock, ] class BetaTextEditorCodeExecutionToolResultBlock(BaseModel): content: Content tool_use_id: str type: Literal["text_editor_code_execution_tool_result"] beta_text_editor_code_execution_tool_result_block_param.py000066400000000000000000000026761506653454500364420ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/types/beta# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union, Optional from typing_extensions import Literal, Required, TypeAlias, TypedDict from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam from .beta_text_editor_code_execution_tool_result_error_param import BetaTextEditorCodeExecutionToolResultErrorParam from .beta_text_editor_code_execution_view_result_block_param import BetaTextEditorCodeExecutionViewResultBlockParam from .beta_text_editor_code_execution_create_result_block_param import BetaTextEditorCodeExecutionCreateResultBlockParam from .beta_text_editor_code_execution_str_replace_result_block_param import ( BetaTextEditorCodeExecutionStrReplaceResultBlockParam, ) __all__ = ["BetaTextEditorCodeExecutionToolResultBlockParam", "Content"] Content: TypeAlias = Union[ BetaTextEditorCodeExecutionToolResultErrorParam, BetaTextEditorCodeExecutionViewResultBlockParam, BetaTextEditorCodeExecutionCreateResultBlockParam, BetaTextEditorCodeExecutionStrReplaceResultBlockParam, ] class BetaTextEditorCodeExecutionToolResultBlockParam(TypedDict, total=False): content: Required[Content] tool_use_id: Required[str] type: Required[Literal["text_editor_code_execution_tool_result"]] cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" beta_text_editor_code_execution_tool_result_error.py000066400000000000000000000010551506653454500353070ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/types/beta# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaTextEditorCodeExecutionToolResultError"] class BetaTextEditorCodeExecutionToolResultError(BaseModel): error_code: Literal[ "invalid_tool_input", "unavailable", "too_many_requests", "execution_time_exceeded", "file_not_found" ] error_message: Optional[str] = None type: Literal["text_editor_code_execution_tool_result_error"] beta_text_editor_code_execution_tool_result_error_param.py000066400000000000000000000011501506653454500364630ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/types/beta# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaTextEditorCodeExecutionToolResultErrorParam"] class BetaTextEditorCodeExecutionToolResultErrorParam(TypedDict, total=False): error_code: Required[ Literal["invalid_tool_input", "unavailable", "too_many_requests", "execution_time_exceeded", "file_not_found"] ] type: Required[Literal["text_editor_code_execution_tool_result_error"]] error_message: Optional[str] beta_text_editor_code_execution_view_result_block.py000066400000000000000000000010441506653454500352430ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/types/beta# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaTextEditorCodeExecutionViewResultBlock"] class BetaTextEditorCodeExecutionViewResultBlock(BaseModel): content: str file_type: Literal["text", "image", "pdf"] num_lines: Optional[int] = None start_line: Optional[int] = None total_lines: Optional[int] = None type: Literal["text_editor_code_execution_view_result"] beta_text_editor_code_execution_view_result_block_param.py000066400000000000000000000011331506653454500364220ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/types/beta# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaTextEditorCodeExecutionViewResultBlockParam"] class BetaTextEditorCodeExecutionViewResultBlockParam(TypedDict, total=False): content: Required[str] file_type: Required[Literal["text", "image", "pdf"]] type: Required[Literal["text_editor_code_execution_view_result"]] num_lines: Optional[int] start_line: Optional[int] total_lines: Optional[int] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_thinking_block.py000066400000000000000000000004531506653454500271010ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaThinkingBlock"] class BetaThinkingBlock(BaseModel): signature: str thinking: str type: Literal["thinking"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_thinking_block_param.py000066400000000000000000000005671506653454500302670ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaThinkingBlockParam"] class BetaThinkingBlockParam(TypedDict, total=False): signature: Required[str] thinking: Required[str] type: Required[Literal["thinking"]] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_thinking_config_disabled_param.py000066400000000000000000000005161506653454500322630ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaThinkingConfigDisabledParam"] class BetaThinkingConfigDisabledParam(TypedDict, total=False): type: Required[Literal["disabled"]] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_thinking_config_enabled_param.py000066400000000000000000000013411506653454500321030ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaThinkingConfigEnabledParam"] class BetaThinkingConfigEnabledParam(TypedDict, total=False): budget_tokens: Required[int] """Determines how many tokens Claude can use for its internal reasoning process. Larger budgets can enable more thorough analysis for complex problems, improving response quality. Must be ≥1024 and less than `max_tokens`. See [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) for details. """ type: Required[Literal["enabled"]] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_thinking_config_param.py000066400000000000000000000007611506653454500304360ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union from typing_extensions import TypeAlias from .beta_thinking_config_enabled_param import BetaThinkingConfigEnabledParam from .beta_thinking_config_disabled_param import BetaThinkingConfigDisabledParam __all__ = ["BetaThinkingConfigParam"] BetaThinkingConfigParam: TypeAlias = Union[BetaThinkingConfigEnabledParam, BetaThinkingConfigDisabledParam] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_thinking_delta.py000066400000000000000000000004351506653454500271000ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaThinkingDelta"] class BetaThinkingDelta(BaseModel): thinking: str type: Literal["thinking_delta"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_tool_bash_20241022_param.py000066400000000000000000000013111506653454500302140ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam __all__ = ["BetaToolBash20241022Param"] class BetaToolBash20241022Param(TypedDict, total=False): name: Required[Literal["bash"]] """Name of the tool. This is how the tool will be called by the model and in `tool_use` blocks. """ type: Required[Literal["bash_20241022"]] cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_tool_bash_20250124_param.py000066400000000000000000000013111506653454500302170ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam __all__ = ["BetaToolBash20250124Param"] class BetaToolBash20250124Param(TypedDict, total=False): name: Required[Literal["bash"]] """Name of the tool. This is how the tool will be called by the model and in `tool_use` blocks. """ type: Required[Literal["bash_20250124"]] cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_tool_choice_any_param.py000066400000000000000000000007551506653454500304370ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaToolChoiceAnyParam"] class BetaToolChoiceAnyParam(TypedDict, total=False): type: Required[Literal["any"]] disable_parallel_tool_use: bool """Whether to disable parallel tool use. Defaults to `false`. If set to `true`, the model will output exactly one tool use. """ anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_tool_choice_auto_param.py000066400000000000000000000007601506653454500306140ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaToolChoiceAutoParam"] class BetaToolChoiceAutoParam(TypedDict, total=False): type: Required[Literal["auto"]] disable_parallel_tool_use: bool """Whether to disable parallel tool use. Defaults to `false`. If set to `true`, the model will output at most one tool use. """ anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_tool_choice_none_param.py000066400000000000000000000004721506653454500306030ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaToolChoiceNoneParam"] class BetaToolChoiceNoneParam(TypedDict, total=False): type: Required[Literal["none"]] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_tool_choice_param.py000066400000000000000000000011631506653454500275620ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union from typing_extensions import TypeAlias from .beta_tool_choice_any_param import BetaToolChoiceAnyParam from .beta_tool_choice_auto_param import BetaToolChoiceAutoParam from .beta_tool_choice_none_param import BetaToolChoiceNoneParam from .beta_tool_choice_tool_param import BetaToolChoiceToolParam __all__ = ["BetaToolChoiceParam"] BetaToolChoiceParam: TypeAlias = Union[ BetaToolChoiceAutoParam, BetaToolChoiceAnyParam, BetaToolChoiceToolParam, BetaToolChoiceNoneParam ] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_tool_choice_tool_param.py000066400000000000000000000010601506653454500306130ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaToolChoiceToolParam"] class BetaToolChoiceToolParam(TypedDict, total=False): name: Required[str] """The name of the tool to use.""" type: Required[Literal["tool"]] disable_parallel_tool_use: bool """Whether to disable parallel tool use. Defaults to `false`. If set to `true`, the model will output exactly one tool use. """ anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_tool_computer_use_20241022_param.py000066400000000000000000000017501506653454500320200ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam __all__ = ["BetaToolComputerUse20241022Param"] class BetaToolComputerUse20241022Param(TypedDict, total=False): display_height_px: Required[int] """The height of the display in pixels.""" display_width_px: Required[int] """The width of the display in pixels.""" name: Required[Literal["computer"]] """Name of the tool. This is how the tool will be called by the model and in `tool_use` blocks. """ type: Required[Literal["computer_20241022"]] cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" display_number: Optional[int] """The X11 display number (e.g. 0, 1) for the display.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_tool_computer_use_20250124_param.py000066400000000000000000000017501506653454500320230ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam __all__ = ["BetaToolComputerUse20250124Param"] class BetaToolComputerUse20250124Param(TypedDict, total=False): display_height_px: Required[int] """The height of the display in pixels.""" display_width_px: Required[int] """The width of the display in pixels.""" name: Required[Literal["computer"]] """Name of the tool. This is how the tool will be called by the model and in `tool_use` blocks. """ type: Required[Literal["computer_20250124"]] cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" display_number: Optional[int] """The X11 display number (e.g. 0, 1) for the display.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_tool_param.py000066400000000000000000000030471506653454500262530ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Dict, Union, Optional from typing_extensions import Literal, Required, TypeAlias, TypedDict from ..._types import SequenceNotStr from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam __all__ = ["BetaToolParam", "InputSchema"] class InputSchemaTyped(TypedDict, total=False): type: Required[Literal["object"]] properties: Optional[object] required: Optional[SequenceNotStr[str]] InputSchema: TypeAlias = Union[InputSchemaTyped, Dict[str, object]] class BetaToolParam(TypedDict, total=False): input_schema: Required[InputSchema] """[JSON schema](https://json-schema.org/draft/2020-12) for this tool's input. This defines the shape of the `input` that your tool accepts and that the model will produce. """ name: Required[str] """Name of the tool. This is how the tool will be called by the model and in `tool_use` blocks. """ cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" description: str """Description of what this tool does. Tool descriptions should be as detailed as possible. The more information that the model has about what the tool is and how to use it, the better it will perform. You can use natural language descriptions to reinforce important aspects of the tool input JSON schema. """ type: Optional[Literal["custom"]] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_tool_result_block_param.py000066400000000000000000000020761506653454500310240ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union, Iterable, Optional from typing_extensions import Literal, Required, TypeAlias, TypedDict from .beta_text_block_param import BetaTextBlockParam from .beta_image_block_param import BetaImageBlockParam from .beta_search_result_block_param import BetaSearchResultBlockParam from .beta_request_document_block_param import BetaRequestDocumentBlockParam from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam __all__ = ["BetaToolResultBlockParam", "Content"] Content: TypeAlias = Union[ BetaTextBlockParam, BetaImageBlockParam, BetaSearchResultBlockParam, BetaRequestDocumentBlockParam ] class BetaToolResultBlockParam(TypedDict, total=False): tool_use_id: Required[str] type: Required[Literal["tool_result"]] cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" content: Union[str, Iterable[Content]] is_error: bool anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_tool_text_editor_20241022_param.py000066400000000000000000000013521506653454500316360ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam __all__ = ["BetaToolTextEditor20241022Param"] class BetaToolTextEditor20241022Param(TypedDict, total=False): name: Required[Literal["str_replace_editor"]] """Name of the tool. This is how the tool will be called by the model and in `tool_use` blocks. """ type: Required[Literal["text_editor_20241022"]] cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_tool_text_editor_20250124_param.py000066400000000000000000000013521506653454500316410ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam __all__ = ["BetaToolTextEditor20250124Param"] class BetaToolTextEditor20250124Param(TypedDict, total=False): name: Required[Literal["str_replace_editor"]] """Name of the tool. This is how the tool will be called by the model and in `tool_use` blocks. """ type: Required[Literal["text_editor_20250124"]] cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_tool_text_editor_20250429_param.py000066400000000000000000000013631506653454500316530ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam __all__ = ["BetaToolTextEditor20250429Param"] class BetaToolTextEditor20250429Param(TypedDict, total=False): name: Required[Literal["str_replace_based_edit_tool"]] """Name of the tool. This is how the tool will be called by the model and in `tool_use` blocks. """ type: Required[Literal["text_editor_20250429"]] cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_tool_text_editor_20250728_param.py000066400000000000000000000016371506653454500316610ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam __all__ = ["BetaToolTextEditor20250728Param"] class BetaToolTextEditor20250728Param(TypedDict, total=False): name: Required[Literal["str_replace_based_edit_tool"]] """Name of the tool. This is how the tool will be called by the model and in `tool_use` blocks. """ type: Required[Literal["text_editor_20250728"]] cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" max_characters: Optional[int] """Maximum number of characters to display when viewing a file. If not specified, defaults to displaying the full file. """ anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_tool_union_param.py000066400000000000000000000034561506653454500274670ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union from typing_extensions import TypeAlias from .beta_tool_param import BetaToolParam from .beta_tool_bash_20241022_param import BetaToolBash20241022Param from .beta_tool_bash_20250124_param import BetaToolBash20250124Param from .beta_memory_tool_20250818_param import BetaMemoryTool20250818Param from .beta_web_fetch_tool_20250910_param import BetaWebFetchTool20250910Param from .beta_web_search_tool_20250305_param import BetaWebSearchTool20250305Param from .beta_tool_text_editor_20241022_param import BetaToolTextEditor20241022Param from .beta_tool_text_editor_20250124_param import BetaToolTextEditor20250124Param from .beta_tool_text_editor_20250429_param import BetaToolTextEditor20250429Param from .beta_tool_text_editor_20250728_param import BetaToolTextEditor20250728Param from .beta_tool_computer_use_20241022_param import BetaToolComputerUse20241022Param from .beta_tool_computer_use_20250124_param import BetaToolComputerUse20250124Param from .beta_code_execution_tool_20250522_param import BetaCodeExecutionTool20250522Param from .beta_code_execution_tool_20250825_param import BetaCodeExecutionTool20250825Param __all__ = ["BetaToolUnionParam"] BetaToolUnionParam: TypeAlias = Union[ BetaToolParam, BetaToolBash20241022Param, BetaToolBash20250124Param, BetaCodeExecutionTool20250522Param, BetaCodeExecutionTool20250825Param, BetaToolComputerUse20241022Param, BetaMemoryTool20250818Param, BetaToolComputerUse20250124Param, BetaToolTextEditor20241022Param, BetaToolTextEditor20250124Param, BetaToolTextEditor20250429Param, BetaToolTextEditor20250728Param, BetaWebSearchTool20250305Param, BetaWebFetchTool20250910Param, ] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_tool_use_block.py000066400000000000000000000004611506653454500271160ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaToolUseBlock"] class BetaToolUseBlock(BaseModel): id: str input: object name: str type: Literal["tool_use"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_tool_use_block_param.py000066400000000000000000000011631506653454500302760ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam __all__ = ["BetaToolUseBlockParam"] class BetaToolUseBlockParam(TypedDict, total=False): id: Required[str] input: Required[object] name: Required[str] type: Required[Literal["tool_use"]] cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_tool_uses_keep_param.py000066400000000000000000000005251506653454500303140ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaToolUsesKeepParam"] class BetaToolUsesKeepParam(TypedDict, total=False): type: Required[Literal["tool_uses"]] value: Required[int] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_tool_uses_trigger_param.py000066400000000000000000000005331506653454500310320ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaToolUsesTriggerParam"] class BetaToolUsesTriggerParam(TypedDict, total=False): type: Required[Literal["tool_uses"]] value: Required[int] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_url_image_source_param.py000066400000000000000000000005211506653454500306140ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaURLImageSourceParam"] class BetaURLImageSourceParam(TypedDict, total=False): type: Required[Literal["url"]] url: Required[str] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_url_pdf_source_param.py000066400000000000000000000005151506653454500303060ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaURLPDFSourceParam"] class BetaURLPDFSourceParam(TypedDict, total=False): type: Required[Literal["url"]] url: Required[str] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_usage.py000066400000000000000000000021001506653454500252070ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from typing_extensions import Literal from ..._models import BaseModel from .beta_cache_creation import BetaCacheCreation from .beta_server_tool_usage import BetaServerToolUsage __all__ = ["BetaUsage"] class BetaUsage(BaseModel): cache_creation: Optional[BetaCacheCreation] = None """Breakdown of cached tokens by TTL""" cache_creation_input_tokens: Optional[int] = None """The number of input tokens used to create the cache entry.""" cache_read_input_tokens: Optional[int] = None """The number of input tokens read from the cache.""" input_tokens: int """The number of input tokens which were used.""" output_tokens: int """The number of output tokens which were used.""" server_tool_use: Optional[BetaServerToolUsage] = None """The number of server tool requests.""" service_tier: Optional[Literal["standard", "priority", "batch"]] = None """If the request used the priority, standard, or batch tier.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_web_fetch_block.py000066400000000000000000000010131506653454500272050ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from typing_extensions import Literal from ..._models import BaseModel from .beta_document_block import BetaDocumentBlock __all__ = ["BetaWebFetchBlock"] class BetaWebFetchBlock(BaseModel): content: BetaDocumentBlock retrieved_at: Optional[str] = None """ISO 8601 timestamp when the content was retrieved""" type: Literal["web_fetch_result"] url: str """Fetched content URL""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_web_fetch_block_param.py000066400000000000000000000011671506653454500303770ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from .beta_request_document_block_param import BetaRequestDocumentBlockParam __all__ = ["BetaWebFetchBlockParam"] class BetaWebFetchBlockParam(TypedDict, total=False): content: Required[BetaRequestDocumentBlockParam] type: Required[Literal["web_fetch_result"]] url: Required[str] """Fetched content URL""" retrieved_at: Optional[str] """ISO 8601 timestamp when the content was retrieved""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_web_fetch_tool_20250910_param.py000066400000000000000000000027451506653454500312470ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from ..._types import SequenceNotStr from .beta_citations_config_param import BetaCitationsConfigParam from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam __all__ = ["BetaWebFetchTool20250910Param"] class BetaWebFetchTool20250910Param(TypedDict, total=False): name: Required[Literal["web_fetch"]] """Name of the tool. This is how the tool will be called by the model and in `tool_use` blocks. """ type: Required[Literal["web_fetch_20250910"]] allowed_domains: Optional[SequenceNotStr[str]] """List of domains to allow fetching from""" blocked_domains: Optional[SequenceNotStr[str]] """List of domains to block fetching from""" cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" citations: Optional[BetaCitationsConfigParam] """Citations configuration for fetched documents. Citations are disabled by default. """ max_content_tokens: Optional[int] """Maximum number of tokens used by including web page text content in the context. The limit is approximate and does not apply to binary content such as PDFs. """ max_uses: Optional[int] """Maximum number of times the tool can be used in the API request.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_web_fetch_tool_result_block.py000066400000000000000000000011321506653454500316420ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Union from typing_extensions import Literal, TypeAlias from ..._models import BaseModel from .beta_web_fetch_block import BetaWebFetchBlock from .beta_web_fetch_tool_result_error_block import BetaWebFetchToolResultErrorBlock __all__ = ["BetaWebFetchToolResultBlock", "Content"] Content: TypeAlias = Union[BetaWebFetchToolResultErrorBlock, BetaWebFetchBlock] class BetaWebFetchToolResultBlock(BaseModel): content: Content tool_use_id: str type: Literal["web_fetch_tool_result"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_web_fetch_tool_result_block_param.py000066400000000000000000000016401506653454500330260ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union, Optional from typing_extensions import Literal, Required, TypeAlias, TypedDict from .beta_web_fetch_block_param import BetaWebFetchBlockParam from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam from .beta_web_fetch_tool_result_error_block_param import BetaWebFetchToolResultErrorBlockParam __all__ = ["BetaWebFetchToolResultBlockParam", "Content"] Content: TypeAlias = Union[BetaWebFetchToolResultErrorBlockParam, BetaWebFetchBlockParam] class BetaWebFetchToolResultBlockParam(TypedDict, total=False): content: Required[Content] tool_use_id: Required[str] type: Required[Literal["web_fetch_tool_result"]] cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_web_fetch_tool_result_error_block.py000066400000000000000000000006711506653454500330620ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel from .beta_web_fetch_tool_result_error_code import BetaWebFetchToolResultErrorCode __all__ = ["BetaWebFetchToolResultErrorBlock"] class BetaWebFetchToolResultErrorBlock(BaseModel): error_code: BetaWebFetchToolResultErrorCode type: Literal["web_fetch_tool_result_error"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_web_fetch_tool_result_error_block_param.py000066400000000000000000000007741506653454500342460ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict from .beta_web_fetch_tool_result_error_code import BetaWebFetchToolResultErrorCode __all__ = ["BetaWebFetchToolResultErrorBlockParam"] class BetaWebFetchToolResultErrorBlockParam(TypedDict, total=False): error_code: Required[BetaWebFetchToolResultErrorCode] type: Required[Literal["web_fetch_tool_result_error"]] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_web_fetch_tool_result_error_code.py000066400000000000000000000006641506653454500327040ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal, TypeAlias __all__ = ["BetaWebFetchToolResultErrorCode"] BetaWebFetchToolResultErrorCode: TypeAlias = Literal[ "invalid_tool_input", "url_too_long", "url_not_allowed", "url_not_accessible", "unsupported_content_type", "too_many_requests", "max_uses_exceeded", "unavailable", ] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_web_search_result_block.py000066400000000000000000000006251506653454500307670ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BetaWebSearchResultBlock"] class BetaWebSearchResultBlock(BaseModel): encrypted_content: str page_age: Optional[str] = None title: str type: Literal["web_search_result"] url: str anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_web_search_result_block_param.py000066400000000000000000000007441506653454500321510ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict __all__ = ["BetaWebSearchResultBlockParam"] class BetaWebSearchResultBlockParam(TypedDict, total=False): encrypted_content: Required[str] title: Required[str] type: Required[Literal["web_search_result"]] url: Required[str] page_age: Optional[str] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_web_search_tool_20250305_param.py000066400000000000000000000034731506653454500314200ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from ..._types import SequenceNotStr from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam __all__ = ["BetaWebSearchTool20250305Param", "UserLocation"] class UserLocation(TypedDict, total=False): type: Required[Literal["approximate"]] city: Optional[str] """The city of the user.""" country: Optional[str] """ The two letter [ISO country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) of the user. """ region: Optional[str] """The region of the user.""" timezone: Optional[str] """The [IANA timezone](https://nodatime.org/TimeZones) of the user.""" class BetaWebSearchTool20250305Param(TypedDict, total=False): name: Required[Literal["web_search"]] """Name of the tool. This is how the tool will be called by the model and in `tool_use` blocks. """ type: Required[Literal["web_search_20250305"]] allowed_domains: Optional[SequenceNotStr[str]] """If provided, only these domains will be included in results. Cannot be used alongside `blocked_domains`. """ blocked_domains: Optional[SequenceNotStr[str]] """If provided, these domains will never appear in results. Cannot be used alongside `allowed_domains`. """ cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" max_uses: Optional[int] """Maximum number of times the tool can be used in the API request.""" user_location: Optional[UserLocation] """Parameters for the user's location. Used to provide more relevant search results. """ anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_web_search_tool_request_error_param.py000066400000000000000000000007721506653454500334200ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict from .beta_web_search_tool_result_error_code import BetaWebSearchToolResultErrorCode __all__ = ["BetaWebSearchToolRequestErrorParam"] class BetaWebSearchToolRequestErrorParam(TypedDict, total=False): error_code: Required[BetaWebSearchToolResultErrorCode] type: Required[Literal["web_search_tool_result_error"]] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_web_search_tool_result_block.py000066400000000000000000000007131506653454500320220ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel from .beta_web_search_tool_result_block_content import BetaWebSearchToolResultBlockContent __all__ = ["BetaWebSearchToolResultBlock"] class BetaWebSearchToolResultBlock(BaseModel): content: BetaWebSearchToolResultBlockContent tool_use_id: str type: Literal["web_search_tool_result"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_web_search_tool_result_block_content.py000066400000000000000000000007271506653454500335610ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import List, Union from typing_extensions import TypeAlias from .beta_web_search_result_block import BetaWebSearchResultBlock from .beta_web_search_tool_result_error import BetaWebSearchToolResultError __all__ = ["BetaWebSearchToolResultBlockContent"] BetaWebSearchToolResultBlockContent: TypeAlias = Union[BetaWebSearchToolResultError, List[BetaWebSearchResultBlock]] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_web_search_tool_result_block_param.py000066400000000000000000000014431506653454500332030ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from .beta_cache_control_ephemeral_param import BetaCacheControlEphemeralParam from .beta_web_search_tool_result_block_param_content_param import BetaWebSearchToolResultBlockParamContentParam __all__ = ["BetaWebSearchToolResultBlockParam"] class BetaWebSearchToolResultBlockParam(TypedDict, total=False): content: Required[BetaWebSearchToolResultBlockParamContentParam] tool_use_id: Required[str] type: Required[Literal["web_search_tool_result"]] cache_control: Optional[BetaCacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" beta_web_search_tool_result_block_param_content_param.py000066400000000000000000000011001506653454500360240ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/types/beta# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union, Iterable from typing_extensions import TypeAlias from .beta_web_search_result_block_param import BetaWebSearchResultBlockParam from .beta_web_search_tool_request_error_param import BetaWebSearchToolRequestErrorParam __all__ = ["BetaWebSearchToolResultBlockParamContentParam"] BetaWebSearchToolResultBlockParamContentParam: TypeAlias = Union[ Iterable[BetaWebSearchResultBlockParam], BetaWebSearchToolRequestErrorParam ] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_web_search_tool_result_error.py000066400000000000000000000006651506653454500320670ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel from .beta_web_search_tool_result_error_code import BetaWebSearchToolResultErrorCode __all__ = ["BetaWebSearchToolResultError"] class BetaWebSearchToolResultError(BaseModel): error_code: BetaWebSearchToolResultErrorCode type: Literal["web_search_tool_result_error"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/beta_web_search_tool_result_error_code.py000066400000000000000000000005261506653454500330550ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal, TypeAlias __all__ = ["BetaWebSearchToolResultErrorCode"] BetaWebSearchToolResultErrorCode: TypeAlias = Literal[ "invalid_tool_input", "unavailable", "max_uses_exceeded", "too_many_requests", "query_too_long" ] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/deleted_file.py000066400000000000000000000006651506653454500255330ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from typing_extensions import Literal from ..._models import BaseModel __all__ = ["DeletedFile"] class DeletedFile(BaseModel): id: str """ID of the deleted file.""" type: Optional[Literal["file_deleted"]] = None """Deleted object type. For file deletion, this is always `"file_deleted"`. """ anthropic-sdk-python-0.69.0/src/anthropic/types/beta/file_list_params.py000066400000000000000000000017161506653454500264410ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import List from typing_extensions import Annotated, TypedDict from ..._utils import PropertyInfo from ..anthropic_beta_param import AnthropicBetaParam __all__ = ["FileListParams"] class FileListParams(TypedDict, total=False): after_id: str """ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately after this object. """ before_id: str """ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately before this object. """ limit: int """Number of items to return per page. Defaults to `20`. Ranges from `1` to `1000`. """ betas: Annotated[List[AnthropicBetaParam], PropertyInfo(alias="anthropic-beta")] """Optional header to specify the beta version(s) you want to use.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/file_metadata.py000066400000000000000000000015231506653454500256770ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel __all__ = ["FileMetadata"] class FileMetadata(BaseModel): id: str """Unique object identifier. The format and length of IDs may change over time. """ created_at: datetime """RFC 3339 datetime string representing when the file was created.""" filename: str """Original filename of the uploaded file.""" mime_type: str """MIME type of the file.""" size_bytes: int """Size of the file in bytes.""" type: Literal["file"] """Object type. For files, this is always `"file"`. """ downloadable: Optional[bool] = None """Whether the file can be downloaded.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/file_upload_params.py000066400000000000000000000011671506653454500267520ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import List from typing_extensions import Required, Annotated, TypedDict from ..._types import FileTypes from ..._utils import PropertyInfo from ..anthropic_beta_param import AnthropicBetaParam __all__ = ["FileUploadParams"] class FileUploadParams(TypedDict, total=False): file: Required[FileTypes] """The file to upload""" betas: Annotated[List[AnthropicBetaParam], PropertyInfo(alias="anthropic-beta")] """Optional header to specify the beta version(s) you want to use.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/message_count_tokens_params.py000066400000000000000000000215351506653454500307070ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import List, Union, Iterable, Optional from typing_extensions import Required, Annotated, TypeAlias, TypedDict from ..._utils import PropertyInfo from ..model_param import ModelParam from .beta_tool_param import BetaToolParam from .beta_message_param import BetaMessageParam from ..anthropic_beta_param import AnthropicBetaParam from .beta_text_block_param import BetaTextBlockParam from .beta_tool_choice_param import BetaToolChoiceParam from .beta_thinking_config_param import BetaThinkingConfigParam from .beta_tool_bash_20241022_param import BetaToolBash20241022Param from .beta_tool_bash_20250124_param import BetaToolBash20250124Param from .beta_memory_tool_20250818_param import BetaMemoryTool20250818Param from .beta_web_fetch_tool_20250910_param import BetaWebFetchTool20250910Param from .beta_web_search_tool_20250305_param import BetaWebSearchTool20250305Param from .beta_context_management_config_param import BetaContextManagementConfigParam from .beta_tool_text_editor_20241022_param import BetaToolTextEditor20241022Param from .beta_tool_text_editor_20250124_param import BetaToolTextEditor20250124Param from .beta_tool_text_editor_20250429_param import BetaToolTextEditor20250429Param from .beta_tool_text_editor_20250728_param import BetaToolTextEditor20250728Param from .beta_tool_computer_use_20241022_param import BetaToolComputerUse20241022Param from .beta_tool_computer_use_20250124_param import BetaToolComputerUse20250124Param from .beta_code_execution_tool_20250522_param import BetaCodeExecutionTool20250522Param from .beta_code_execution_tool_20250825_param import BetaCodeExecutionTool20250825Param from .beta_request_mcp_server_url_definition_param import BetaRequestMCPServerURLDefinitionParam __all__ = ["MessageCountTokensParams", "Tool"] class MessageCountTokensParams(TypedDict, total=False): messages: Required[Iterable[BetaMessageParam]] """Input messages. Our models are trained to operate on alternating `user` and `assistant` conversational turns. When creating a new `Message`, you specify the prior conversational turns with the `messages` parameter, and the model then generates the next `Message` in the conversation. Consecutive `user` or `assistant` turns in your request will be combined into a single turn. Each input message must be an object with a `role` and `content`. You can specify a single `user`-role message, or you can include multiple `user` and `assistant` messages. If the final message uses the `assistant` role, the response content will continue immediately from the content in that message. This can be used to constrain part of the model's response. Example with a single `user` message: ```json [{ "role": "user", "content": "Hello, Claude" }] ``` Example with multiple conversational turns: ```json [ { "role": "user", "content": "Hello there." }, { "role": "assistant", "content": "Hi, I'm Claude. How can I help you?" }, { "role": "user", "content": "Can you explain LLMs in plain English?" } ] ``` Example with a partially-filled response from Claude: ```json [ { "role": "user", "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun" }, { "role": "assistant", "content": "The best answer is (" } ] ``` Each input message `content` may be either a single `string` or an array of content blocks, where each block has a specific `type`. Using a `string` for `content` is shorthand for an array of one content block of type `"text"`. The following input messages are equivalent: ```json { "role": "user", "content": "Hello, Claude" } ``` ```json { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } ``` See [input examples](https://docs.anthropic.com/en/api/messages-examples). Note that if you want to include a [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use the top-level `system` parameter — there is no `"system"` role for input messages in the Messages API. There is a limit of 100,000 messages in a single request. """ model: Required[ModelParam] """ The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. """ context_management: Optional[BetaContextManagementConfigParam] """Configuration for context management operations.""" mcp_servers: Iterable[BetaRequestMCPServerURLDefinitionParam] """MCP servers to be utilized in this request""" system: Union[str, Iterable[BetaTextBlockParam]] """System prompt. A system prompt is a way of providing context and instructions to Claude, such as specifying a particular goal or role. See our [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts). """ thinking: BetaThinkingConfigParam """Configuration for enabling Claude's extended thinking. When enabled, responses include `thinking` content blocks showing Claude's thinking process before the final answer. Requires a minimum budget of 1,024 tokens and counts towards your `max_tokens` limit. See [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) for details. """ tool_choice: BetaToolChoiceParam """How the model should use the provided tools. The model can use a specific tool, any available tool, decide by itself, or not use tools at all. """ tools: Iterable[Tool] """Definitions of tools that the model may use. If you include `tools` in your API request, the model may return `tool_use` content blocks that represent the model's use of those tools. You can then run those tools using the tool input generated by the model and then optionally return results back to the model using `tool_result` content blocks. There are two types of tools: **client tools** and **server tools**. The behavior described below applies to client tools. For [server tools](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#server-tools), see their individual documentation as each has its own behavior (e.g., the [web search tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool)). Each tool definition includes: - `name`: Name of the tool. - `description`: Optional, but strongly-recommended description of the tool. - `input_schema`: [JSON schema](https://json-schema.org/draft/2020-12) for the tool `input` shape that the model will produce in `tool_use` output content blocks. For example, if you defined `tools` as: ```json [ { "name": "get_stock_price", "description": "Get the current stock price for a given ticker symbol.", "input_schema": { "type": "object", "properties": { "ticker": { "type": "string", "description": "The stock ticker symbol, e.g. AAPL for Apple Inc." } }, "required": ["ticker"] } } ] ``` And then asked the model "What's the S&P 500 at today?", the model might produce `tool_use` content blocks in the response like this: ```json [ { "type": "tool_use", "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "name": "get_stock_price", "input": { "ticker": "^GSPC" } } ] ``` You might then run your `get_stock_price` tool with `{"ticker": "^GSPC"}` as an input, and return the following back to the model in a subsequent `user` message: ```json [ { "type": "tool_result", "tool_use_id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "content": "259.75 USD" } ] ``` Tools can be used for workflows that include running client-side tools and functions, or more generally whenever you want the model to produce a particular JSON structure of output. See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. """ betas: Annotated[List[AnthropicBetaParam], PropertyInfo(alias="anthropic-beta")] """Optional header to specify the beta version(s) you want to use.""" Tool: TypeAlias = Union[ BetaToolParam, BetaToolBash20241022Param, BetaToolBash20250124Param, BetaCodeExecutionTool20250522Param, BetaCodeExecutionTool20250825Param, BetaToolComputerUse20241022Param, BetaMemoryTool20250818Param, BetaToolComputerUse20250124Param, BetaToolTextEditor20241022Param, BetaToolTextEditor20250124Param, BetaToolTextEditor20250429Param, BetaToolTextEditor20250728Param, BetaWebSearchTool20250305Param, BetaWebFetchTool20250910Param, ] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/message_create_params.py000066400000000000000000000254271506653454500274430ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import List, Union, Iterable, Optional from typing_extensions import Literal, Required, Annotated, TypedDict from ..._types import SequenceNotStr from ..._utils import PropertyInfo from ..model_param import ModelParam from .beta_message_param import BetaMessageParam from .beta_metadata_param import BetaMetadataParam from ..anthropic_beta_param import AnthropicBetaParam from .beta_text_block_param import BetaTextBlockParam from .beta_tool_union_param import BetaToolUnionParam from .beta_tool_choice_param import BetaToolChoiceParam from .beta_thinking_config_param import BetaThinkingConfigParam from .beta_context_management_config_param import BetaContextManagementConfigParam from .beta_request_mcp_server_url_definition_param import BetaRequestMCPServerURLDefinitionParam __all__ = ["MessageCreateParamsBase", "MessageCreateParamsNonStreaming", "MessageCreateParamsStreaming"] class MessageCreateParamsBase(TypedDict, total=False): max_tokens: Required[int] """The maximum number of tokens to generate before stopping. Note that our models may stop _before_ reaching this maximum. This parameter only specifies the absolute maximum number of tokens to generate. Different models have different maximum values for this parameter. See [models](https://docs.anthropic.com/en/docs/models-overview) for details. """ messages: Required[Iterable[BetaMessageParam]] """Input messages. Our models are trained to operate on alternating `user` and `assistant` conversational turns. When creating a new `Message`, you specify the prior conversational turns with the `messages` parameter, and the model then generates the next `Message` in the conversation. Consecutive `user` or `assistant` turns in your request will be combined into a single turn. Each input message must be an object with a `role` and `content`. You can specify a single `user`-role message, or you can include multiple `user` and `assistant` messages. If the final message uses the `assistant` role, the response content will continue immediately from the content in that message. This can be used to constrain part of the model's response. Example with a single `user` message: ```json [{ "role": "user", "content": "Hello, Claude" }] ``` Example with multiple conversational turns: ```json [ { "role": "user", "content": "Hello there." }, { "role": "assistant", "content": "Hi, I'm Claude. How can I help you?" }, { "role": "user", "content": "Can you explain LLMs in plain English?" } ] ``` Example with a partially-filled response from Claude: ```json [ { "role": "user", "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun" }, { "role": "assistant", "content": "The best answer is (" } ] ``` Each input message `content` may be either a single `string` or an array of content blocks, where each block has a specific `type`. Using a `string` for `content` is shorthand for an array of one content block of type `"text"`. The following input messages are equivalent: ```json { "role": "user", "content": "Hello, Claude" } ``` ```json { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } ``` See [input examples](https://docs.anthropic.com/en/api/messages-examples). Note that if you want to include a [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use the top-level `system` parameter — there is no `"system"` role for input messages in the Messages API. There is a limit of 100,000 messages in a single request. """ model: Required[ModelParam] """ The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. """ container: Optional[str] """Container identifier for reuse across requests.""" context_management: Optional[BetaContextManagementConfigParam] """Configuration for context management operations.""" mcp_servers: Iterable[BetaRequestMCPServerURLDefinitionParam] """MCP servers to be utilized in this request""" metadata: BetaMetadataParam """An object describing metadata about the request.""" service_tier: Literal["auto", "standard_only"] """ Determines whether to use priority capacity (if available) or standard capacity for this request. Anthropic offers different levels of service for your API requests. See [service-tiers](https://docs.anthropic.com/en/api/service-tiers) for details. """ stop_sequences: SequenceNotStr[str] """Custom text sequences that will cause the model to stop generating. Our models will normally stop when they have naturally completed their turn, which will result in a response `stop_reason` of `"end_turn"`. If you want the model to stop generating when it encounters custom strings of text, you can use the `stop_sequences` parameter. If the model encounters one of the custom sequences, the response `stop_reason` value will be `"stop_sequence"` and the response `stop_sequence` value will contain the matched stop sequence. """ system: Union[str, Iterable[BetaTextBlockParam]] """System prompt. A system prompt is a way of providing context and instructions to Claude, such as specifying a particular goal or role. See our [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts). """ temperature: float """Amount of randomness injected into the response. Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0` for analytical / multiple choice, and closer to `1.0` for creative and generative tasks. Note that even with `temperature` of `0.0`, the results will not be fully deterministic. """ thinking: BetaThinkingConfigParam """Configuration for enabling Claude's extended thinking. When enabled, responses include `thinking` content blocks showing Claude's thinking process before the final answer. Requires a minimum budget of 1,024 tokens and counts towards your `max_tokens` limit. See [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) for details. """ tool_choice: BetaToolChoiceParam """How the model should use the provided tools. The model can use a specific tool, any available tool, decide by itself, or not use tools at all. """ tools: Iterable[BetaToolUnionParam] """Definitions of tools that the model may use. If you include `tools` in your API request, the model may return `tool_use` content blocks that represent the model's use of those tools. You can then run those tools using the tool input generated by the model and then optionally return results back to the model using `tool_result` content blocks. There are two types of tools: **client tools** and **server tools**. The behavior described below applies to client tools. For [server tools](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#server-tools), see their individual documentation as each has its own behavior (e.g., the [web search tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool)). Each tool definition includes: - `name`: Name of the tool. - `description`: Optional, but strongly-recommended description of the tool. - `input_schema`: [JSON schema](https://json-schema.org/draft/2020-12) for the tool `input` shape that the model will produce in `tool_use` output content blocks. For example, if you defined `tools` as: ```json [ { "name": "get_stock_price", "description": "Get the current stock price for a given ticker symbol.", "input_schema": { "type": "object", "properties": { "ticker": { "type": "string", "description": "The stock ticker symbol, e.g. AAPL for Apple Inc." } }, "required": ["ticker"] } } ] ``` And then asked the model "What's the S&P 500 at today?", the model might produce `tool_use` content blocks in the response like this: ```json [ { "type": "tool_use", "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "name": "get_stock_price", "input": { "ticker": "^GSPC" } } ] ``` You might then run your `get_stock_price` tool with `{"ticker": "^GSPC"}` as an input, and return the following back to the model in a subsequent `user` message: ```json [ { "type": "tool_result", "tool_use_id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "content": "259.75 USD" } ] ``` Tools can be used for workflows that include running client-side tools and functions, or more generally whenever you want the model to produce a particular JSON structure of output. See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. """ top_k: int """Only sample from the top K options for each subsequent token. Used to remove "long tail" low probability responses. [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277). Recommended for advanced use cases only. You usually only need to use `temperature`. """ top_p: float """Use nucleus sampling. In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by `top_p`. You should either alter `temperature` or `top_p`, but not both. Recommended for advanced use cases only. You usually only need to use `temperature`. """ betas: Annotated[List[AnthropicBetaParam], PropertyInfo(alias="anthropic-beta")] """Optional header to specify the beta version(s) you want to use.""" class MessageCreateParamsNonStreaming(MessageCreateParamsBase, total=False): stream: Literal[False] """Whether to incrementally stream the response using server-sent events. See [streaming](https://docs.anthropic.com/en/api/messages-streaming) for details. """ class MessageCreateParamsStreaming(MessageCreateParamsBase): stream: Required[Literal[True]] """Whether to incrementally stream the response using server-sent events. See [streaming](https://docs.anthropic.com/en/api/messages-streaming) for details. """ MessageCreateParams = Union[MessageCreateParamsNonStreaming, MessageCreateParamsStreaming] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/messages/000077500000000000000000000000001506653454500243545ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/types/beta/messages/__init__.py000066400000000000000000000022621506653454500264670ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from .batch_list_params import BatchListParams as BatchListParams from .beta_message_batch import BetaMessageBatch as BetaMessageBatch from .batch_create_params import BatchCreateParams as BatchCreateParams from .beta_message_batch_result import BetaMessageBatchResult as BetaMessageBatchResult from .beta_deleted_message_batch import BetaDeletedMessageBatch as BetaDeletedMessageBatch from .beta_message_batch_errored_result import BetaMessageBatchErroredResult as BetaMessageBatchErroredResult from .beta_message_batch_expired_result import BetaMessageBatchExpiredResult as BetaMessageBatchExpiredResult from .beta_message_batch_request_counts import BetaMessageBatchRequestCounts as BetaMessageBatchRequestCounts from .beta_message_batch_canceled_result import BetaMessageBatchCanceledResult as BetaMessageBatchCanceledResult from .beta_message_batch_succeeded_result import BetaMessageBatchSucceededResult as BetaMessageBatchSucceededResult from .beta_message_batch_individual_response import ( BetaMessageBatchIndividualResponse as BetaMessageBatchIndividualResponse, ) anthropic-sdk-python-0.69.0/src/anthropic/types/beta/messages/batch_create_params.py000066400000000000000000000024701506653454500307000ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import List, Iterable from typing_extensions import Required, Annotated, TypedDict from ...._utils import PropertyInfo from ...anthropic_beta_param import AnthropicBetaParam from ..message_create_params import MessageCreateParamsNonStreaming __all__ = ["BatchCreateParams", "Request"] class BatchCreateParams(TypedDict, total=False): requests: Required[Iterable[Request]] """List of requests for prompt completion. Each is an individual request to create a Message. """ betas: Annotated[List[AnthropicBetaParam], PropertyInfo(alias="anthropic-beta")] """Optional header to specify the beta version(s) you want to use.""" class Request(TypedDict, total=False): custom_id: Required[str] """Developer-provided ID created for each request in a Message Batch. Useful for matching results to requests, as results may be given out of request order. Must be unique for each request within the Message Batch. """ params: Required[MessageCreateParamsNonStreaming] """Messages API creation parameters for the individual request. See the [Messages API reference](/en/api/messages) for full documentation on available parameters. """ anthropic-sdk-python-0.69.0/src/anthropic/types/beta/messages/batch_list_params.py000066400000000000000000000017221506653454500304070ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import List from typing_extensions import Annotated, TypedDict from ...._utils import PropertyInfo from ...anthropic_beta_param import AnthropicBetaParam __all__ = ["BatchListParams"] class BatchListParams(TypedDict, total=False): after_id: str """ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately after this object. """ before_id: str """ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately before this object. """ limit: int """Number of items to return per page. Defaults to `20`. Ranges from `1` to `1000`. """ betas: Annotated[List[AnthropicBetaParam], PropertyInfo(alias="anthropic-beta")] """Optional header to specify the beta version(s) you want to use.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta/messages/beta_deleted_message_batch.py000066400000000000000000000006661506653454500322040ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ...._models import BaseModel __all__ = ["BetaDeletedMessageBatch"] class BetaDeletedMessageBatch(BaseModel): id: str """ID of the Message Batch.""" type: Literal["message_batch_deleted"] """Deleted object type. For Message Batches, this is always `"message_batch_deleted"`. """ anthropic-sdk-python-0.69.0/src/anthropic/types/beta/messages/beta_message_batch.py000066400000000000000000000046051506653454500305130ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from datetime import datetime from typing_extensions import Literal from ...._models import BaseModel from .beta_message_batch_request_counts import BetaMessageBatchRequestCounts __all__ = ["BetaMessageBatch"] class BetaMessageBatch(BaseModel): id: str """Unique object identifier. The format and length of IDs may change over time. """ archived_at: Optional[datetime] = None """ RFC 3339 datetime string representing the time at which the Message Batch was archived and its results became unavailable. """ cancel_initiated_at: Optional[datetime] = None """ RFC 3339 datetime string representing the time at which cancellation was initiated for the Message Batch. Specified only if cancellation was initiated. """ created_at: datetime """ RFC 3339 datetime string representing the time at which the Message Batch was created. """ ended_at: Optional[datetime] = None """ RFC 3339 datetime string representing the time at which processing for the Message Batch ended. Specified only once processing ends. Processing ends when every request in a Message Batch has either succeeded, errored, canceled, or expired. """ expires_at: datetime """ RFC 3339 datetime string representing the time at which the Message Batch will expire and end processing, which is 24 hours after creation. """ processing_status: Literal["in_progress", "canceling", "ended"] """Processing status of the Message Batch.""" request_counts: BetaMessageBatchRequestCounts """Tallies requests within the Message Batch, categorized by their status. Requests start as `processing` and move to one of the other statuses only once processing of the entire batch ends. The sum of all values always matches the total number of requests in the batch. """ results_url: Optional[str] = None """URL to a `.jsonl` file containing the results of the Message Batch requests. Specified only once processing ends. Results in the file are not guaranteed to be in the same order as requests. Use the `custom_id` field to match results to requests. """ type: Literal["message_batch"] """Object type. For Message Batches, this is always `"message_batch"`. """ anthropic-sdk-python-0.69.0/src/anthropic/types/beta/messages/beta_message_batch_canceled_result.py000066400000000000000000000004371506653454500337260ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ...._models import BaseModel __all__ = ["BetaMessageBatchCanceledResult"] class BetaMessageBatchCanceledResult(BaseModel): type: Literal["canceled"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/messages/beta_message_batch_errored_result.py000066400000000000000000000005571506653454500336350ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ...._models import BaseModel from ...beta_error_response import BetaErrorResponse __all__ = ["BetaMessageBatchErroredResult"] class BetaMessageBatchErroredResult(BaseModel): error: BetaErrorResponse type: Literal["errored"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/messages/beta_message_batch_expired_result.py000066400000000000000000000004341506653454500336250ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ...._models import BaseModel __all__ = ["BetaMessageBatchExpiredResult"] class BetaMessageBatchExpiredResult(BaseModel): type: Literal["expired"] beta_message_batch_individual_response.py000066400000000000000000000014741506653454500345630ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/types/beta/messages# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from ...._models import BaseModel from .beta_message_batch_result import BetaMessageBatchResult __all__ = ["BetaMessageBatchIndividualResponse"] class BetaMessageBatchIndividualResponse(BaseModel): custom_id: str """Developer-provided ID created for each request in a Message Batch. Useful for matching results to requests, as results may be given out of request order. Must be unique for each request within the Message Batch. """ result: BetaMessageBatchResult """Processing result for this request. Contains a Message output if processing was successful, an error response if processing failed, or the reason why processing was not attempted, such as cancellation or expiration. """ anthropic-sdk-python-0.69.0/src/anthropic/types/beta/messages/beta_message_batch_request_counts.py000066400000000000000000000017531506653454500336570ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from ...._models import BaseModel __all__ = ["BetaMessageBatchRequestCounts"] class BetaMessageBatchRequestCounts(BaseModel): canceled: int """Number of requests in the Message Batch that have been canceled. This is zero until processing of the entire Message Batch has ended. """ errored: int """Number of requests in the Message Batch that encountered an error. This is zero until processing of the entire Message Batch has ended. """ expired: int """Number of requests in the Message Batch that have expired. This is zero until processing of the entire Message Batch has ended. """ processing: int """Number of requests in the Message Batch that are processing.""" succeeded: int """Number of requests in the Message Batch that have completed successfully. This is zero until processing of the entire Message Batch has ended. """ anthropic-sdk-python-0.69.0/src/anthropic/types/beta/messages/beta_message_batch_result.py000066400000000000000000000014631506653454500321100ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Union from typing_extensions import Annotated, TypeAlias from ...._utils import PropertyInfo from .beta_message_batch_errored_result import BetaMessageBatchErroredResult from .beta_message_batch_expired_result import BetaMessageBatchExpiredResult from .beta_message_batch_canceled_result import BetaMessageBatchCanceledResult from .beta_message_batch_succeeded_result import BetaMessageBatchSucceededResult __all__ = ["BetaMessageBatchResult"] BetaMessageBatchResult: TypeAlias = Annotated[ Union[ BetaMessageBatchSucceededResult, BetaMessageBatchErroredResult, BetaMessageBatchCanceledResult, BetaMessageBatchExpiredResult, ], PropertyInfo(discriminator="type"), ] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/messages/beta_message_batch_succeeded_result.py000066400000000000000000000005431506653454500341120ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ...._models import BaseModel from ..beta_message import BetaMessage __all__ = ["BetaMessageBatchSucceededResult"] class BetaMessageBatchSucceededResult(BaseModel): message: BetaMessage type: Literal["succeeded"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta/model_list_params.py000066400000000000000000000017201506653454500266150ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import List from typing_extensions import Annotated, TypedDict from ..._utils import PropertyInfo from ..anthropic_beta_param import AnthropicBetaParam __all__ = ["ModelListParams"] class ModelListParams(TypedDict, total=False): after_id: str """ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately after this object. """ before_id: str """ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately before this object. """ limit: int """Number of items to return per page. Defaults to `20`. Ranges from `1` to `1000`. """ betas: Annotated[List[AnthropicBetaParam], PropertyInfo(alias="anthropic-beta")] """Optional header to specify the beta version(s) you want to use.""" anthropic-sdk-python-0.69.0/src/anthropic/types/beta_api_error.py000066400000000000000000000004141506653454500251600ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from .._models import BaseModel __all__ = ["BetaAPIError"] class BetaAPIError(BaseModel): message: str type: Literal["api_error"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta_authentication_error.py000066400000000000000000000004551506653454500274330ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from .._models import BaseModel __all__ = ["BetaAuthenticationError"] class BetaAuthenticationError(BaseModel): message: str type: Literal["authentication_error"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta_billing_error.py000066400000000000000000000004301506653454500260250ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from .._models import BaseModel __all__ = ["BetaBillingError"] class BetaBillingError(BaseModel): message: str type: Literal["billing_error"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta_error.py000066400000000000000000000020631506653454500243310ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Union from typing_extensions import Annotated, TypeAlias from .._utils import PropertyInfo from .beta_api_error import BetaAPIError from .beta_billing_error import BetaBillingError from .beta_not_found_error import BetaNotFoundError from .beta_overloaded_error import BetaOverloadedError from .beta_permission_error import BetaPermissionError from .beta_rate_limit_error import BetaRateLimitError from .beta_authentication_error import BetaAuthenticationError from .beta_gateway_timeout_error import BetaGatewayTimeoutError from .beta_invalid_request_error import BetaInvalidRequestError __all__ = ["BetaError"] BetaError: TypeAlias = Annotated[ Union[ BetaInvalidRequestError, BetaAuthenticationError, BetaBillingError, BetaPermissionError, BetaNotFoundError, BetaRateLimitError, BetaGatewayTimeoutError, BetaAPIError, BetaOverloadedError, ], PropertyInfo(discriminator="type"), ] anthropic-sdk-python-0.69.0/src/anthropic/types/beta_error_response.py000066400000000000000000000005721506653454500262520ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from typing_extensions import Literal from .._models import BaseModel from .beta_error import BetaError __all__ = ["BetaErrorResponse"] class BetaErrorResponse(BaseModel): error: BetaError request_id: Optional[str] = None type: Literal["error"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta_gateway_timeout_error.py000066400000000000000000000004461506653454500276230ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from .._models import BaseModel __all__ = ["BetaGatewayTimeoutError"] class BetaGatewayTimeoutError(BaseModel): message: str type: Literal["timeout_error"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta_invalid_request_error.py000066400000000000000000000004561506653454500276130ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from .._models import BaseModel __all__ = ["BetaInvalidRequestError"] class BetaInvalidRequestError(BaseModel): message: str type: Literal["invalid_request_error"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta_not_found_error.py000066400000000000000000000004341506653454500264040ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from .._models import BaseModel __all__ = ["BetaNotFoundError"] class BetaNotFoundError(BaseModel): message: str type: Literal["not_found_error"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta_overloaded_error.py000066400000000000000000000004411506653454500265330ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from .._models import BaseModel __all__ = ["BetaOverloadedError"] class BetaOverloadedError(BaseModel): message: str type: Literal["overloaded_error"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta_permission_error.py000066400000000000000000000004411506653454500265770ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from .._models import BaseModel __all__ = ["BetaPermissionError"] class BetaPermissionError(BaseModel): message: str type: Literal["permission_error"] anthropic-sdk-python-0.69.0/src/anthropic/types/beta_rate_limit_error.py000066400000000000000000000004371506653454500265450ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from .._models import BaseModel __all__ = ["BetaRateLimitError"] class BetaRateLimitError(BaseModel): message: str type: Literal["rate_limit_error"] anthropic-sdk-python-0.69.0/src/anthropic/types/cache_control_ephemeral_param.py000066400000000000000000000010211506653454500302030ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["CacheControlEphemeralParam"] class CacheControlEphemeralParam(TypedDict, total=False): type: Required[Literal["ephemeral"]] ttl: Literal["5m", "1h"] """The time-to-live for the cache control breakpoint. This may be one the following values: - `5m`: 5 minutes - `1h`: 1 hour Defaults to `5m`. """ anthropic-sdk-python-0.69.0/src/anthropic/types/cache_creation.py000066400000000000000000000006271506653454500251400ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from .._models import BaseModel __all__ = ["CacheCreation"] class CacheCreation(BaseModel): ephemeral_1h_input_tokens: int """The number of input tokens used to create the 1 hour cache entry.""" ephemeral_5m_input_tokens: int """The number of input tokens used to create the 5 minute cache entry.""" anthropic-sdk-python-0.69.0/src/anthropic/types/citation_char_location.py000066400000000000000000000007311506653454500267040ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from typing_extensions import Literal from .._models import BaseModel __all__ = ["CitationCharLocation"] class CitationCharLocation(BaseModel): cited_text: str document_index: int document_title: Optional[str] = None end_char_index: int file_id: Optional[str] = None start_char_index: int type: Literal["char_location"] anthropic-sdk-python-0.69.0/src/anthropic/types/citation_char_location_param.py000066400000000000000000000010321506653454500300570ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict __all__ = ["CitationCharLocationParam"] class CitationCharLocationParam(TypedDict, total=False): cited_text: Required[str] document_index: Required[int] document_title: Required[Optional[str]] end_char_index: Required[int] start_char_index: Required[int] type: Required[Literal["char_location"]] anthropic-sdk-python-0.69.0/src/anthropic/types/citation_content_block_location.py000066400000000000000000000007641506653454500306210ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from typing_extensions import Literal from .._models import BaseModel __all__ = ["CitationContentBlockLocation"] class CitationContentBlockLocation(BaseModel): cited_text: str document_index: int document_title: Optional[str] = None end_block_index: int file_id: Optional[str] = None start_block_index: int type: Literal["content_block_location"] anthropic-sdk-python-0.69.0/src/anthropic/types/citation_content_block_location_param.py000066400000000000000000000010651506653454500317740ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict __all__ = ["CitationContentBlockLocationParam"] class CitationContentBlockLocationParam(TypedDict, total=False): cited_text: Required[str] document_index: Required[int] document_title: Required[Optional[str]] end_block_index: Required[int] start_block_index: Required[int] type: Required[Literal["content_block_location"]] anthropic-sdk-python-0.69.0/src/anthropic/types/citation_page_location.py000066400000000000000000000007331506653454500267050ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from typing_extensions import Literal from .._models import BaseModel __all__ = ["CitationPageLocation"] class CitationPageLocation(BaseModel): cited_text: str document_index: int document_title: Optional[str] = None end_page_number: int file_id: Optional[str] = None start_page_number: int type: Literal["page_location"] anthropic-sdk-python-0.69.0/src/anthropic/types/citation_page_location_param.py000066400000000000000000000010341506653454500300600ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict __all__ = ["CitationPageLocationParam"] class CitationPageLocationParam(TypedDict, total=False): cited_text: Required[str] document_index: Required[int] document_title: Required[Optional[str]] end_page_number: Required[int] start_page_number: Required[int] type: Required[Literal["page_location"]] anthropic-sdk-python-0.69.0/src/anthropic/types/citation_search_result_location_param.py000066400000000000000000000011141506653454500320060ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict __all__ = ["CitationSearchResultLocationParam"] class CitationSearchResultLocationParam(TypedDict, total=False): cited_text: Required[str] end_block_index: Required[int] search_result_index: Required[int] source: Required[str] start_block_index: Required[int] title: Required[Optional[str]] type: Required[Literal["search_result_location"]] anthropic-sdk-python-0.69.0/src/anthropic/types/citation_web_search_result_location_param.py000066400000000000000000000010051506653454500326420ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict __all__ = ["CitationWebSearchResultLocationParam"] class CitationWebSearchResultLocationParam(TypedDict, total=False): cited_text: Required[str] encrypted_index: Required[str] title: Required[Optional[str]] type: Required[Literal["web_search_result_location"]] url: Required[str] anthropic-sdk-python-0.69.0/src/anthropic/types/citations_config_param.py000066400000000000000000000004171506653454500267100ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import TypedDict __all__ = ["CitationsConfigParam"] class CitationsConfigParam(TypedDict, total=False): enabled: bool anthropic-sdk-python-0.69.0/src/anthropic/types/citations_delta.py000066400000000000000000000017451506653454500253610ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Union from typing_extensions import Literal, Annotated, TypeAlias from .._utils import PropertyInfo from .._models import BaseModel from .citation_char_location import CitationCharLocation from .citation_page_location import CitationPageLocation from .citation_content_block_location import CitationContentBlockLocation from .citations_search_result_location import CitationsSearchResultLocation from .citations_web_search_result_location import CitationsWebSearchResultLocation __all__ = ["CitationsDelta", "Citation"] Citation: TypeAlias = Annotated[ Union[ CitationCharLocation, CitationPageLocation, CitationContentBlockLocation, CitationsWebSearchResultLocation, CitationsSearchResultLocation, ], PropertyInfo(discriminator="type"), ] class CitationsDelta(BaseModel): citation: Citation type: Literal["citations_delta"] anthropic-sdk-python-0.69.0/src/anthropic/types/citations_search_result_location.py000066400000000000000000000007401506653454500310150ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from typing_extensions import Literal from .._models import BaseModel __all__ = ["CitationsSearchResultLocation"] class CitationsSearchResultLocation(BaseModel): cited_text: str end_block_index: int search_result_index: int source: str start_block_index: int title: Optional[str] = None type: Literal["search_result_location"] anthropic-sdk-python-0.69.0/src/anthropic/types/citations_web_search_result_location.py000066400000000000000000000006551506653454500316570ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from typing_extensions import Literal from .._models import BaseModel __all__ = ["CitationsWebSearchResultLocation"] class CitationsWebSearchResultLocation(BaseModel): cited_text: str encrypted_index: str title: Optional[str] = None type: Literal["web_search_result_location"] url: str anthropic-sdk-python-0.69.0/src/anthropic/types/completion.py000066400000000000000000000021771506653454500243640ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from typing_extensions import Literal from .model import Model from .._models import BaseModel __all__ = ["Completion"] class Completion(BaseModel): id: str """Unique object identifier. The format and length of IDs may change over time. """ completion: str """The resulting completion up to and excluding the stop sequences.""" model: Model """ The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. """ stop_reason: Optional[str] = None """The reason that we stopped. This may be one the following values: - `"stop_sequence"`: we reached a stop sequence — either provided by you via the `stop_sequences` parameter, or a stop sequence built into the model - `"max_tokens"`: we exceeded `max_tokens_to_sample` or the model's maximum """ type: Literal["completion"] """Object type. For Text Completions, this is always `"completion"`. """ anthropic-sdk-python-0.69.0/src/anthropic/types/completion_create_params.py000066400000000000000000000113671506653454500272530ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import List, Union from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict from .._types import SequenceNotStr from .._utils import PropertyInfo from .model_param import ModelParam from .metadata_param import MetadataParam from .anthropic_beta_param import AnthropicBetaParam __all__ = [ "CompletionRequestStreamingMetadata", "CompletionRequestNonStreamingMetadata", "CompletionRequestNonStreaming", "CompletionRequestStreaming", "CompletionCreateParamsBase", "Metadata", "CompletionCreateParamsNonStreaming", "CompletionCreateParamsStreaming", ] class CompletionCreateParamsBase(TypedDict, total=False): max_tokens_to_sample: Required[int] """The maximum number of tokens to generate before stopping. Note that our models may stop _before_ reaching this maximum. This parameter only specifies the absolute maximum number of tokens to generate. """ model: Required[ModelParam] """ The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. """ prompt: Required[str] """The prompt that you want Claude to complete. For proper response generation you will need to format your prompt using alternating `\n\nHuman:` and `\n\nAssistant:` conversational turns. For example: ``` "\n\nHuman: {userQuestion}\n\nAssistant:" ``` See [prompt validation](https://docs.anthropic.com/en/api/prompt-validation) and our guide to [prompt design](https://docs.anthropic.com/en/docs/intro-to-prompting) for more details. """ metadata: MetadataParam """An object describing metadata about the request.""" stop_sequences: SequenceNotStr[str] """Sequences that will cause the model to stop generating. Our models stop on `"\n\nHuman:"`, and may include additional built-in stop sequences in the future. By providing the stop_sequences parameter, you may include additional strings that will cause the model to stop generating. """ temperature: float """Amount of randomness injected into the response. Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0` for analytical / multiple choice, and closer to `1.0` for creative and generative tasks. Note that even with `temperature` of `0.0`, the results will not be fully deterministic. """ top_k: int """Only sample from the top K options for each subsequent token. Used to remove "long tail" low probability responses. [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277). Recommended for advanced use cases only. You usually only need to use `temperature`. """ top_p: float """Use nucleus sampling. In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by `top_p`. You should either alter `temperature` or `top_p`, but not both. Recommended for advanced use cases only. You usually only need to use `temperature`. """ betas: Annotated[List[AnthropicBetaParam], PropertyInfo(alias="anthropic-beta")] """Optional header to specify the beta version(s) you want to use.""" Metadata: TypeAlias = MetadataParam """This is deprecated, `MetadataParam` should be used instead""" class CompletionCreateParamsNonStreaming(CompletionCreateParamsBase, total=False): stream: Literal[False] """Whether to incrementally stream the response using server-sent events. See [streaming](https://docs.anthropic.com/en/api/streaming) for details. """ class CompletionCreateParamsStreaming(CompletionCreateParamsBase): stream: Required[Literal[True]] """Whether to incrementally stream the response using server-sent events. See [streaming](https://docs.anthropic.com/en/api/streaming) for details. """ CompletionRequestStreamingMetadata = MetadataParam """This is deprecated, `MetadataParam` should be used instead""" CompletionRequestNonStreamingMetadata = MetadataParam """This is deprecated, `MetadataParam` should be used instead""" CompletionRequestNonStreaming = CompletionCreateParamsNonStreaming """This is deprecated, `CompletionCreateParamsNonStreaming` should be used instead""" CompletionRequestStreaming = CompletionCreateParamsStreaming """This is deprecated, `CompletionCreateParamsStreaming` should be used instead""" CompletionCreateParams = Union[CompletionCreateParamsNonStreaming, CompletionCreateParamsStreaming] anthropic-sdk-python-0.69.0/src/anthropic/types/content_block.py000066400000000000000000000013231506653454500250270ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Union from typing_extensions import Annotated, TypeAlias from .._utils import PropertyInfo from .text_block import TextBlock from .thinking_block import ThinkingBlock from .tool_use_block import ToolUseBlock from .server_tool_use_block import ServerToolUseBlock from .redacted_thinking_block import RedactedThinkingBlock from .web_search_tool_result_block import WebSearchToolResultBlock __all__ = ["ContentBlock"] ContentBlock: TypeAlias = Annotated[ Union[TextBlock, ThinkingBlock, RedactedThinkingBlock, ToolUseBlock, ServerToolUseBlock, WebSearchToolResultBlock], PropertyInfo(discriminator="type"), ] anthropic-sdk-python-0.69.0/src/anthropic/types/content_block_delta_event.py000066400000000000000000000004661506653454500274100ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from .raw_content_block_delta_event import RawContentBlockDeltaEvent __all__ = ["ContentBlockDeltaEvent"] ContentBlockDeltaEvent = RawContentBlockDeltaEvent """The RawContentBlockDeltaEvent type should be used instead""" anthropic-sdk-python-0.69.0/src/anthropic/types/content_block_param.py000066400000000000000000000021241506653454500262070ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union from typing_extensions import TypeAlias from .text_block_param import TextBlockParam from .image_block_param import ImageBlockParam from .document_block_param import DocumentBlockParam from .thinking_block_param import ThinkingBlockParam from .tool_use_block_param import ToolUseBlockParam from .tool_result_block_param import ToolResultBlockParam from .search_result_block_param import SearchResultBlockParam from .server_tool_use_block_param import ServerToolUseBlockParam from .redacted_thinking_block_param import RedactedThinkingBlockParam from .web_search_tool_result_block_param import WebSearchToolResultBlockParam __all__ = ["ContentBlockParam"] ContentBlockParam: TypeAlias = Union[ TextBlockParam, ImageBlockParam, DocumentBlockParam, SearchResultBlockParam, ThinkingBlockParam, RedactedThinkingBlockParam, ToolUseBlockParam, ToolResultBlockParam, ServerToolUseBlockParam, WebSearchToolResultBlockParam, ] anthropic-sdk-python-0.69.0/src/anthropic/types/content_block_source_content_param.py000066400000000000000000000006331506653454500313240ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union from typing_extensions import TypeAlias from .text_block_param import TextBlockParam from .image_block_param import ImageBlockParam __all__ = ["ContentBlockSourceContentParam"] ContentBlockSourceContentParam: TypeAlias = Union[TextBlockParam, ImageBlockParam] anthropic-sdk-python-0.69.0/src/anthropic/types/content_block_source_param.py000066400000000000000000000007751506653454500276010ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union, Iterable from typing_extensions import Literal, Required, TypedDict from .content_block_source_content_param import ContentBlockSourceContentParam __all__ = ["ContentBlockSourceParam"] class ContentBlockSourceParam(TypedDict, total=False): content: Required[Union[str, Iterable[ContentBlockSourceContentParam]]] type: Required[Literal["content"]] anthropic-sdk-python-0.69.0/src/anthropic/types/content_block_start_event.py000066400000000000000000000004661506653454500274540ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from .raw_content_block_start_event import RawContentBlockStartEvent __all__ = ["ContentBlockStartEvent"] ContentBlockStartEvent = RawContentBlockStartEvent """The RawContentBlockStartEvent type should be used instead""" anthropic-sdk-python-0.69.0/src/anthropic/types/content_block_stop_event.py000066400000000000000000000004601506653454500272760ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from .raw_content_block_stop_event import RawContentBlockStopEvent __all__ = ["ContentBlockStopEvent"] ContentBlockStopEvent = RawContentBlockStopEvent """The RawContentBlockStopEvent type should be used instead""" anthropic-sdk-python-0.69.0/src/anthropic/types/document_block_param.py000066400000000000000000000021061506653454500263530ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union, Optional from typing_extensions import Literal, Required, TypeAlias, TypedDict from .url_pdf_source_param import URLPDFSourceParam from .citations_config_param import CitationsConfigParam from .base64_pdf_source_param import Base64PDFSourceParam from .plain_text_source_param import PlainTextSourceParam from .content_block_source_param import ContentBlockSourceParam from .cache_control_ephemeral_param import CacheControlEphemeralParam __all__ = ["DocumentBlockParam", "Source"] Source: TypeAlias = Union[Base64PDFSourceParam, PlainTextSourceParam, ContentBlockSourceParam, URLPDFSourceParam] class DocumentBlockParam(TypedDict, total=False): source: Required[Source] type: Required[Literal["document"]] cache_control: Optional[CacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" citations: Optional[CitationsConfigParam] context: Optional[str] title: Optional[str] anthropic-sdk-python-0.69.0/src/anthropic/types/image_block_param.py000066400000000000000000000014021506653454500256150ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union, Optional from typing_extensions import Literal, Required, TypeAlias, TypedDict from .url_image_source_param import URLImageSourceParam from .base64_image_source_param import Base64ImageSourceParam from .cache_control_ephemeral_param import CacheControlEphemeralParam __all__ = ["ImageBlockParam", "Source"] Source: TypeAlias = Union[Base64ImageSourceParam, URLImageSourceParam] class ImageBlockParam(TypedDict, total=False): source: Required[Source] type: Required[Literal["image"]] cache_control: Optional[CacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" anthropic-sdk-python-0.69.0/src/anthropic/types/input_json_delta.py000066400000000000000000000005201506653454500255420ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from .._models import BaseModel __all__ = ["InputJSONDelta", "InputJsonDelta"] class InputJSONDelta(BaseModel): partial_json: str type: Literal["input_json_delta"] InputJsonDelta = InputJSONDelta anthropic-sdk-python-0.69.0/src/anthropic/types/message.py000066400000000000000000000067121506653454500236360ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import List, Optional from typing_extensions import Literal from .model import Model from .usage import Usage from .._models import BaseModel from .stop_reason import StopReason from .content_block import ContentBlock, ContentBlock as ContentBlock __all__ = ["Message"] class Message(BaseModel): id: str """Unique object identifier. The format and length of IDs may change over time. """ content: List[ContentBlock] """Content generated by the model. This is an array of content blocks, each of which has a `type` that determines its shape. Example: ```json [{ "type": "text", "text": "Hi, I'm Claude." }] ``` If the request input `messages` ended with an `assistant` turn, then the response `content` will continue directly from that last turn. You can use this to constrain the model's output. For example, if the input `messages` were: ```json [ { "role": "user", "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun" }, { "role": "assistant", "content": "The best answer is (" } ] ``` Then the response `content` might be: ```json [{ "type": "text", "text": "B)" }] ``` """ model: Model """ The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. """ role: Literal["assistant"] """Conversational role of the generated message. This will always be `"assistant"`. """ stop_reason: Optional[StopReason] = None """The reason that we stopped. This may be one the following values: - `"end_turn"`: the model reached a natural stopping point - `"max_tokens"`: we exceeded the requested `max_tokens` or the model's maximum - `"stop_sequence"`: one of your provided custom `stop_sequences` was generated - `"tool_use"`: the model invoked one or more tools - `"pause_turn"`: we paused a long-running turn. You may provide the response back as-is in a subsequent request to let the model continue. - `"refusal"`: when streaming classifiers intervene to handle potential policy violations In non-streaming mode this value is always non-null. In streaming mode, it is null in the `message_start` event and non-null otherwise. """ stop_sequence: Optional[str] = None """Which custom stop sequence was generated, if any. This value will be a non-null string if one of your custom stop sequences was generated. """ type: Literal["message"] """Object type. For Messages, this is always `"message"`. """ usage: Usage """Billing and rate-limit usage. Anthropic's API bills and rate-limits by token counts, as tokens represent the underlying cost to our systems. Under the hood, the API transforms requests into a format suitable for the model. The model's output then goes through a parsing stage before becoming an API response. As a result, the token counts in `usage` will not match one-to-one with the exact visible content of an API request or response. For example, `output_tokens` will be non-zero, even for an empty string response from Claude. Total input tokens in a request is the summation of `input_tokens`, `cache_creation_input_tokens`, and `cache_read_input_tokens`. """ anthropic-sdk-python-0.69.0/src/anthropic/types/message_count_tokens_params.py000066400000000000000000000151641506653454500277750ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union, Iterable from typing_extensions import Required, TypedDict from .model_param import ModelParam from .message_param import MessageParam from .text_block_param import TextBlockParam from .tool_choice_param import ToolChoiceParam from .thinking_config_param import ThinkingConfigParam from .message_count_tokens_tool_param import MessageCountTokensToolParam __all__ = ["MessageCountTokensParams"] class MessageCountTokensParams(TypedDict, total=False): messages: Required[Iterable[MessageParam]] """Input messages. Our models are trained to operate on alternating `user` and `assistant` conversational turns. When creating a new `Message`, you specify the prior conversational turns with the `messages` parameter, and the model then generates the next `Message` in the conversation. Consecutive `user` or `assistant` turns in your request will be combined into a single turn. Each input message must be an object with a `role` and `content`. You can specify a single `user`-role message, or you can include multiple `user` and `assistant` messages. If the final message uses the `assistant` role, the response content will continue immediately from the content in that message. This can be used to constrain part of the model's response. Example with a single `user` message: ```json [{ "role": "user", "content": "Hello, Claude" }] ``` Example with multiple conversational turns: ```json [ { "role": "user", "content": "Hello there." }, { "role": "assistant", "content": "Hi, I'm Claude. How can I help you?" }, { "role": "user", "content": "Can you explain LLMs in plain English?" } ] ``` Example with a partially-filled response from Claude: ```json [ { "role": "user", "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun" }, { "role": "assistant", "content": "The best answer is (" } ] ``` Each input message `content` may be either a single `string` or an array of content blocks, where each block has a specific `type`. Using a `string` for `content` is shorthand for an array of one content block of type `"text"`. The following input messages are equivalent: ```json { "role": "user", "content": "Hello, Claude" } ``` ```json { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } ``` See [input examples](https://docs.anthropic.com/en/api/messages-examples). Note that if you want to include a [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use the top-level `system` parameter — there is no `"system"` role for input messages in the Messages API. There is a limit of 100,000 messages in a single request. """ model: Required[ModelParam] """ The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. """ system: Union[str, Iterable[TextBlockParam]] """System prompt. A system prompt is a way of providing context and instructions to Claude, such as specifying a particular goal or role. See our [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts). """ thinking: ThinkingConfigParam """Configuration for enabling Claude's extended thinking. When enabled, responses include `thinking` content blocks showing Claude's thinking process before the final answer. Requires a minimum budget of 1,024 tokens and counts towards your `max_tokens` limit. See [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) for details. """ tool_choice: ToolChoiceParam """How the model should use the provided tools. The model can use a specific tool, any available tool, decide by itself, or not use tools at all. """ tools: Iterable[MessageCountTokensToolParam] """Definitions of tools that the model may use. If you include `tools` in your API request, the model may return `tool_use` content blocks that represent the model's use of those tools. You can then run those tools using the tool input generated by the model and then optionally return results back to the model using `tool_result` content blocks. There are two types of tools: **client tools** and **server tools**. The behavior described below applies to client tools. For [server tools](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#server-tools), see their individual documentation as each has its own behavior (e.g., the [web search tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool)). Each tool definition includes: - `name`: Name of the tool. - `description`: Optional, but strongly-recommended description of the tool. - `input_schema`: [JSON schema](https://json-schema.org/draft/2020-12) for the tool `input` shape that the model will produce in `tool_use` output content blocks. For example, if you defined `tools` as: ```json [ { "name": "get_stock_price", "description": "Get the current stock price for a given ticker symbol.", "input_schema": { "type": "object", "properties": { "ticker": { "type": "string", "description": "The stock ticker symbol, e.g. AAPL for Apple Inc." } }, "required": ["ticker"] } } ] ``` And then asked the model "What's the S&P 500 at today?", the model might produce `tool_use` content blocks in the response like this: ```json [ { "type": "tool_use", "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "name": "get_stock_price", "input": { "ticker": "^GSPC" } } ] ``` You might then run your `get_stock_price` tool with `{"ticker": "^GSPC"}` as an input, and return the following back to the model in a subsequent `user` message: ```json [ { "type": "tool_result", "tool_use_id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "content": "259.75 USD" } ] ``` Tools can be used for workflows that include running client-side tools and functions, or more generally whenever you want the model to produce a particular JSON structure of output. See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. """ anthropic-sdk-python-0.69.0/src/anthropic/types/message_count_tokens_tool_param.py000066400000000000000000000015101506653454500306350ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union from typing_extensions import TypeAlias from .tool_param import ToolParam from .tool_bash_20250124_param import ToolBash20250124Param from .web_search_tool_20250305_param import WebSearchTool20250305Param from .tool_text_editor_20250124_param import ToolTextEditor20250124Param from .tool_text_editor_20250429_param import ToolTextEditor20250429Param from .tool_text_editor_20250728_param import ToolTextEditor20250728Param __all__ = ["MessageCountTokensToolParam"] MessageCountTokensToolParam: TypeAlias = Union[ ToolParam, ToolBash20250124Param, ToolTextEditor20250124Param, ToolTextEditor20250429Param, ToolTextEditor20250728Param, WebSearchTool20250305Param, ] anthropic-sdk-python-0.69.0/src/anthropic/types/message_create_params.py000066400000000000000000000255071506653454500265270ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union, Iterable from typing_extensions import Literal, Required, TypeAlias, TypedDict from .._types import SequenceNotStr from .model_param import ModelParam from .message_param import MessageParam from .metadata_param import MetadataParam from .text_block_param import TextBlockParam from .tool_union_param import ToolUnionParam from .tool_choice_param import ToolChoiceParam from .thinking_config_param import ThinkingConfigParam from .tool_choice_any_param import ToolChoiceAnyParam from .tool_choice_auto_param import ToolChoiceAutoParam from .tool_choice_tool_param import ToolChoiceToolParam __all__ = [ "MessageCreateParamsBase", "Metadata", "ToolChoice", "ToolChoiceToolChoiceAuto", "ToolChoiceToolChoiceAny", "ToolChoiceToolChoiceTool", "MessageCreateParamsNonStreaming", "MessageCreateParamsStreaming", ] class MessageCreateParamsBase(TypedDict, total=False): max_tokens: Required[int] """The maximum number of tokens to generate before stopping. Note that our models may stop _before_ reaching this maximum. This parameter only specifies the absolute maximum number of tokens to generate. Different models have different maximum values for this parameter. See [models](https://docs.anthropic.com/en/docs/models-overview) for details. """ messages: Required[Iterable[MessageParam]] """Input messages. Our models are trained to operate on alternating `user` and `assistant` conversational turns. When creating a new `Message`, you specify the prior conversational turns with the `messages` parameter, and the model then generates the next `Message` in the conversation. Consecutive `user` or `assistant` turns in your request will be combined into a single turn. Each input message must be an object with a `role` and `content`. You can specify a single `user`-role message, or you can include multiple `user` and `assistant` messages. If the final message uses the `assistant` role, the response content will continue immediately from the content in that message. This can be used to constrain part of the model's response. Example with a single `user` message: ```json [{ "role": "user", "content": "Hello, Claude" }] ``` Example with multiple conversational turns: ```json [ { "role": "user", "content": "Hello there." }, { "role": "assistant", "content": "Hi, I'm Claude. How can I help you?" }, { "role": "user", "content": "Can you explain LLMs in plain English?" } ] ``` Example with a partially-filled response from Claude: ```json [ { "role": "user", "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun" }, { "role": "assistant", "content": "The best answer is (" } ] ``` Each input message `content` may be either a single `string` or an array of content blocks, where each block has a specific `type`. Using a `string` for `content` is shorthand for an array of one content block of type `"text"`. The following input messages are equivalent: ```json { "role": "user", "content": "Hello, Claude" } ``` ```json { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } ``` See [input examples](https://docs.anthropic.com/en/api/messages-examples). Note that if you want to include a [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use the top-level `system` parameter — there is no `"system"` role for input messages in the Messages API. There is a limit of 100,000 messages in a single request. """ model: Required[ModelParam] """ The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options. """ metadata: MetadataParam """An object describing metadata about the request.""" service_tier: Literal["auto", "standard_only"] """ Determines whether to use priority capacity (if available) or standard capacity for this request. Anthropic offers different levels of service for your API requests. See [service-tiers](https://docs.anthropic.com/en/api/service-tiers) for details. """ stop_sequences: SequenceNotStr[str] """Custom text sequences that will cause the model to stop generating. Our models will normally stop when they have naturally completed their turn, which will result in a response `stop_reason` of `"end_turn"`. If you want the model to stop generating when it encounters custom strings of text, you can use the `stop_sequences` parameter. If the model encounters one of the custom sequences, the response `stop_reason` value will be `"stop_sequence"` and the response `stop_sequence` value will contain the matched stop sequence. """ system: Union[str, Iterable[TextBlockParam]] """System prompt. A system prompt is a way of providing context and instructions to Claude, such as specifying a particular goal or role. See our [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts). """ temperature: float """Amount of randomness injected into the response. Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0` for analytical / multiple choice, and closer to `1.0` for creative and generative tasks. Note that even with `temperature` of `0.0`, the results will not be fully deterministic. """ thinking: ThinkingConfigParam """Configuration for enabling Claude's extended thinking. When enabled, responses include `thinking` content blocks showing Claude's thinking process before the final answer. Requires a minimum budget of 1,024 tokens and counts towards your `max_tokens` limit. See [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) for details. """ tool_choice: ToolChoiceParam """How the model should use the provided tools. The model can use a specific tool, any available tool, decide by itself, or not use tools at all. """ tools: Iterable[ToolUnionParam] """Definitions of tools that the model may use. If you include `tools` in your API request, the model may return `tool_use` content blocks that represent the model's use of those tools. You can then run those tools using the tool input generated by the model and then optionally return results back to the model using `tool_result` content blocks. There are two types of tools: **client tools** and **server tools**. The behavior described below applies to client tools. For [server tools](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#server-tools), see their individual documentation as each has its own behavior (e.g., the [web search tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool)). Each tool definition includes: - `name`: Name of the tool. - `description`: Optional, but strongly-recommended description of the tool. - `input_schema`: [JSON schema](https://json-schema.org/draft/2020-12) for the tool `input` shape that the model will produce in `tool_use` output content blocks. For example, if you defined `tools` as: ```json [ { "name": "get_stock_price", "description": "Get the current stock price for a given ticker symbol.", "input_schema": { "type": "object", "properties": { "ticker": { "type": "string", "description": "The stock ticker symbol, e.g. AAPL for Apple Inc." } }, "required": ["ticker"] } } ] ``` And then asked the model "What's the S&P 500 at today?", the model might produce `tool_use` content blocks in the response like this: ```json [ { "type": "tool_use", "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "name": "get_stock_price", "input": { "ticker": "^GSPC" } } ] ``` You might then run your `get_stock_price` tool with `{"ticker": "^GSPC"}` as an input, and return the following back to the model in a subsequent `user` message: ```json [ { "type": "tool_result", "tool_use_id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", "content": "259.75 USD" } ] ``` Tools can be used for workflows that include running client-side tools and functions, or more generally whenever you want the model to produce a particular JSON structure of output. See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. """ top_k: int """Only sample from the top K options for each subsequent token. Used to remove "long tail" low probability responses. [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277). Recommended for advanced use cases only. You usually only need to use `temperature`. """ top_p: float """Use nucleus sampling. In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by `top_p`. You should either alter `temperature` or `top_p`, but not both. Recommended for advanced use cases only. You usually only need to use `temperature`. """ Metadata: TypeAlias = MetadataParam """This is deprecated, `MetadataParam` should be used instead""" ToolChoice: TypeAlias = ToolChoiceParam """This is deprecated, `ToolChoiceParam` should be used instead""" ToolChoiceToolChoiceAuto: TypeAlias = ToolChoiceAutoParam """This is deprecated, `ToolChoiceAutoParam` should be used instead""" ToolChoiceToolChoiceAny: TypeAlias = ToolChoiceAnyParam """This is deprecated, `ToolChoiceAnyParam` should be used instead""" ToolChoiceToolChoiceTool: TypeAlias = ToolChoiceToolParam """This is deprecated, `ToolChoiceToolParam` should be used instead""" class MessageCreateParamsNonStreaming(MessageCreateParamsBase, total=False): stream: Literal[False] """Whether to incrementally stream the response using server-sent events. See [streaming](https://docs.anthropic.com/en/api/messages-streaming) for details. """ class MessageCreateParamsStreaming(MessageCreateParamsBase): stream: Required[Literal[True]] """Whether to incrementally stream the response using server-sent events. See [streaming](https://docs.anthropic.com/en/api/messages-streaming) for details. """ MessageCreateParams = Union[MessageCreateParamsNonStreaming, MessageCreateParamsStreaming] anthropic-sdk-python-0.69.0/src/anthropic/types/message_delta_event.py000066400000000000000000000004271506653454500262050ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from .raw_message_delta_event import RawMessageDeltaEvent __all__ = ["MessageDeltaEvent"] MessageDeltaEvent = RawMessageDeltaEvent """The RawMessageDeltaEvent type should be used instead""" anthropic-sdk-python-0.69.0/src/anthropic/types/message_delta_usage.py000066400000000000000000000014601506653454500261660ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from .._models import BaseModel from .server_tool_usage import ServerToolUsage __all__ = ["MessageDeltaUsage"] class MessageDeltaUsage(BaseModel): cache_creation_input_tokens: Optional[int] = None """The cumulative number of input tokens used to create the cache entry.""" cache_read_input_tokens: Optional[int] = None """The cumulative number of input tokens read from the cache.""" input_tokens: Optional[int] = None """The cumulative number of input tokens which were used.""" output_tokens: int """The cumulative number of output tokens which were used.""" server_tool_use: Optional[ServerToolUsage] = None """The number of server tool requests.""" anthropic-sdk-python-0.69.0/src/anthropic/types/message_param.py000066400000000000000000000030421506653454500250070ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union, Iterable from typing_extensions import Literal, Required, TypedDict from .content_block import ContentBlock from .text_block_param import TextBlockParam from .image_block_param import ImageBlockParam from .document_block_param import DocumentBlockParam from .thinking_block_param import ThinkingBlockParam from .tool_use_block_param import ToolUseBlockParam from .tool_result_block_param import ToolResultBlockParam from .search_result_block_param import SearchResultBlockParam from .server_tool_use_block_param import ServerToolUseBlockParam from .redacted_thinking_block_param import RedactedThinkingBlockParam from .web_search_tool_result_block_param import WebSearchToolResultBlockParam __all__ = ["MessageParam"] class MessageParam(TypedDict, total=False): content: Required[ Union[ str, Iterable[ Union[ TextBlockParam, ImageBlockParam, DocumentBlockParam, SearchResultBlockParam, ThinkingBlockParam, RedactedThinkingBlockParam, ToolUseBlockParam, ToolResultBlockParam, ServerToolUseBlockParam, WebSearchToolResultBlockParam, ContentBlock, ] ], ] ] role: Required[Literal["user", "assistant"]] anthropic-sdk-python-0.69.0/src/anthropic/types/message_start_event.py000066400000000000000000000004271506653454500262510ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from .raw_message_start_event import RawMessageStartEvent __all__ = ["MessageStartEvent"] MessageStartEvent = RawMessageStartEvent """The RawMessageStartEvent type should be used instead""" anthropic-sdk-python-0.69.0/src/anthropic/types/message_stop_event.py000066400000000000000000000004211506653454500260730ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from .raw_message_stop_event import RawMessageStopEvent __all__ = ["MessageStopEvent"] MessageStopEvent = RawMessageStopEvent """The RawMessageStopEvent type should be used instead""" anthropic-sdk-python-0.69.0/src/anthropic/types/message_stream_event.py000066400000000000000000000004351506653454500264060ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from .raw_message_stream_event import RawMessageStreamEvent __all__ = ["MessageStreamEvent"] MessageStreamEvent = RawMessageStreamEvent """The RawMessageStreamEvent type should be used instead""" anthropic-sdk-python-0.69.0/src/anthropic/types/message_tokens_count.py000066400000000000000000000005111506653454500264200ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from .._models import BaseModel __all__ = ["MessageTokensCount"] class MessageTokensCount(BaseModel): input_tokens: int """ The total number of tokens across the provided list of messages, system prompt, and tools. """ anthropic-sdk-python-0.69.0/src/anthropic/types/messages/000077500000000000000000000000001506653454500234415ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/types/messages/__init__.py000066400000000000000000000020641506653454500255540ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from .message_batch import MessageBatch as MessageBatch from .batch_list_params import BatchListParams as BatchListParams from .batch_create_params import BatchCreateParams as BatchCreateParams from .message_batch_result import MessageBatchResult as MessageBatchResult from .deleted_message_batch import DeletedMessageBatch as DeletedMessageBatch from .message_batch_errored_result import MessageBatchErroredResult as MessageBatchErroredResult from .message_batch_expired_result import MessageBatchExpiredResult as MessageBatchExpiredResult from .message_batch_request_counts import MessageBatchRequestCounts as MessageBatchRequestCounts from .message_batch_canceled_result import MessageBatchCanceledResult as MessageBatchCanceledResult from .message_batch_succeeded_result import MessageBatchSucceededResult as MessageBatchSucceededResult from .message_batch_individual_response import MessageBatchIndividualResponse as MessageBatchIndividualResponse anthropic-sdk-python-0.69.0/src/anthropic/types/messages/batch_create_params.py000066400000000000000000000020541506653454500277630ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Iterable from typing_extensions import Required, TypedDict from ..message_create_params import MessageCreateParamsNonStreaming __all__ = ["BatchCreateParams", "Request"] class BatchCreateParams(TypedDict, total=False): requests: Required[Iterable[Request]] """List of requests for prompt completion. Each is an individual request to create a Message. """ class Request(TypedDict, total=False): custom_id: Required[str] """Developer-provided ID created for each request in a Message Batch. Useful for matching results to requests, as results may be given out of request order. Must be unique for each request within the Message Batch. """ params: Required[MessageCreateParamsNonStreaming] """Messages API creation parameters for the individual request. See the [Messages API reference](/en/api/messages) for full documentation on available parameters. """ anthropic-sdk-python-0.69.0/src/anthropic/types/messages/batch_list_params.py000066400000000000000000000012631506653454500274740ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import TypedDict __all__ = ["BatchListParams"] class BatchListParams(TypedDict, total=False): after_id: str """ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately after this object. """ before_id: str """ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately before this object. """ limit: int """Number of items to return per page. Defaults to `20`. Ranges from `1` to `1000`. """ anthropic-sdk-python-0.69.0/src/anthropic/types/messages/deleted_message_batch.py000066400000000000000000000006551506653454500302740ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["DeletedMessageBatch"] class DeletedMessageBatch(BaseModel): id: str """ID of the Message Batch.""" type: Literal["message_batch_deleted"] """Deleted object type. For Message Batches, this is always `"message_batch_deleted"`. """ anthropic-sdk-python-0.69.0/src/anthropic/types/messages/message_batch.py000066400000000000000000000045571506653454500266130ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel from .message_batch_request_counts import MessageBatchRequestCounts __all__ = ["MessageBatch"] class MessageBatch(BaseModel): id: str """Unique object identifier. The format and length of IDs may change over time. """ archived_at: Optional[datetime] = None """ RFC 3339 datetime string representing the time at which the Message Batch was archived and its results became unavailable. """ cancel_initiated_at: Optional[datetime] = None """ RFC 3339 datetime string representing the time at which cancellation was initiated for the Message Batch. Specified only if cancellation was initiated. """ created_at: datetime """ RFC 3339 datetime string representing the time at which the Message Batch was created. """ ended_at: Optional[datetime] = None """ RFC 3339 datetime string representing the time at which processing for the Message Batch ended. Specified only once processing ends. Processing ends when every request in a Message Batch has either succeeded, errored, canceled, or expired. """ expires_at: datetime """ RFC 3339 datetime string representing the time at which the Message Batch will expire and end processing, which is 24 hours after creation. """ processing_status: Literal["in_progress", "canceling", "ended"] """Processing status of the Message Batch.""" request_counts: MessageBatchRequestCounts """Tallies requests within the Message Batch, categorized by their status. Requests start as `processing` and move to one of the other statuses only once processing of the entire batch ends. The sum of all values always matches the total number of requests in the batch. """ results_url: Optional[str] = None """URL to a `.jsonl` file containing the results of the Message Batch requests. Specified only once processing ends. Results in the file are not guaranteed to be in the same order as requests. Use the `custom_id` field to match results to requests. """ type: Literal["message_batch"] """Object type. For Message Batches, this is always `"message_batch"`. """ anthropic-sdk-python-0.69.0/src/anthropic/types/messages/message_batch_canceled_result.py000066400000000000000000000004261506653454500320160ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["MessageBatchCanceledResult"] class MessageBatchCanceledResult(BaseModel): type: Literal["canceled"] anthropic-sdk-python-0.69.0/src/anthropic/types/messages/message_batch_errored_result.py000066400000000000000000000005371506653454500317250ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel from ..shared.error_response import ErrorResponse __all__ = ["MessageBatchErroredResult"] class MessageBatchErroredResult(BaseModel): error: ErrorResponse type: Literal["errored"] anthropic-sdk-python-0.69.0/src/anthropic/types/messages/message_batch_expired_result.py000066400000000000000000000004231506653454500317150ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["MessageBatchExpiredResult"] class MessageBatchExpiredResult(BaseModel): type: Literal["expired"] anthropic-sdk-python-0.69.0/src/anthropic/types/messages/message_batch_individual_response.py000066400000000000000000000014461506653454500327330ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from ..._models import BaseModel from .message_batch_result import MessageBatchResult __all__ = ["MessageBatchIndividualResponse"] class MessageBatchIndividualResponse(BaseModel): custom_id: str """Developer-provided ID created for each request in a Message Batch. Useful for matching results to requests, as results may be given out of request order. Must be unique for each request within the Message Batch. """ result: MessageBatchResult """Processing result for this request. Contains a Message output if processing was successful, an error response if processing failed, or the reason why processing was not attempted, such as cancellation or expiration. """ anthropic-sdk-python-0.69.0/src/anthropic/types/messages/message_batch_request_counts.py000066400000000000000000000017421506653454500317470ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from ..._models import BaseModel __all__ = ["MessageBatchRequestCounts"] class MessageBatchRequestCounts(BaseModel): canceled: int """Number of requests in the Message Batch that have been canceled. This is zero until processing of the entire Message Batch has ended. """ errored: int """Number of requests in the Message Batch that encountered an error. This is zero until processing of the entire Message Batch has ended. """ expired: int """Number of requests in the Message Batch that have expired. This is zero until processing of the entire Message Batch has ended. """ processing: int """Number of requests in the Message Batch that are processing.""" succeeded: int """Number of requests in the Message Batch that have completed successfully. This is zero until processing of the entire Message Batch has ended. """ anthropic-sdk-python-0.69.0/src/anthropic/types/messages/message_batch_result.py000066400000000000000000000013351506653454500302000ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Union from typing_extensions import Annotated, TypeAlias from ..._utils import PropertyInfo from .message_batch_errored_result import MessageBatchErroredResult from .message_batch_expired_result import MessageBatchExpiredResult from .message_batch_canceled_result import MessageBatchCanceledResult from .message_batch_succeeded_result import MessageBatchSucceededResult __all__ = ["MessageBatchResult"] MessageBatchResult: TypeAlias = Annotated[ Union[ MessageBatchSucceededResult, MessageBatchErroredResult, MessageBatchCanceledResult, MessageBatchExpiredResult ], PropertyInfo(discriminator="type"), ] anthropic-sdk-python-0.69.0/src/anthropic/types/messages/message_batch_succeeded_result.py000066400000000000000000000005151506653454500322030ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..message import Message from ..._models import BaseModel __all__ = ["MessageBatchSucceededResult"] class MessageBatchSucceededResult(BaseModel): message: Message type: Literal["succeeded"] anthropic-sdk-python-0.69.0/src/anthropic/types/metadata_param.py000066400000000000000000000011221506653454500251400ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import TypedDict __all__ = ["MetadataParam"] class MetadataParam(TypedDict, total=False): user_id: Optional[str] """An external identifier for the user who is associated with the request. This should be a uuid, hash value, or other opaque identifier. Anthropic may use this id to help detect abuse. Do not include any identifying information such as name, email address, or phone number. """ anthropic-sdk-python-0.69.0/src/anthropic/types/model.py000066400000000000000000000016021506653454500233030ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Union from typing_extensions import Literal, TypeAlias __all__ = ["Model"] Model: TypeAlias = Union[ Literal[ "claude-3-7-sonnet-latest", "claude-3-7-sonnet-20250219", "claude-3-5-haiku-latest", "claude-3-5-haiku-20241022", "claude-sonnet-4-20250514", "claude-sonnet-4-0", "claude-4-sonnet-20250514", "claude-sonnet-4-5", "claude-sonnet-4-5-20250929", "claude-3-5-sonnet-latest", "claude-3-5-sonnet-20241022", "claude-3-5-sonnet-20240620", "claude-opus-4-0", "claude-opus-4-20250514", "claude-4-opus-20250514", "claude-opus-4-1-20250805", "claude-3-opus-latest", "claude-3-opus-20240229", "claude-3-haiku-20240307", ], str, ] anthropic-sdk-python-0.69.0/src/anthropic/types/model_info.py000066400000000000000000000012061506653454500243160ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from datetime import datetime from typing_extensions import Literal from .._models import BaseModel __all__ = ["ModelInfo"] class ModelInfo(BaseModel): id: str """Unique model identifier.""" created_at: datetime """RFC 3339 datetime string representing the time at which the model was released. May be set to an epoch value if the release date is unknown. """ display_name: str """A human-readable name for the model.""" type: Literal["model"] """Object type. For Models, this is always `"model"`. """ anthropic-sdk-python-0.69.0/src/anthropic/types/model_list_params.py000066400000000000000000000017161506653454500257070ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import List from typing_extensions import Annotated, TypedDict from .._utils import PropertyInfo from .anthropic_beta_param import AnthropicBetaParam __all__ = ["ModelListParams"] class ModelListParams(TypedDict, total=False): after_id: str """ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately after this object. """ before_id: str """ID of the object to use as a cursor for pagination. When provided, returns the page of results immediately before this object. """ limit: int """Number of items to return per page. Defaults to `20`. Ranges from `1` to `1000`. """ betas: Annotated[List[AnthropicBetaParam], PropertyInfo(alias="anthropic-beta")] """Optional header to specify the beta version(s) you want to use.""" anthropic-sdk-python-0.69.0/src/anthropic/types/model_param.py000066400000000000000000000016601506653454500244670ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union from typing_extensions import Literal, TypeAlias __all__ = ["ModelParam"] ModelParam: TypeAlias = Union[ Literal[ "claude-3-7-sonnet-latest", "claude-3-7-sonnet-20250219", "claude-3-5-haiku-latest", "claude-3-5-haiku-20241022", "claude-sonnet-4-20250514", "claude-sonnet-4-0", "claude-4-sonnet-20250514", "claude-sonnet-4-5", "claude-sonnet-4-5-20250929", "claude-3-5-sonnet-latest", "claude-3-5-sonnet-20241022", "claude-3-5-sonnet-20240620", "claude-opus-4-0", "claude-opus-4-20250514", "claude-4-opus-20250514", "claude-opus-4-1-20250805", "claude-3-opus-latest", "claude-3-opus-20240229", "claude-3-haiku-20240307", ], str, ] anthropic-sdk-python-0.69.0/src/anthropic/types/plain_text_source_param.py000066400000000000000000000005761506653454500271230ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["PlainTextSourceParam"] class PlainTextSourceParam(TypedDict, total=False): data: Required[str] media_type: Required[Literal["text/plain"]] type: Required[Literal["text"]] anthropic-sdk-python-0.69.0/src/anthropic/types/raw_content_block_delta.py000066400000000000000000000011431506653454500270510ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Union from typing_extensions import Annotated, TypeAlias from .._utils import PropertyInfo from .text_delta import TextDelta from .thinking_delta import ThinkingDelta from .citations_delta import CitationsDelta from .signature_delta import SignatureDelta from .input_json_delta import InputJSONDelta __all__ = ["RawContentBlockDelta"] RawContentBlockDelta: TypeAlias = Annotated[ Union[TextDelta, InputJSONDelta, CitationsDelta, ThinkingDelta, SignatureDelta], PropertyInfo(discriminator="type") ] anthropic-sdk-python-0.69.0/src/anthropic/types/raw_content_block_delta_event.py000066400000000000000000000006111506653454500302510ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from .._models import BaseModel from .raw_content_block_delta import RawContentBlockDelta __all__ = ["RawContentBlockDeltaEvent"] class RawContentBlockDeltaEvent(BaseModel): delta: RawContentBlockDelta index: int type: Literal["content_block_delta"] anthropic-sdk-python-0.69.0/src/anthropic/types/raw_content_block_start_event.py000066400000000000000000000016411506653454500303210ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Union from typing_extensions import Literal, Annotated, TypeAlias from .._utils import PropertyInfo from .._models import BaseModel from .text_block import TextBlock from .thinking_block import ThinkingBlock from .tool_use_block import ToolUseBlock from .server_tool_use_block import ServerToolUseBlock from .redacted_thinking_block import RedactedThinkingBlock from .web_search_tool_result_block import WebSearchToolResultBlock __all__ = ["RawContentBlockStartEvent", "ContentBlock"] ContentBlock: TypeAlias = Annotated[ Union[TextBlock, ThinkingBlock, RedactedThinkingBlock, ToolUseBlock, ServerToolUseBlock, WebSearchToolResultBlock], PropertyInfo(discriminator="type"), ] class RawContentBlockStartEvent(BaseModel): content_block: ContentBlock index: int type: Literal["content_block_start"] anthropic-sdk-python-0.69.0/src/anthropic/types/raw_content_block_stop_event.py000066400000000000000000000004531506653454500301510ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from .._models import BaseModel __all__ = ["RawContentBlockStopEvent"] class RawContentBlockStopEvent(BaseModel): index: int type: Literal["content_block_stop"] anthropic-sdk-python-0.69.0/src/anthropic/types/raw_message_delta_event.py000066400000000000000000000023731506653454500270600ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from typing_extensions import Literal from .._models import BaseModel from .stop_reason import StopReason from .message_delta_usage import MessageDeltaUsage __all__ = ["RawMessageDeltaEvent", "Delta"] class Delta(BaseModel): stop_reason: Optional[StopReason] = None stop_sequence: Optional[str] = None class RawMessageDeltaEvent(BaseModel): delta: Delta type: Literal["message_delta"] usage: MessageDeltaUsage """Billing and rate-limit usage. Anthropic's API bills and rate-limits by token counts, as tokens represent the underlying cost to our systems. Under the hood, the API transforms requests into a format suitable for the model. The model's output then goes through a parsing stage before becoming an API response. As a result, the token counts in `usage` will not match one-to-one with the exact visible content of an API request or response. For example, `output_tokens` will be non-zero, even for an empty string response from Claude. Total input tokens in a request is the summation of `input_tokens`, `cache_creation_input_tokens`, and `cache_read_input_tokens`. """ anthropic-sdk-python-0.69.0/src/anthropic/types/raw_message_start_event.py000066400000000000000000000005011506653454500271130ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from .message import Message from .._models import BaseModel __all__ = ["RawMessageStartEvent"] class RawMessageStartEvent(BaseModel): message: Message type: Literal["message_start"] anthropic-sdk-python-0.69.0/src/anthropic/types/raw_message_stop_event.py000066400000000000000000000004131506653454500267450ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from .._models import BaseModel __all__ = ["RawMessageStopEvent"] class RawMessageStopEvent(BaseModel): type: Literal["message_stop"] anthropic-sdk-python-0.69.0/src/anthropic/types/raw_message_stream_event.py000066400000000000000000000016201506653454500272540ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Union from typing_extensions import Annotated, TypeAlias from .._utils import PropertyInfo from .raw_message_stop_event import RawMessageStopEvent from .raw_message_delta_event import RawMessageDeltaEvent from .raw_message_start_event import RawMessageStartEvent from .raw_content_block_stop_event import RawContentBlockStopEvent from .raw_content_block_delta_event import RawContentBlockDeltaEvent from .raw_content_block_start_event import RawContentBlockStartEvent __all__ = ["RawMessageStreamEvent"] RawMessageStreamEvent: TypeAlias = Annotated[ Union[ RawMessageStartEvent, RawMessageDeltaEvent, RawMessageStopEvent, RawContentBlockStartEvent, RawContentBlockDeltaEvent, RawContentBlockStopEvent, ], PropertyInfo(discriminator="type"), ] anthropic-sdk-python-0.69.0/src/anthropic/types/redacted_thinking_block.py000066400000000000000000000004431506653454500270250ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from .._models import BaseModel __all__ = ["RedactedThinkingBlock"] class RedactedThinkingBlock(BaseModel): data: str type: Literal["redacted_thinking"] anthropic-sdk-python-0.69.0/src/anthropic/types/redacted_thinking_block_param.py000066400000000000000000000005461506653454500302110ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["RedactedThinkingBlockParam"] class RedactedThinkingBlockParam(TypedDict, total=False): data: Required[str] type: Required[Literal["redacted_thinking"]] anthropic-sdk-python-0.69.0/src/anthropic/types/search_result_block_param.py000066400000000000000000000014331506653454500274020ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Iterable, Optional from typing_extensions import Literal, Required, TypedDict from .text_block_param import TextBlockParam from .citations_config_param import CitationsConfigParam from .cache_control_ephemeral_param import CacheControlEphemeralParam __all__ = ["SearchResultBlockParam"] class SearchResultBlockParam(TypedDict, total=False): content: Required[Iterable[TextBlockParam]] source: Required[str] title: Required[str] type: Required[Literal["search_result"]] cache_control: Optional[CacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" citations: CitationsConfigParam anthropic-sdk-python-0.69.0/src/anthropic/types/server_tool_usage.py000066400000000000000000000004111506653454500257270ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from .._models import BaseModel __all__ = ["ServerToolUsage"] class ServerToolUsage(BaseModel): web_search_requests: int """The number of web search tool requests.""" anthropic-sdk-python-0.69.0/src/anthropic/types/server_tool_use_block.py000066400000000000000000000005151506653454500265760ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from .._models import BaseModel __all__ = ["ServerToolUseBlock"] class ServerToolUseBlock(BaseModel): id: str input: object name: Literal["web_search"] type: Literal["server_tool_use"] anthropic-sdk-python-0.69.0/src/anthropic/types/server_tool_use_block_param.py000066400000000000000000000012031506653454500277510ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from .cache_control_ephemeral_param import CacheControlEphemeralParam __all__ = ["ServerToolUseBlockParam"] class ServerToolUseBlockParam(TypedDict, total=False): id: Required[str] input: Required[object] name: Required[Literal["web_search"]] type: Required[Literal["server_tool_use"]] cache_control: Optional[CacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" anthropic-sdk-python-0.69.0/src/anthropic/types/shared/000077500000000000000000000000001506653454500231005ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/src/anthropic/types/shared/__init__.py000066400000000000000000000014441506653454500252140ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from .error_object import ErrorObject as ErrorObject from .billing_error import BillingError as BillingError from .error_response import ErrorResponse as ErrorResponse from .not_found_error import NotFoundError as NotFoundError from .api_error_object import APIErrorObject as APIErrorObject from .overloaded_error import OverloadedError as OverloadedError from .permission_error import PermissionError as PermissionError from .rate_limit_error import RateLimitError as RateLimitError from .authentication_error import AuthenticationError as AuthenticationError from .gateway_timeout_error import GatewayTimeoutError as GatewayTimeoutError from .invalid_request_error import InvalidRequestError as InvalidRequestError anthropic-sdk-python-0.69.0/src/anthropic/types/shared/api_error_object.py000066400000000000000000000004211506653454500267570ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["APIErrorObject"] class APIErrorObject(BaseModel): message: str type: Literal["api_error"] anthropic-sdk-python-0.69.0/src/anthropic/types/shared/authentication_error.py000066400000000000000000000004461506653454500277060ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["AuthenticationError"] class AuthenticationError(BaseModel): message: str type: Literal["authentication_error"] anthropic-sdk-python-0.69.0/src/anthropic/types/shared/billing_error.py000066400000000000000000000004211506653454500263000ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["BillingError"] class BillingError(BaseModel): message: str type: Literal["billing_error"] anthropic-sdk-python-0.69.0/src/anthropic/types/shared/error_object.py000066400000000000000000000017261506653454500261370ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Union from typing_extensions import Annotated, TypeAlias from ..._utils import PropertyInfo from .billing_error import BillingError from .not_found_error import NotFoundError from .api_error_object import APIErrorObject from .overloaded_error import OverloadedError from .permission_error import PermissionError from .rate_limit_error import RateLimitError from .authentication_error import AuthenticationError from .gateway_timeout_error import GatewayTimeoutError from .invalid_request_error import InvalidRequestError __all__ = ["ErrorObject"] ErrorObject: TypeAlias = Annotated[ Union[ InvalidRequestError, AuthenticationError, BillingError, PermissionError, NotFoundError, RateLimitError, GatewayTimeoutError, APIErrorObject, OverloadedError, ], PropertyInfo(discriminator="type"), ] anthropic-sdk-python-0.69.0/src/anthropic/types/shared/error_response.py000066400000000000000000000005711506653454500265240ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from typing_extensions import Literal from ..._models import BaseModel from .error_object import ErrorObject __all__ = ["ErrorResponse"] class ErrorResponse(BaseModel): error: ErrorObject request_id: Optional[str] = None type: Literal["error"] anthropic-sdk-python-0.69.0/src/anthropic/types/shared/gateway_timeout_error.py000066400000000000000000000004371506653454500300760ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["GatewayTimeoutError"] class GatewayTimeoutError(BaseModel): message: str type: Literal["timeout_error"] anthropic-sdk-python-0.69.0/src/anthropic/types/shared/invalid_request_error.py000066400000000000000000000004471506653454500300660ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["InvalidRequestError"] class InvalidRequestError(BaseModel): message: str type: Literal["invalid_request_error"] anthropic-sdk-python-0.69.0/src/anthropic/types/shared/not_found_error.py000066400000000000000000000004251506653454500266570ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["NotFoundError"] class NotFoundError(BaseModel): message: str type: Literal["not_found_error"] anthropic-sdk-python-0.69.0/src/anthropic/types/shared/overloaded_error.py000066400000000000000000000004321506653454500270060ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["OverloadedError"] class OverloadedError(BaseModel): message: str type: Literal["overloaded_error"] anthropic-sdk-python-0.69.0/src/anthropic/types/shared/permission_error.py000066400000000000000000000004321506653454500270520ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["PermissionError"] class PermissionError(BaseModel): message: str type: Literal["permission_error"] anthropic-sdk-python-0.69.0/src/anthropic/types/shared/rate_limit_error.py000066400000000000000000000004301506653454500270110ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from ..._models import BaseModel __all__ = ["RateLimitError"] class RateLimitError(BaseModel): message: str type: Literal["rate_limit_error"] anthropic-sdk-python-0.69.0/src/anthropic/types/signature_delta.py000066400000000000000000000004301506653454500253530ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from .._models import BaseModel __all__ = ["SignatureDelta"] class SignatureDelta(BaseModel): signature: str type: Literal["signature_delta"] anthropic-sdk-python-0.69.0/src/anthropic/types/stop_reason.py000066400000000000000000000004721506653454500245430ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal, TypeAlias __all__ = ["StopReason"] StopReason: TypeAlias = Literal[ "end_turn", "max_tokens", "stop_sequence", "tool_use", "pause_turn", "refusal", "model_context_window_exceeded" ] anthropic-sdk-python-0.69.0/src/anthropic/types/text_block.py000066400000000000000000000012261506653454500243430ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import List, Optional from typing_extensions import Literal from .._models import BaseModel from .text_citation import TextCitation __all__ = ["TextBlock"] class TextBlock(BaseModel): citations: Optional[List[TextCitation]] = None """Citations supporting the text block. The type of citation returned will depend on the type of document being cited. Citing a PDF results in `page_location`, plain text results in `char_location`, and content document results in `content_block_location`. """ text: str type: Literal["text"] anthropic-sdk-python-0.69.0/src/anthropic/types/text_block_param.py000066400000000000000000000012231506653454500255200ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Iterable, Optional from typing_extensions import Literal, Required, TypedDict from .text_citation_param import TextCitationParam from .cache_control_ephemeral_param import CacheControlEphemeralParam __all__ = ["TextBlockParam"] class TextBlockParam(TypedDict, total=False): text: Required[str] type: Required[Literal["text"]] cache_control: Optional[CacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" citations: Optional[Iterable[TextCitationParam]] anthropic-sdk-python-0.69.0/src/anthropic/types/text_citation.py000066400000000000000000000015221506653454500250620ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Union from typing_extensions import Annotated, TypeAlias from .._utils import PropertyInfo from .citation_char_location import CitationCharLocation from .citation_page_location import CitationPageLocation from .citation_content_block_location import CitationContentBlockLocation from .citations_search_result_location import CitationsSearchResultLocation from .citations_web_search_result_location import CitationsWebSearchResultLocation __all__ = ["TextCitation"] TextCitation: TypeAlias = Annotated[ Union[ CitationCharLocation, CitationPageLocation, CitationContentBlockLocation, CitationsWebSearchResultLocation, CitationsSearchResultLocation, ], PropertyInfo(discriminator="type"), ] anthropic-sdk-python-0.69.0/src/anthropic/types/text_citation_param.py000066400000000000000000000015131506653454500262420ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union from typing_extensions import TypeAlias from .citation_char_location_param import CitationCharLocationParam from .citation_page_location_param import CitationPageLocationParam from .citation_content_block_location_param import CitationContentBlockLocationParam from .citation_search_result_location_param import CitationSearchResultLocationParam from .citation_web_search_result_location_param import CitationWebSearchResultLocationParam __all__ = ["TextCitationParam"] TextCitationParam: TypeAlias = Union[ CitationCharLocationParam, CitationPageLocationParam, CitationContentBlockLocationParam, CitationWebSearchResultLocationParam, CitationSearchResultLocationParam, ] anthropic-sdk-python-0.69.0/src/anthropic/types/text_delta.py000066400000000000000000000004041506653454500243370ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from .._models import BaseModel __all__ = ["TextDelta"] class TextDelta(BaseModel): text: str type: Literal["text_delta"] anthropic-sdk-python-0.69.0/src/anthropic/types/thinking_block.py000066400000000000000000000004421506653454500251710ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from .._models import BaseModel __all__ = ["ThinkingBlock"] class ThinkingBlock(BaseModel): signature: str thinking: str type: Literal["thinking"] anthropic-sdk-python-0.69.0/src/anthropic/types/thinking_block_param.py000066400000000000000000000005571506653454500263600ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["ThinkingBlockParam"] class ThinkingBlockParam(TypedDict, total=False): signature: Required[str] thinking: Required[str] type: Required[Literal["thinking"]] anthropic-sdk-python-0.69.0/src/anthropic/types/thinking_config_disabled_param.py000066400000000000000000000005061506653454500303540ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["ThinkingConfigDisabledParam"] class ThinkingConfigDisabledParam(TypedDict, total=False): type: Required[Literal["disabled"]] anthropic-sdk-python-0.69.0/src/anthropic/types/thinking_config_enabled_param.py000066400000000000000000000013311506653454500301740ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["ThinkingConfigEnabledParam"] class ThinkingConfigEnabledParam(TypedDict, total=False): budget_tokens: Required[int] """Determines how many tokens Claude can use for its internal reasoning process. Larger budgets can enable more thorough analysis for complex problems, improving response quality. Must be ≥1024 and less than `max_tokens`. See [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) for details. """ type: Required[Literal["enabled"]] anthropic-sdk-python-0.69.0/src/anthropic/types/thinking_config_param.py000066400000000000000000000007171506653454500265310ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union from typing_extensions import TypeAlias from .thinking_config_enabled_param import ThinkingConfigEnabledParam from .thinking_config_disabled_param import ThinkingConfigDisabledParam __all__ = ["ThinkingConfigParam"] ThinkingConfigParam: TypeAlias = Union[ThinkingConfigEnabledParam, ThinkingConfigDisabledParam] anthropic-sdk-python-0.69.0/src/anthropic/types/thinking_delta.py000066400000000000000000000004241506653454500251700ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from .._models import BaseModel __all__ = ["ThinkingDelta"] class ThinkingDelta(BaseModel): thinking: str type: Literal["thinking_delta"] anthropic-sdk-python-0.69.0/src/anthropic/types/tool_bash_20250124_param.py000066400000000000000000000012641506653454500263200ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from .cache_control_ephemeral_param import CacheControlEphemeralParam __all__ = ["ToolBash20250124Param"] class ToolBash20250124Param(TypedDict, total=False): name: Required[Literal["bash"]] """Name of the tool. This is how the tool will be called by the model and in `tool_use` blocks. """ type: Required[Literal["bash_20250124"]] cache_control: Optional[CacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" anthropic-sdk-python-0.69.0/src/anthropic/types/tool_choice_any_param.py000066400000000000000000000007451506653454500265300ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["ToolChoiceAnyParam"] class ToolChoiceAnyParam(TypedDict, total=False): type: Required[Literal["any"]] disable_parallel_tool_use: bool """Whether to disable parallel tool use. Defaults to `false`. If set to `true`, the model will output exactly one tool use. """ anthropic-sdk-python-0.69.0/src/anthropic/types/tool_choice_auto_param.py000066400000000000000000000007501506653454500267050ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["ToolChoiceAutoParam"] class ToolChoiceAutoParam(TypedDict, total=False): type: Required[Literal["auto"]] disable_parallel_tool_use: bool """Whether to disable parallel tool use. Defaults to `false`. If set to `true`, the model will output at most one tool use. """ anthropic-sdk-python-0.69.0/src/anthropic/types/tool_choice_none_param.py000066400000000000000000000004621506653454500266740ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["ToolChoiceNoneParam"] class ToolChoiceNoneParam(TypedDict, total=False): type: Required[Literal["none"]] anthropic-sdk-python-0.69.0/src/anthropic/types/tool_choice_param.py000066400000000000000000000010611506653454500256510ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union from typing_extensions import TypeAlias from .tool_choice_any_param import ToolChoiceAnyParam from .tool_choice_auto_param import ToolChoiceAutoParam from .tool_choice_none_param import ToolChoiceNoneParam from .tool_choice_tool_param import ToolChoiceToolParam __all__ = ["ToolChoiceParam"] ToolChoiceParam: TypeAlias = Union[ToolChoiceAutoParam, ToolChoiceAnyParam, ToolChoiceToolParam, ToolChoiceNoneParam] anthropic-sdk-python-0.69.0/src/anthropic/types/tool_choice_tool_param.py000066400000000000000000000010501506653454500267040ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["ToolChoiceToolParam"] class ToolChoiceToolParam(TypedDict, total=False): name: Required[str] """The name of the tool to use.""" type: Required[Literal["tool"]] disable_parallel_tool_use: bool """Whether to disable parallel tool use. Defaults to `false`. If set to `true`, the model will output exactly one tool use. """ anthropic-sdk-python-0.69.0/src/anthropic/types/tool_param.py000066400000000000000000000031661506653454500243470ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Dict, Union, Optional from typing_extensions import Literal, Required, TypeAlias, TypedDict from .._types import SequenceNotStr from .._models import set_pydantic_config from .cache_control_ephemeral_param import CacheControlEphemeralParam __all__ = ["ToolParam", "InputSchema"] class InputSchemaTyped(TypedDict, total=False): type: Required[Literal["object"]] properties: Optional[object] required: Optional[SequenceNotStr[str]] set_pydantic_config(InputSchemaTyped, {"extra": "allow"}) InputSchema: TypeAlias = Union[InputSchemaTyped, Dict[str, object]] class ToolParam(TypedDict, total=False): input_schema: Required[InputSchema] """[JSON schema](https://json-schema.org/draft/2020-12) for this tool's input. This defines the shape of the `input` that your tool accepts and that the model will produce. """ name: Required[str] """Name of the tool. This is how the tool will be called by the model and in `tool_use` blocks. """ cache_control: Optional[CacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" description: str """Description of what this tool does. Tool descriptions should be as detailed as possible. The more information that the model has about what the tool is and how to use it, the better it will perform. You can use natural language descriptions to reinforce important aspects of the tool input JSON schema. """ type: Optional[Literal["custom"]] anthropic-sdk-python-0.69.0/src/anthropic/types/tool_result_block_param.py000066400000000000000000000017311506653454500271130ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union, Iterable, Optional from typing_extensions import Literal, Required, TypeAlias, TypedDict from .text_block_param import TextBlockParam from .image_block_param import ImageBlockParam from .document_block_param import DocumentBlockParam from .search_result_block_param import SearchResultBlockParam from .cache_control_ephemeral_param import CacheControlEphemeralParam __all__ = ["ToolResultBlockParam", "Content"] Content: TypeAlias = Union[TextBlockParam, ImageBlockParam, SearchResultBlockParam, DocumentBlockParam] class ToolResultBlockParam(TypedDict, total=False): tool_use_id: Required[str] type: Required[Literal["tool_result"]] cache_control: Optional[CacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" content: Union[str, Iterable[Content]] is_error: bool anthropic-sdk-python-0.69.0/src/anthropic/types/tool_text_editor_20250124_param.py000066400000000000000000000013251506653454500277330ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from .cache_control_ephemeral_param import CacheControlEphemeralParam __all__ = ["ToolTextEditor20250124Param"] class ToolTextEditor20250124Param(TypedDict, total=False): name: Required[Literal["str_replace_editor"]] """Name of the tool. This is how the tool will be called by the model and in `tool_use` blocks. """ type: Required[Literal["text_editor_20250124"]] cache_control: Optional[CacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" anthropic-sdk-python-0.69.0/src/anthropic/types/tool_text_editor_20250429_param.py000066400000000000000000000013361506653454500277450ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from .cache_control_ephemeral_param import CacheControlEphemeralParam __all__ = ["ToolTextEditor20250429Param"] class ToolTextEditor20250429Param(TypedDict, total=False): name: Required[Literal["str_replace_based_edit_tool"]] """Name of the tool. This is how the tool will be called by the model and in `tool_use` blocks. """ type: Required[Literal["text_editor_20250429"]] cache_control: Optional[CacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" anthropic-sdk-python-0.69.0/src/anthropic/types/tool_text_editor_20250728_param.py000066400000000000000000000016121506653454500277440ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from .cache_control_ephemeral_param import CacheControlEphemeralParam __all__ = ["ToolTextEditor20250728Param"] class ToolTextEditor20250728Param(TypedDict, total=False): name: Required[Literal["str_replace_based_edit_tool"]] """Name of the tool. This is how the tool will be called by the model and in `tool_use` blocks. """ type: Required[Literal["text_editor_20250728"]] cache_control: Optional[CacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" max_characters: Optional[int] """Maximum number of characters to display when viewing a file. If not specified, defaults to displaying the full file. """ anthropic-sdk-python-0.69.0/src/anthropic/types/tool_union_param.py000066400000000000000000000014561506653454500255570ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union from typing_extensions import TypeAlias from .tool_param import ToolParam from .tool_bash_20250124_param import ToolBash20250124Param from .web_search_tool_20250305_param import WebSearchTool20250305Param from .tool_text_editor_20250124_param import ToolTextEditor20250124Param from .tool_text_editor_20250429_param import ToolTextEditor20250429Param from .tool_text_editor_20250728_param import ToolTextEditor20250728Param __all__ = ["ToolUnionParam"] ToolUnionParam: TypeAlias = Union[ ToolParam, ToolBash20250124Param, ToolTextEditor20250124Param, ToolTextEditor20250429Param, ToolTextEditor20250728Param, WebSearchTool20250305Param, ] anthropic-sdk-python-0.69.0/src/anthropic/types/tool_use_block.py000066400000000000000000000004501506653454500252060ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from .._models import BaseModel __all__ = ["ToolUseBlock"] class ToolUseBlock(BaseModel): id: str input: object name: str type: Literal["tool_use"] anthropic-sdk-python-0.69.0/src/anthropic/types/tool_use_block_param.py000066400000000000000000000011361506653454500263700ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from .cache_control_ephemeral_param import CacheControlEphemeralParam __all__ = ["ToolUseBlockParam"] class ToolUseBlockParam(TypedDict, total=False): id: Required[str] input: Required[object] name: Required[str] type: Required[Literal["tool_use"]] cache_control: Optional[CacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" anthropic-sdk-python-0.69.0/src/anthropic/types/url_image_source_param.py000066400000000000000000000005111506653454500267050ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["URLImageSourceParam"] class URLImageSourceParam(TypedDict, total=False): type: Required[Literal["url"]] url: Required[str] anthropic-sdk-python-0.69.0/src/anthropic/types/url_pdf_source_param.py000066400000000000000000000005051506653454500263770ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["URLPDFSourceParam"] class URLPDFSourceParam(TypedDict, total=False): type: Required[Literal["url"]] url: Required[str] anthropic-sdk-python-0.69.0/src/anthropic/types/usage.py000066400000000000000000000020351506653454500233100ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from typing_extensions import Literal from .._models import BaseModel from .cache_creation import CacheCreation from .server_tool_usage import ServerToolUsage __all__ = ["Usage"] class Usage(BaseModel): cache_creation: Optional[CacheCreation] = None """Breakdown of cached tokens by TTL""" cache_creation_input_tokens: Optional[int] = None """The number of input tokens used to create the cache entry.""" cache_read_input_tokens: Optional[int] = None """The number of input tokens read from the cache.""" input_tokens: int """The number of input tokens which were used.""" output_tokens: int """The number of output tokens which were used.""" server_tool_use: Optional[ServerToolUsage] = None """The number of server tool requests.""" service_tier: Optional[Literal["standard", "priority", "batch"]] = None """If the request used the priority, standard, or batch tier.""" anthropic-sdk-python-0.69.0/src/anthropic/types/web_search_result_block.py000066400000000000000000000006141506653454500270570ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional from typing_extensions import Literal from .._models import BaseModel __all__ = ["WebSearchResultBlock"] class WebSearchResultBlock(BaseModel): encrypted_content: str page_age: Optional[str] = None title: str type: Literal["web_search_result"] url: str anthropic-sdk-python-0.69.0/src/anthropic/types/web_search_result_block_param.py000066400000000000000000000007341506653454500302420ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict __all__ = ["WebSearchResultBlockParam"] class WebSearchResultBlockParam(TypedDict, total=False): encrypted_content: Required[str] title: Required[str] type: Required[Literal["web_search_result"]] url: Required[str] page_age: Optional[str] anthropic-sdk-python-0.69.0/src/anthropic/types/web_search_tool_20250305_param.py000066400000000000000000000034451506653454500275110ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from .._types import SequenceNotStr from .cache_control_ephemeral_param import CacheControlEphemeralParam __all__ = ["WebSearchTool20250305Param", "UserLocation"] class UserLocation(TypedDict, total=False): type: Required[Literal["approximate"]] city: Optional[str] """The city of the user.""" country: Optional[str] """ The two letter [ISO country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) of the user. """ region: Optional[str] """The region of the user.""" timezone: Optional[str] """The [IANA timezone](https://nodatime.org/TimeZones) of the user.""" class WebSearchTool20250305Param(TypedDict, total=False): name: Required[Literal["web_search"]] """Name of the tool. This is how the tool will be called by the model and in `tool_use` blocks. """ type: Required[Literal["web_search_20250305"]] allowed_domains: Optional[SequenceNotStr[str]] """If provided, only these domains will be included in results. Cannot be used alongside `blocked_domains`. """ blocked_domains: Optional[SequenceNotStr[str]] """If provided, these domains will never appear in results. Cannot be used alongside `allowed_domains`. """ cache_control: Optional[CacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" max_uses: Optional[int] """Maximum number of times the tool can be used in the API request.""" user_location: Optional[UserLocation] """Parameters for the user's location. Used to provide more relevant search results. """ anthropic-sdk-python-0.69.0/src/anthropic/types/web_search_tool_request_error_param.py000066400000000000000000000007621506653454500315110ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing_extensions import Literal, Required, TypedDict __all__ = ["WebSearchToolRequestErrorParam"] class WebSearchToolRequestErrorParam(TypedDict, total=False): error_code: Required[ Literal["invalid_tool_input", "unavailable", "max_uses_exceeded", "too_many_requests", "query_too_long"] ] type: Required[Literal["web_search_tool_result_error"]] anthropic-sdk-python-0.69.0/src/anthropic/types/web_search_tool_result_block.py000066400000000000000000000006651506653454500301220ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from .._models import BaseModel from .web_search_tool_result_block_content import WebSearchToolResultBlockContent __all__ = ["WebSearchToolResultBlock"] class WebSearchToolResultBlock(BaseModel): content: WebSearchToolResultBlockContent tool_use_id: str type: Literal["web_search_tool_result"] anthropic-sdk-python-0.69.0/src/anthropic/types/web_search_tool_result_block_content.py000066400000000000000000000006651506653454500316540ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import List, Union from typing_extensions import TypeAlias from .web_search_result_block import WebSearchResultBlock from .web_search_tool_result_error import WebSearchToolResultError __all__ = ["WebSearchToolResultBlockContent"] WebSearchToolResultBlockContent: TypeAlias = Union[WebSearchToolResultError, List[WebSearchResultBlock]] anthropic-sdk-python-0.69.0/src/anthropic/types/web_search_tool_result_block_param.py000066400000000000000000000014011506653454500312670ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Optional from typing_extensions import Literal, Required, TypedDict from .cache_control_ephemeral_param import CacheControlEphemeralParam from .web_search_tool_result_block_param_content_param import WebSearchToolResultBlockParamContentParam __all__ = ["WebSearchToolResultBlockParam"] class WebSearchToolResultBlockParam(TypedDict, total=False): content: Required[WebSearchToolResultBlockParamContentParam] tool_use_id: Required[str] type: Required[Literal["web_search_tool_result"]] cache_control: Optional[CacheControlEphemeralParam] """Create a cache control breakpoint at this content block.""" anthropic-sdk-python-0.69.0/src/anthropic/types/web_search_tool_result_block_param_content_param.py000066400000000000000000000010361506653454500342050ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations from typing import Union, Iterable from typing_extensions import TypeAlias from .web_search_result_block_param import WebSearchResultBlockParam from .web_search_tool_request_error_param import WebSearchToolRequestErrorParam __all__ = ["WebSearchToolResultBlockParamContentParam"] WebSearchToolResultBlockParamContentParam: TypeAlias = Union[ Iterable[WebSearchResultBlockParam], WebSearchToolRequestErrorParam ] anthropic-sdk-python-0.69.0/src/anthropic/types/web_search_tool_result_error.py000066400000000000000000000006371506653454500301600ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing_extensions import Literal from .._models import BaseModel __all__ = ["WebSearchToolResultError"] class WebSearchToolResultError(BaseModel): error_code: Literal["invalid_tool_input", "unavailable", "max_uses_exceeded", "too_many_requests", "query_too_long"] type: Literal["web_search_tool_result_error"] anthropic-sdk-python-0.69.0/tests/000077500000000000000000000000001506653454500170525ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/tests/__init__.py000066400000000000000000000001261506653454500211620ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. anthropic-sdk-python-0.69.0/tests/api_resources/000077500000000000000000000000001506653454500217155ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/tests/api_resources/__init__.py000066400000000000000000000001261506653454500240250ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. anthropic-sdk-python-0.69.0/tests/api_resources/beta/000077500000000000000000000000001506653454500226305ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/tests/api_resources/beta/__init__.py000066400000000000000000000001261506653454500247400ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. anthropic-sdk-python-0.69.0/tests/api_resources/beta/messages/000077500000000000000000000000001506653454500244375ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/tests/api_resources/beta/messages/__init__.py000066400000000000000000000001261506653454500265470ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. anthropic-sdk-python-0.69.0/tests/api_resources/beta/messages/test_batches.py000066400000000000000000001062221506653454500274640ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations import os import json from typing import Any, cast import httpx import pytest from respx import MockRouter from anthropic import Anthropic, AsyncAnthropic from tests.utils import assert_matches_type from anthropic.pagination import SyncPage, AsyncPage from anthropic.types.beta.messages import ( BetaMessageBatch, BetaDeletedMessageBatch, ) base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") class TestBatches: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize def test_method_create(self, client: Anthropic) -> None: batch = client.beta.messages.batches.create( requests=[ { "custom_id": "my-custom-id-1", "params": { "max_tokens": 1024, "messages": [ { "content": "Hello, world", "role": "user", } ], "model": "claude-sonnet-4-20250514", }, } ], ) assert_matches_type(BetaMessageBatch, batch, path=["response"]) @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize def test_method_create_with_all_params(self, client: Anthropic) -> None: batch = client.beta.messages.batches.create( requests=[ { "custom_id": "my-custom-id-1", "params": { "max_tokens": 1024, "messages": [ { "content": "Hello, world", "role": "user", } ], "model": "claude-sonnet-4-20250514", "container": "container", "context_management": { "edits": [ { "type": "clear_tool_uses_20250919", "clear_at_least": { "type": "input_tokens", "value": 0, }, "clear_tool_inputs": True, "exclude_tools": ["string"], "keep": { "type": "tool_uses", "value": 0, }, "trigger": { "type": "input_tokens", "value": 1, }, } ] }, "mcp_servers": [ { "name": "name", "type": "url", "url": "url", "authorization_token": "authorization_token", "tool_configuration": { "allowed_tools": ["string"], "enabled": True, }, } ], "metadata": {"user_id": "13803d75-b4b5-4c3e-b2a2-6f21399b021b"}, "service_tier": "auto", "stop_sequences": ["string"], "stream": False, "system": [ { "text": "Today's date is 2024-06-01.", "type": "text", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "citations": [ { "cited_text": "cited_text", "document_index": 0, "document_title": "x", "end_char_index": 0, "start_char_index": 0, "type": "char_location", } ], } ], "temperature": 1, "thinking": { "budget_tokens": 1024, "type": "enabled", }, "tool_choice": { "type": "auto", "disable_parallel_tool_use": True, }, "tools": [ { "input_schema": { "type": "object", "properties": { "location": { "description": "The city and state, e.g. San Francisco, CA", "type": "string", }, "unit": { "description": "Unit for the output - one of (celsius, fahrenheit)", "type": "string", }, }, "required": ["location"], }, "name": "name", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "description": "Get the current weather in a given location", "type": "custom", } ], "top_k": 5, "top_p": 0.7, }, } ], betas=["string"], ) assert_matches_type(BetaMessageBatch, batch, path=["response"]) @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize def test_raw_response_create(self, client: Anthropic) -> None: response = client.beta.messages.batches.with_raw_response.create( requests=[ { "custom_id": "my-custom-id-1", "params": { "max_tokens": 1024, "messages": [ { "content": "Hello, world", "role": "user", } ], "model": "claude-sonnet-4-20250514", }, } ], ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(BetaMessageBatch, batch, path=["response"]) @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize def test_streaming_response_create(self, client: Anthropic) -> None: with client.beta.messages.batches.with_streaming_response.create( requests=[ { "custom_id": "my-custom-id-1", "params": { "max_tokens": 1024, "messages": [ { "content": "Hello, world", "role": "user", } ], "model": "claude-sonnet-4-20250514", }, } ], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(BetaMessageBatch, batch, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize def test_method_retrieve(self, client: Anthropic) -> None: batch = client.beta.messages.batches.retrieve( message_batch_id="message_batch_id", ) assert_matches_type(BetaMessageBatch, batch, path=["response"]) @parametrize def test_method_retrieve_with_all_params(self, client: Anthropic) -> None: batch = client.beta.messages.batches.retrieve( message_batch_id="message_batch_id", betas=["string"], ) assert_matches_type(BetaMessageBatch, batch, path=["response"]) @parametrize def test_raw_response_retrieve(self, client: Anthropic) -> None: response = client.beta.messages.batches.with_raw_response.retrieve( message_batch_id="message_batch_id", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(BetaMessageBatch, batch, path=["response"]) @parametrize def test_streaming_response_retrieve(self, client: Anthropic) -> None: with client.beta.messages.batches.with_streaming_response.retrieve( message_batch_id="message_batch_id", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(BetaMessageBatch, batch, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize def test_path_params_retrieve(self, client: Anthropic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `message_batch_id` but received ''"): client.beta.messages.batches.with_raw_response.retrieve( message_batch_id="", ) @parametrize def test_method_list(self, client: Anthropic) -> None: batch = client.beta.messages.batches.list() assert_matches_type(SyncPage[BetaMessageBatch], batch, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Anthropic) -> None: batch = client.beta.messages.batches.list( after_id="after_id", before_id="before_id", limit=1, betas=["string"], ) assert_matches_type(SyncPage[BetaMessageBatch], batch, path=["response"]) @parametrize def test_raw_response_list(self, client: Anthropic) -> None: response = client.beta.messages.batches.with_raw_response.list() assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(SyncPage[BetaMessageBatch], batch, path=["response"]) @parametrize def test_streaming_response_list(self, client: Anthropic) -> None: with client.beta.messages.batches.with_streaming_response.list() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(SyncPage[BetaMessageBatch], batch, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize def test_method_delete(self, client: Anthropic) -> None: batch = client.beta.messages.batches.delete( message_batch_id="message_batch_id", ) assert_matches_type(BetaDeletedMessageBatch, batch, path=["response"]) @parametrize def test_method_delete_with_all_params(self, client: Anthropic) -> None: batch = client.beta.messages.batches.delete( message_batch_id="message_batch_id", betas=["string"], ) assert_matches_type(BetaDeletedMessageBatch, batch, path=["response"]) @parametrize def test_raw_response_delete(self, client: Anthropic) -> None: response = client.beta.messages.batches.with_raw_response.delete( message_batch_id="message_batch_id", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(BetaDeletedMessageBatch, batch, path=["response"]) @parametrize def test_streaming_response_delete(self, client: Anthropic) -> None: with client.beta.messages.batches.with_streaming_response.delete( message_batch_id="message_batch_id", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(BetaDeletedMessageBatch, batch, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize def test_path_params_delete(self, client: Anthropic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `message_batch_id` but received ''"): client.beta.messages.batches.with_raw_response.delete( message_batch_id="", ) @parametrize def test_method_cancel(self, client: Anthropic) -> None: batch = client.beta.messages.batches.cancel( message_batch_id="message_batch_id", ) assert_matches_type(BetaMessageBatch, batch, path=["response"]) @parametrize def test_method_cancel_with_all_params(self, client: Anthropic) -> None: batch = client.beta.messages.batches.cancel( message_batch_id="message_batch_id", betas=["string"], ) assert_matches_type(BetaMessageBatch, batch, path=["response"]) @parametrize def test_raw_response_cancel(self, client: Anthropic) -> None: response = client.beta.messages.batches.with_raw_response.cancel( message_batch_id="message_batch_id", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(BetaMessageBatch, batch, path=["response"]) @parametrize def test_streaming_response_cancel(self, client: Anthropic) -> None: with client.beta.messages.batches.with_streaming_response.cancel( message_batch_id="message_batch_id", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(BetaMessageBatch, batch, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize def test_path_params_cancel(self, client: Anthropic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `message_batch_id` but received ''"): client.beta.messages.batches.with_raw_response.cancel( message_batch_id="", ) @pytest.mark.respx(base_url=base_url) @pytest.mark.parametrize("client", [False], indirect=True) def test_method_results(self, client: Anthropic, respx_mock: MockRouter) -> None: respx_mock.get("/v1/messages/batches/message_batch_id?beta=true").mock( return_value=httpx.Response( 200, json={"results_url": "/v1/messages/batches/message_batch_id/results?beta=true"} ) ) respx_mock.get("/v1/messages/batches/message_batch_id/results?beta=true").mock( return_value=httpx.Response( 200, content="\n".join([json.dumps({"foo": "bar"}), json.dumps({"bar": "baz"})]) ) ) results = client.beta.messages.batches.results( message_batch_id="message_batch_id", ) assert results.http_response is not None assert not results.http_response.is_stream_consumed i = 0 for i, result in enumerate(results): if i == 0: assert result.to_dict() == {"foo": "bar"} elif i == 1: assert result.to_dict() == {"bar": "baz"} else: raise RuntimeError(f"iterated too many times, expected 2 times but got {i + 1}") assert i == 1 assert results.http_response.is_stream_consumed @pytest.mark.skip(reason="Prism doesn't support application/x-jsonl responses") @parametrize def test_path_params_results(self, client: Anthropic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `message_batch_id` but received ''"): client.beta.messages.batches.results( message_batch_id="", ) class TestAsyncBatches: parametrize = pytest.mark.parametrize( "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] ) @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize async def test_method_create(self, async_client: AsyncAnthropic) -> None: batch = await async_client.beta.messages.batches.create( requests=[ { "custom_id": "my-custom-id-1", "params": { "max_tokens": 1024, "messages": [ { "content": "Hello, world", "role": "user", } ], "model": "claude-sonnet-4-20250514", }, } ], ) assert_matches_type(BetaMessageBatch, batch, path=["response"]) @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize async def test_method_create_with_all_params(self, async_client: AsyncAnthropic) -> None: batch = await async_client.beta.messages.batches.create( requests=[ { "custom_id": "my-custom-id-1", "params": { "max_tokens": 1024, "messages": [ { "content": "Hello, world", "role": "user", } ], "model": "claude-sonnet-4-20250514", "container": "container", "context_management": { "edits": [ { "type": "clear_tool_uses_20250919", "clear_at_least": { "type": "input_tokens", "value": 0, }, "clear_tool_inputs": True, "exclude_tools": ["string"], "keep": { "type": "tool_uses", "value": 0, }, "trigger": { "type": "input_tokens", "value": 1, }, } ] }, "mcp_servers": [ { "name": "name", "type": "url", "url": "url", "authorization_token": "authorization_token", "tool_configuration": { "allowed_tools": ["string"], "enabled": True, }, } ], "metadata": {"user_id": "13803d75-b4b5-4c3e-b2a2-6f21399b021b"}, "service_tier": "auto", "stop_sequences": ["string"], "stream": False, "system": [ { "text": "Today's date is 2024-06-01.", "type": "text", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "citations": [ { "cited_text": "cited_text", "document_index": 0, "document_title": "x", "end_char_index": 0, "start_char_index": 0, "type": "char_location", } ], } ], "temperature": 1, "thinking": { "budget_tokens": 1024, "type": "enabled", }, "tool_choice": { "type": "auto", "disable_parallel_tool_use": True, }, "tools": [ { "input_schema": { "type": "object", "properties": { "location": { "description": "The city and state, e.g. San Francisco, CA", "type": "string", }, "unit": { "description": "Unit for the output - one of (celsius, fahrenheit)", "type": "string", }, }, "required": ["location"], }, "name": "name", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "description": "Get the current weather in a given location", "type": "custom", } ], "top_k": 5, "top_p": 0.7, }, } ], betas=["string"], ) assert_matches_type(BetaMessageBatch, batch, path=["response"]) @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize async def test_raw_response_create(self, async_client: AsyncAnthropic) -> None: response = await async_client.beta.messages.batches.with_raw_response.create( requests=[ { "custom_id": "my-custom-id-1", "params": { "max_tokens": 1024, "messages": [ { "content": "Hello, world", "role": "user", } ], "model": "claude-sonnet-4-20250514", }, } ], ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(BetaMessageBatch, batch, path=["response"]) @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize async def test_streaming_response_create(self, async_client: AsyncAnthropic) -> None: async with async_client.beta.messages.batches.with_streaming_response.create( requests=[ { "custom_id": "my-custom-id-1", "params": { "max_tokens": 1024, "messages": [ { "content": "Hello, world", "role": "user", } ], "model": "claude-sonnet-4-20250514", }, } ], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = await response.parse() assert_matches_type(BetaMessageBatch, batch, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize async def test_method_retrieve(self, async_client: AsyncAnthropic) -> None: batch = await async_client.beta.messages.batches.retrieve( message_batch_id="message_batch_id", ) assert_matches_type(BetaMessageBatch, batch, path=["response"]) @parametrize async def test_method_retrieve_with_all_params(self, async_client: AsyncAnthropic) -> None: batch = await async_client.beta.messages.batches.retrieve( message_batch_id="message_batch_id", betas=["string"], ) assert_matches_type(BetaMessageBatch, batch, path=["response"]) @parametrize async def test_raw_response_retrieve(self, async_client: AsyncAnthropic) -> None: response = await async_client.beta.messages.batches.with_raw_response.retrieve( message_batch_id="message_batch_id", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(BetaMessageBatch, batch, path=["response"]) @parametrize async def test_streaming_response_retrieve(self, async_client: AsyncAnthropic) -> None: async with async_client.beta.messages.batches.with_streaming_response.retrieve( message_batch_id="message_batch_id", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = await response.parse() assert_matches_type(BetaMessageBatch, batch, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize async def test_path_params_retrieve(self, async_client: AsyncAnthropic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `message_batch_id` but received ''"): await async_client.beta.messages.batches.with_raw_response.retrieve( message_batch_id="", ) @parametrize async def test_method_list(self, async_client: AsyncAnthropic) -> None: batch = await async_client.beta.messages.batches.list() assert_matches_type(AsyncPage[BetaMessageBatch], batch, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncAnthropic) -> None: batch = await async_client.beta.messages.batches.list( after_id="after_id", before_id="before_id", limit=1, betas=["string"], ) assert_matches_type(AsyncPage[BetaMessageBatch], batch, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncAnthropic) -> None: response = await async_client.beta.messages.batches.with_raw_response.list() assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(AsyncPage[BetaMessageBatch], batch, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncAnthropic) -> None: async with async_client.beta.messages.batches.with_streaming_response.list() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = await response.parse() assert_matches_type(AsyncPage[BetaMessageBatch], batch, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize async def test_method_delete(self, async_client: AsyncAnthropic) -> None: batch = await async_client.beta.messages.batches.delete( message_batch_id="message_batch_id", ) assert_matches_type(BetaDeletedMessageBatch, batch, path=["response"]) @parametrize async def test_method_delete_with_all_params(self, async_client: AsyncAnthropic) -> None: batch = await async_client.beta.messages.batches.delete( message_batch_id="message_batch_id", betas=["string"], ) assert_matches_type(BetaDeletedMessageBatch, batch, path=["response"]) @parametrize async def test_raw_response_delete(self, async_client: AsyncAnthropic) -> None: response = await async_client.beta.messages.batches.with_raw_response.delete( message_batch_id="message_batch_id", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(BetaDeletedMessageBatch, batch, path=["response"]) @parametrize async def test_streaming_response_delete(self, async_client: AsyncAnthropic) -> None: async with async_client.beta.messages.batches.with_streaming_response.delete( message_batch_id="message_batch_id", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = await response.parse() assert_matches_type(BetaDeletedMessageBatch, batch, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize async def test_path_params_delete(self, async_client: AsyncAnthropic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `message_batch_id` but received ''"): await async_client.beta.messages.batches.with_raw_response.delete( message_batch_id="", ) @parametrize async def test_method_cancel(self, async_client: AsyncAnthropic) -> None: batch = await async_client.beta.messages.batches.cancel( message_batch_id="message_batch_id", ) assert_matches_type(BetaMessageBatch, batch, path=["response"]) @parametrize async def test_method_cancel_with_all_params(self, async_client: AsyncAnthropic) -> None: batch = await async_client.beta.messages.batches.cancel( message_batch_id="message_batch_id", betas=["string"], ) assert_matches_type(BetaMessageBatch, batch, path=["response"]) @parametrize async def test_raw_response_cancel(self, async_client: AsyncAnthropic) -> None: response = await async_client.beta.messages.batches.with_raw_response.cancel( message_batch_id="message_batch_id", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(BetaMessageBatch, batch, path=["response"]) @parametrize async def test_streaming_response_cancel(self, async_client: AsyncAnthropic) -> None: async with async_client.beta.messages.batches.with_streaming_response.cancel( message_batch_id="message_batch_id", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = await response.parse() assert_matches_type(BetaMessageBatch, batch, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize async def test_path_params_cancel(self, async_client: AsyncAnthropic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `message_batch_id` but received ''"): await async_client.beta.messages.batches.with_raw_response.cancel( message_batch_id="", ) @pytest.mark.respx(base_url=base_url) @pytest.mark.parametrize("async_client", [False], indirect=True) async def test_method_results(self, async_client: AsyncAnthropic, respx_mock: MockRouter) -> None: respx_mock.get("/v1/messages/batches/message_batch_id?beta=true").mock( return_value=httpx.Response( 200, json={"results_url": "/v1/messages/batches/message_batch_id/results?beta=true"} ) ) respx_mock.get("/v1/messages/batches/message_batch_id/results?beta=true").mock( return_value=httpx.Response( 200, content="\n".join([json.dumps({"foo": "bar"}), json.dumps({"bar": "baz"})]) ) ) results = await async_client.beta.messages.batches.results( message_batch_id="message_batch_id", ) assert results.http_response is not None assert not results.http_response.is_stream_consumed i = -1 async for result in results: i += 1 if i == 0: assert result.to_dict() == {"foo": "bar"} elif i == 1: assert result.to_dict() == {"bar": "baz"} else: raise RuntimeError(f"iterated too many times, expected 2 times but got {i + 1}") assert i == 1 assert results.http_response.is_stream_consumed @pytest.mark.skip(reason="Prism doesn't support application/x-jsonl responses") @parametrize async def test_path_params_results(self, async_client: AsyncAnthropic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `message_batch_id` but received ''"): await async_client.beta.messages.batches.results( message_batch_id="", ) anthropic-sdk-python-0.69.0/tests/api_resources/beta/test_files.py000066400000000000000000000471551506653454500253570ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations import os from typing import Any, cast import httpx import pytest from respx import MockRouter from anthropic import Anthropic, AsyncAnthropic from tests.utils import assert_matches_type from anthropic._response import ( BinaryAPIResponse, AsyncBinaryAPIResponse, StreamedBinaryAPIResponse, AsyncStreamedBinaryAPIResponse, ) from anthropic.pagination import SyncPage, AsyncPage from anthropic.types.beta import DeletedFile, FileMetadata # pyright: reportDeprecated=false base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") class TestFiles: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize def test_method_list(self, client: Anthropic) -> None: file = client.beta.files.list() assert_matches_type(SyncPage[FileMetadata], file, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Anthropic) -> None: file = client.beta.files.list( after_id="after_id", before_id="before_id", limit=1, betas=["string"], ) assert_matches_type(SyncPage[FileMetadata], file, path=["response"]) @parametrize def test_raw_response_list(self, client: Anthropic) -> None: response = client.beta.files.with_raw_response.list() assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" file = response.parse() assert_matches_type(SyncPage[FileMetadata], file, path=["response"]) @parametrize def test_streaming_response_list(self, client: Anthropic) -> None: with client.beta.files.with_streaming_response.list() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" file = response.parse() assert_matches_type(SyncPage[FileMetadata], file, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize def test_method_delete(self, client: Anthropic) -> None: file = client.beta.files.delete( file_id="file_id", ) assert_matches_type(DeletedFile, file, path=["response"]) @parametrize def test_method_delete_with_all_params(self, client: Anthropic) -> None: file = client.beta.files.delete( file_id="file_id", betas=["string"], ) assert_matches_type(DeletedFile, file, path=["response"]) @parametrize def test_raw_response_delete(self, client: Anthropic) -> None: response = client.beta.files.with_raw_response.delete( file_id="file_id", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" file = response.parse() assert_matches_type(DeletedFile, file, path=["response"]) @parametrize def test_streaming_response_delete(self, client: Anthropic) -> None: with client.beta.files.with_streaming_response.delete( file_id="file_id", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" file = response.parse() assert_matches_type(DeletedFile, file, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize def test_path_params_delete(self, client: Anthropic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `file_id` but received ''"): client.beta.files.with_raw_response.delete( file_id="", ) @parametrize @pytest.mark.respx(base_url=base_url) def test_method_download(self, client: Anthropic, respx_mock: MockRouter) -> None: respx_mock.get("/v1/files/file_id/content?beta=true").mock( return_value=httpx.Response(200, json={"foo": "bar"}) ) file = client.beta.files.download( file_id="file_id", ) assert file.is_closed assert file.json() == {"foo": "bar"} assert cast(Any, file.is_closed) is True assert isinstance(file, BinaryAPIResponse) @parametrize @pytest.mark.respx(base_url=base_url) def test_method_download_with_all_params(self, client: Anthropic, respx_mock: MockRouter) -> None: respx_mock.get("/v1/files/file_id/content?beta=true").mock( return_value=httpx.Response(200, json={"foo": "bar"}) ) file = client.beta.files.download( file_id="file_id", betas=["string"], ) assert file.is_closed assert file.json() == {"foo": "bar"} assert cast(Any, file.is_closed) is True assert isinstance(file, BinaryAPIResponse) @parametrize @pytest.mark.respx(base_url=base_url) def test_raw_response_download(self, client: Anthropic, respx_mock: MockRouter) -> None: respx_mock.get("/v1/files/file_id/content?beta=true").mock( return_value=httpx.Response(200, json={"foo": "bar"}) ) file = client.beta.files.with_raw_response.download( file_id="file_id", ) assert file.is_closed is True assert file.http_request.headers.get("X-Stainless-Lang") == "python" assert file.json() == {"foo": "bar"} assert isinstance(file, BinaryAPIResponse) @parametrize @pytest.mark.respx(base_url=base_url) def test_streaming_response_download(self, client: Anthropic, respx_mock: MockRouter) -> None: respx_mock.get("/v1/files/file_id/content?beta=true").mock( return_value=httpx.Response(200, json={"foo": "bar"}) ) with client.beta.files.with_streaming_response.download( file_id="file_id", ) as file: assert not file.is_closed assert file.http_request.headers.get("X-Stainless-Lang") == "python" assert file.json() == {"foo": "bar"} assert cast(Any, file.is_closed) is True assert isinstance(file, StreamedBinaryAPIResponse) assert cast(Any, file.is_closed) is True @parametrize @pytest.mark.respx(base_url=base_url) def test_path_params_download(self, client: Anthropic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `file_id` but received ''"): client.beta.files.with_raw_response.download( file_id="", ) @parametrize def test_method_retrieve_metadata(self, client: Anthropic) -> None: file = client.beta.files.retrieve_metadata( file_id="file_id", ) assert_matches_type(FileMetadata, file, path=["response"]) @parametrize def test_method_retrieve_metadata_with_all_params(self, client: Anthropic) -> None: file = client.beta.files.retrieve_metadata( file_id="file_id", betas=["string"], ) assert_matches_type(FileMetadata, file, path=["response"]) @parametrize def test_raw_response_retrieve_metadata(self, client: Anthropic) -> None: response = client.beta.files.with_raw_response.retrieve_metadata( file_id="file_id", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" file = response.parse() assert_matches_type(FileMetadata, file, path=["response"]) @parametrize def test_streaming_response_retrieve_metadata(self, client: Anthropic) -> None: with client.beta.files.with_streaming_response.retrieve_metadata( file_id="file_id", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" file = response.parse() assert_matches_type(FileMetadata, file, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize def test_path_params_retrieve_metadata(self, client: Anthropic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `file_id` but received ''"): client.beta.files.with_raw_response.retrieve_metadata( file_id="", ) @parametrize def test_method_upload(self, client: Anthropic) -> None: file = client.beta.files.upload( file=b"raw file contents", ) assert_matches_type(FileMetadata, file, path=["response"]) @parametrize def test_method_upload_with_all_params(self, client: Anthropic) -> None: file = client.beta.files.upload( file=b"raw file contents", betas=["string"], ) assert_matches_type(FileMetadata, file, path=["response"]) @parametrize def test_raw_response_upload(self, client: Anthropic) -> None: response = client.beta.files.with_raw_response.upload( file=b"raw file contents", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" file = response.parse() assert_matches_type(FileMetadata, file, path=["response"]) @parametrize def test_streaming_response_upload(self, client: Anthropic) -> None: with client.beta.files.with_streaming_response.upload( file=b"raw file contents", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" file = response.parse() assert_matches_type(FileMetadata, file, path=["response"]) assert cast(Any, response.is_closed) is True class TestAsyncFiles: parametrize = pytest.mark.parametrize( "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] ) @parametrize async def test_method_list(self, async_client: AsyncAnthropic) -> None: file = await async_client.beta.files.list() assert_matches_type(AsyncPage[FileMetadata], file, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncAnthropic) -> None: file = await async_client.beta.files.list( after_id="after_id", before_id="before_id", limit=1, betas=["string"], ) assert_matches_type(AsyncPage[FileMetadata], file, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncAnthropic) -> None: response = await async_client.beta.files.with_raw_response.list() assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" file = response.parse() assert_matches_type(AsyncPage[FileMetadata], file, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncAnthropic) -> None: async with async_client.beta.files.with_streaming_response.list() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" file = await response.parse() assert_matches_type(AsyncPage[FileMetadata], file, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize async def test_method_delete(self, async_client: AsyncAnthropic) -> None: file = await async_client.beta.files.delete( file_id="file_id", ) assert_matches_type(DeletedFile, file, path=["response"]) @parametrize async def test_method_delete_with_all_params(self, async_client: AsyncAnthropic) -> None: file = await async_client.beta.files.delete( file_id="file_id", betas=["string"], ) assert_matches_type(DeletedFile, file, path=["response"]) @parametrize async def test_raw_response_delete(self, async_client: AsyncAnthropic) -> None: response = await async_client.beta.files.with_raw_response.delete( file_id="file_id", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" file = response.parse() assert_matches_type(DeletedFile, file, path=["response"]) @parametrize async def test_streaming_response_delete(self, async_client: AsyncAnthropic) -> None: async with async_client.beta.files.with_streaming_response.delete( file_id="file_id", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" file = await response.parse() assert_matches_type(DeletedFile, file, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize async def test_path_params_delete(self, async_client: AsyncAnthropic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `file_id` but received ''"): await async_client.beta.files.with_raw_response.delete( file_id="", ) @parametrize @pytest.mark.respx(base_url=base_url) async def test_method_download(self, async_client: AsyncAnthropic, respx_mock: MockRouter) -> None: respx_mock.get("/v1/files/file_id/content?beta=true").mock( return_value=httpx.Response(200, json={"foo": "bar"}) ) file = await async_client.beta.files.download( file_id="file_id", ) assert file.is_closed assert await file.json() == {"foo": "bar"} assert cast(Any, file.is_closed) is True assert isinstance(file, AsyncBinaryAPIResponse) @parametrize @pytest.mark.respx(base_url=base_url) async def test_method_download_with_all_params(self, async_client: AsyncAnthropic, respx_mock: MockRouter) -> None: respx_mock.get("/v1/files/file_id/content?beta=true").mock( return_value=httpx.Response(200, json={"foo": "bar"}) ) file = await async_client.beta.files.download( file_id="file_id", betas=["string"], ) assert file.is_closed assert await file.json() == {"foo": "bar"} assert cast(Any, file.is_closed) is True assert isinstance(file, AsyncBinaryAPIResponse) @parametrize @pytest.mark.respx(base_url=base_url) async def test_raw_response_download(self, async_client: AsyncAnthropic, respx_mock: MockRouter) -> None: respx_mock.get("/v1/files/file_id/content?beta=true").mock( return_value=httpx.Response(200, json={"foo": "bar"}) ) file = await async_client.beta.files.with_raw_response.download( file_id="file_id", ) assert file.is_closed is True assert file.http_request.headers.get("X-Stainless-Lang") == "python" assert await file.json() == {"foo": "bar"} assert isinstance(file, AsyncBinaryAPIResponse) @parametrize @pytest.mark.respx(base_url=base_url) async def test_streaming_response_download(self, async_client: AsyncAnthropic, respx_mock: MockRouter) -> None: respx_mock.get("/v1/files/file_id/content?beta=true").mock( return_value=httpx.Response(200, json={"foo": "bar"}) ) async with async_client.beta.files.with_streaming_response.download( file_id="file_id", ) as file: assert not file.is_closed assert file.http_request.headers.get("X-Stainless-Lang") == "python" assert await file.json() == {"foo": "bar"} assert cast(Any, file.is_closed) is True assert isinstance(file, AsyncStreamedBinaryAPIResponse) assert cast(Any, file.is_closed) is True @parametrize @pytest.mark.respx(base_url=base_url) async def test_path_params_download(self, async_client: AsyncAnthropic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `file_id` but received ''"): await async_client.beta.files.with_raw_response.download( file_id="", ) @parametrize async def test_method_retrieve_metadata(self, async_client: AsyncAnthropic) -> None: file = await async_client.beta.files.retrieve_metadata( file_id="file_id", ) assert_matches_type(FileMetadata, file, path=["response"]) @parametrize async def test_method_retrieve_metadata_with_all_params(self, async_client: AsyncAnthropic) -> None: file = await async_client.beta.files.retrieve_metadata( file_id="file_id", betas=["string"], ) assert_matches_type(FileMetadata, file, path=["response"]) @parametrize async def test_raw_response_retrieve_metadata(self, async_client: AsyncAnthropic) -> None: response = await async_client.beta.files.with_raw_response.retrieve_metadata( file_id="file_id", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" file = response.parse() assert_matches_type(FileMetadata, file, path=["response"]) @parametrize async def test_streaming_response_retrieve_metadata(self, async_client: AsyncAnthropic) -> None: async with async_client.beta.files.with_streaming_response.retrieve_metadata( file_id="file_id", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" file = await response.parse() assert_matches_type(FileMetadata, file, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize async def test_path_params_retrieve_metadata(self, async_client: AsyncAnthropic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `file_id` but received ''"): await async_client.beta.files.with_raw_response.retrieve_metadata( file_id="", ) @parametrize async def test_method_upload(self, async_client: AsyncAnthropic) -> None: file = await async_client.beta.files.upload( file=b"raw file contents", ) assert_matches_type(FileMetadata, file, path=["response"]) @parametrize async def test_method_upload_with_all_params(self, async_client: AsyncAnthropic) -> None: file = await async_client.beta.files.upload( file=b"raw file contents", betas=["string"], ) assert_matches_type(FileMetadata, file, path=["response"]) @parametrize async def test_raw_response_upload(self, async_client: AsyncAnthropic) -> None: response = await async_client.beta.files.with_raw_response.upload( file=b"raw file contents", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" file = response.parse() assert_matches_type(FileMetadata, file, path=["response"]) @parametrize async def test_streaming_response_upload(self, async_client: AsyncAnthropic) -> None: async with async_client.beta.files.with_streaming_response.upload( file=b"raw file contents", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" file = await response.parse() assert_matches_type(FileMetadata, file, path=["response"]) assert cast(Any, response.is_closed) is True anthropic-sdk-python-0.69.0/tests/api_resources/beta/test_messages.py000066400000000000000000001072611506653454500260570ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations import os from typing import Any, cast import pytest from anthropic import Anthropic, AsyncAnthropic from tests.utils import assert_matches_type from anthropic.types.beta import ( BetaMessage, BetaMessageTokensCount, ) base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") class TestMessages: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize def test_method_create_overload_1(self, client: Anthropic) -> None: message = client.beta.messages.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", ) assert_matches_type(BetaMessage, message, path=["response"]) @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize def test_method_create_with_all_params_overload_1(self, client: Anthropic) -> None: message = client.beta.messages.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", container="container", context_management={ "edits": [ { "type": "clear_tool_uses_20250919", "clear_at_least": { "type": "input_tokens", "value": 0, }, "clear_tool_inputs": True, "exclude_tools": ["string"], "keep": { "type": "tool_uses", "value": 0, }, "trigger": { "type": "input_tokens", "value": 1, }, } ] }, mcp_servers=[ { "name": "name", "type": "url", "url": "url", "authorization_token": "authorization_token", "tool_configuration": { "allowed_tools": ["string"], "enabled": True, }, } ], metadata={"user_id": "13803d75-b4b5-4c3e-b2a2-6f21399b021b"}, service_tier="auto", stop_sequences=["string"], stream=False, system=[ { "text": "Today's date is 2024-06-01.", "type": "text", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "citations": [ { "cited_text": "cited_text", "document_index": 0, "document_title": "x", "end_char_index": 0, "start_char_index": 0, "type": "char_location", } ], } ], temperature=1, thinking={ "budget_tokens": 1024, "type": "enabled", }, tool_choice={ "type": "auto", "disable_parallel_tool_use": True, }, tools=[ { "input_schema": { "type": "object", "properties": { "location": { "description": "The city and state, e.g. San Francisco, CA", "type": "string", }, "unit": { "description": "Unit for the output - one of (celsius, fahrenheit)", "type": "string", }, }, "required": ["location"], }, "name": "name", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "description": "Get the current weather in a given location", "type": "custom", } ], top_k=5, top_p=0.7, betas=["string"], ) assert_matches_type(BetaMessage, message, path=["response"]) @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize def test_raw_response_create_overload_1(self, client: Anthropic) -> None: response = client.beta.messages.with_raw_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" message = response.parse() assert_matches_type(BetaMessage, message, path=["response"]) @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize def test_streaming_response_create_overload_1(self, client: Anthropic) -> None: with client.beta.messages.with_streaming_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" message = response.parse() assert_matches_type(BetaMessage, message, path=["response"]) assert cast(Any, response.is_closed) is True @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize def test_method_create_overload_2(self, client: Anthropic) -> None: message_stream = client.beta.messages.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", stream=True, ) message_stream.response.close() @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize def test_method_create_with_all_params_overload_2(self, client: Anthropic) -> None: message_stream = client.beta.messages.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", stream=True, container="container", context_management={ "edits": [ { "type": "clear_tool_uses_20250919", "clear_at_least": { "type": "input_tokens", "value": 0, }, "clear_tool_inputs": True, "exclude_tools": ["string"], "keep": { "type": "tool_uses", "value": 0, }, "trigger": { "type": "input_tokens", "value": 1, }, } ] }, mcp_servers=[ { "name": "name", "type": "url", "url": "url", "authorization_token": "authorization_token", "tool_configuration": { "allowed_tools": ["string"], "enabled": True, }, } ], metadata={"user_id": "13803d75-b4b5-4c3e-b2a2-6f21399b021b"}, service_tier="auto", stop_sequences=["string"], system=[ { "text": "Today's date is 2024-06-01.", "type": "text", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "citations": [ { "cited_text": "cited_text", "document_index": 0, "document_title": "x", "end_char_index": 0, "start_char_index": 0, "type": "char_location", } ], } ], temperature=1, thinking={ "budget_tokens": 1024, "type": "enabled", }, tool_choice={ "type": "auto", "disable_parallel_tool_use": True, }, tools=[ { "input_schema": { "type": "object", "properties": { "location": { "description": "The city and state, e.g. San Francisco, CA", "type": "string", }, "unit": { "description": "Unit for the output - one of (celsius, fahrenheit)", "type": "string", }, }, "required": ["location"], }, "name": "name", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "description": "Get the current weather in a given location", "type": "custom", } ], top_k=5, top_p=0.7, betas=["string"], ) message_stream.response.close() @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize def test_raw_response_create_overload_2(self, client: Anthropic) -> None: response = client.beta.messages.with_raw_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", stream=True, ) assert response.http_request.headers.get("X-Stainless-Lang") == "python" stream = response.parse() stream.close() @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize def test_streaming_response_create_overload_2(self, client: Anthropic) -> None: with client.beta.messages.with_streaming_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", stream=True, ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" stream = response.parse() stream.close() assert cast(Any, response.is_closed) is True @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize def test_method_count_tokens(self, client: Anthropic) -> None: message = client.beta.messages.count_tokens( messages=[ { "content": "string", "role": "user", } ], model="claude-3-7-sonnet-latest", ) assert_matches_type(BetaMessageTokensCount, message, path=["response"]) @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize def test_method_count_tokens_with_all_params(self, client: Anthropic) -> None: message = client.beta.messages.count_tokens( messages=[ { "content": "string", "role": "user", } ], model="claude-3-7-sonnet-latest", context_management={ "edits": [ { "type": "clear_tool_uses_20250919", "clear_at_least": { "type": "input_tokens", "value": 0, }, "clear_tool_inputs": True, "exclude_tools": ["string"], "keep": { "type": "tool_uses", "value": 0, }, "trigger": { "type": "input_tokens", "value": 1, }, } ] }, mcp_servers=[ { "name": "name", "type": "url", "url": "url", "authorization_token": "authorization_token", "tool_configuration": { "allowed_tools": ["string"], "enabled": True, }, } ], system=[ { "text": "Today's date is 2024-06-01.", "type": "text", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "citations": [ { "cited_text": "cited_text", "document_index": 0, "document_title": "x", "end_char_index": 0, "start_char_index": 0, "type": "char_location", } ], } ], thinking={ "budget_tokens": 1024, "type": "enabled", }, tool_choice={ "type": "auto", "disable_parallel_tool_use": True, }, tools=[ { "input_schema": { "type": "object", "properties": { "location": { "description": "The city and state, e.g. San Francisco, CA", "type": "string", }, "unit": { "description": "Unit for the output - one of (celsius, fahrenheit)", "type": "string", }, }, "required": ["location"], }, "name": "name", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "description": "Get the current weather in a given location", "type": "custom", } ], betas=["string"], ) assert_matches_type(BetaMessageTokensCount, message, path=["response"]) @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize def test_raw_response_count_tokens(self, client: Anthropic) -> None: response = client.beta.messages.with_raw_response.count_tokens( messages=[ { "content": "string", "role": "user", } ], model="claude-3-7-sonnet-latest", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" message = response.parse() assert_matches_type(BetaMessageTokensCount, message, path=["response"]) @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize def test_streaming_response_count_tokens(self, client: Anthropic) -> None: with client.beta.messages.with_streaming_response.count_tokens( messages=[ { "content": "string", "role": "user", } ], model="claude-3-7-sonnet-latest", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" message = response.parse() assert_matches_type(BetaMessageTokensCount, message, path=["response"]) assert cast(Any, response.is_closed) is True class TestAsyncMessages: parametrize = pytest.mark.parametrize( "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] ) @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize async def test_method_create_overload_1(self, async_client: AsyncAnthropic) -> None: message = await async_client.beta.messages.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", ) assert_matches_type(BetaMessage, message, path=["response"]) @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize async def test_method_create_with_all_params_overload_1(self, async_client: AsyncAnthropic) -> None: message = await async_client.beta.messages.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", container="container", context_management={ "edits": [ { "type": "clear_tool_uses_20250919", "clear_at_least": { "type": "input_tokens", "value": 0, }, "clear_tool_inputs": True, "exclude_tools": ["string"], "keep": { "type": "tool_uses", "value": 0, }, "trigger": { "type": "input_tokens", "value": 1, }, } ] }, mcp_servers=[ { "name": "name", "type": "url", "url": "url", "authorization_token": "authorization_token", "tool_configuration": { "allowed_tools": ["string"], "enabled": True, }, } ], metadata={"user_id": "13803d75-b4b5-4c3e-b2a2-6f21399b021b"}, service_tier="auto", stop_sequences=["string"], stream=False, system=[ { "text": "Today's date is 2024-06-01.", "type": "text", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "citations": [ { "cited_text": "cited_text", "document_index": 0, "document_title": "x", "end_char_index": 0, "start_char_index": 0, "type": "char_location", } ], } ], temperature=1, thinking={ "budget_tokens": 1024, "type": "enabled", }, tool_choice={ "type": "auto", "disable_parallel_tool_use": True, }, tools=[ { "input_schema": { "type": "object", "properties": { "location": { "description": "The city and state, e.g. San Francisco, CA", "type": "string", }, "unit": { "description": "Unit for the output - one of (celsius, fahrenheit)", "type": "string", }, }, "required": ["location"], }, "name": "name", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "description": "Get the current weather in a given location", "type": "custom", } ], top_k=5, top_p=0.7, betas=["string"], ) assert_matches_type(BetaMessage, message, path=["response"]) @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize async def test_raw_response_create_overload_1(self, async_client: AsyncAnthropic) -> None: response = await async_client.beta.messages.with_raw_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" message = response.parse() assert_matches_type(BetaMessage, message, path=["response"]) @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize async def test_streaming_response_create_overload_1(self, async_client: AsyncAnthropic) -> None: async with async_client.beta.messages.with_streaming_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" message = await response.parse() assert_matches_type(BetaMessage, message, path=["response"]) assert cast(Any, response.is_closed) is True @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize async def test_method_create_overload_2(self, async_client: AsyncAnthropic) -> None: message_stream = await async_client.beta.messages.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", stream=True, ) await message_stream.response.aclose() @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize async def test_method_create_with_all_params_overload_2(self, async_client: AsyncAnthropic) -> None: message_stream = await async_client.beta.messages.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", stream=True, container="container", context_management={ "edits": [ { "type": "clear_tool_uses_20250919", "clear_at_least": { "type": "input_tokens", "value": 0, }, "clear_tool_inputs": True, "exclude_tools": ["string"], "keep": { "type": "tool_uses", "value": 0, }, "trigger": { "type": "input_tokens", "value": 1, }, } ] }, mcp_servers=[ { "name": "name", "type": "url", "url": "url", "authorization_token": "authorization_token", "tool_configuration": { "allowed_tools": ["string"], "enabled": True, }, } ], metadata={"user_id": "13803d75-b4b5-4c3e-b2a2-6f21399b021b"}, service_tier="auto", stop_sequences=["string"], system=[ { "text": "Today's date is 2024-06-01.", "type": "text", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "citations": [ { "cited_text": "cited_text", "document_index": 0, "document_title": "x", "end_char_index": 0, "start_char_index": 0, "type": "char_location", } ], } ], temperature=1, thinking={ "budget_tokens": 1024, "type": "enabled", }, tool_choice={ "type": "auto", "disable_parallel_tool_use": True, }, tools=[ { "input_schema": { "type": "object", "properties": { "location": { "description": "The city and state, e.g. San Francisco, CA", "type": "string", }, "unit": { "description": "Unit for the output - one of (celsius, fahrenheit)", "type": "string", }, }, "required": ["location"], }, "name": "name", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "description": "Get the current weather in a given location", "type": "custom", } ], top_k=5, top_p=0.7, betas=["string"], ) await message_stream.response.aclose() @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize async def test_raw_response_create_overload_2(self, async_client: AsyncAnthropic) -> None: response = await async_client.beta.messages.with_raw_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", stream=True, ) assert response.http_request.headers.get("X-Stainless-Lang") == "python" stream = response.parse() await stream.close() @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize async def test_streaming_response_create_overload_2(self, async_client: AsyncAnthropic) -> None: async with async_client.beta.messages.with_streaming_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", stream=True, ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" stream = await response.parse() await stream.close() assert cast(Any, response.is_closed) is True @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize async def test_method_count_tokens(self, async_client: AsyncAnthropic) -> None: message = await async_client.beta.messages.count_tokens( messages=[ { "content": "string", "role": "user", } ], model="claude-3-7-sonnet-latest", ) assert_matches_type(BetaMessageTokensCount, message, path=["response"]) @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize async def test_method_count_tokens_with_all_params(self, async_client: AsyncAnthropic) -> None: message = await async_client.beta.messages.count_tokens( messages=[ { "content": "string", "role": "user", } ], model="claude-3-7-sonnet-latest", context_management={ "edits": [ { "type": "clear_tool_uses_20250919", "clear_at_least": { "type": "input_tokens", "value": 0, }, "clear_tool_inputs": True, "exclude_tools": ["string"], "keep": { "type": "tool_uses", "value": 0, }, "trigger": { "type": "input_tokens", "value": 1, }, } ] }, mcp_servers=[ { "name": "name", "type": "url", "url": "url", "authorization_token": "authorization_token", "tool_configuration": { "allowed_tools": ["string"], "enabled": True, }, } ], system=[ { "text": "Today's date is 2024-06-01.", "type": "text", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "citations": [ { "cited_text": "cited_text", "document_index": 0, "document_title": "x", "end_char_index": 0, "start_char_index": 0, "type": "char_location", } ], } ], thinking={ "budget_tokens": 1024, "type": "enabled", }, tool_choice={ "type": "auto", "disable_parallel_tool_use": True, }, tools=[ { "input_schema": { "type": "object", "properties": { "location": { "description": "The city and state, e.g. San Francisco, CA", "type": "string", }, "unit": { "description": "Unit for the output - one of (celsius, fahrenheit)", "type": "string", }, }, "required": ["location"], }, "name": "name", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "description": "Get the current weather in a given location", "type": "custom", } ], betas=["string"], ) assert_matches_type(BetaMessageTokensCount, message, path=["response"]) @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize async def test_raw_response_count_tokens(self, async_client: AsyncAnthropic) -> None: response = await async_client.beta.messages.with_raw_response.count_tokens( messages=[ { "content": "string", "role": "user", } ], model="claude-3-7-sonnet-latest", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" message = response.parse() assert_matches_type(BetaMessageTokensCount, message, path=["response"]) @pytest.mark.skip(reason="prism validates based on the non-beta endpoint") @parametrize async def test_streaming_response_count_tokens(self, async_client: AsyncAnthropic) -> None: async with async_client.beta.messages.with_streaming_response.count_tokens( messages=[ { "content": "string", "role": "user", } ], model="claude-3-7-sonnet-latest", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" message = await response.parse() assert_matches_type(BetaMessageTokensCount, message, path=["response"]) assert cast(Any, response.is_closed) is True anthropic-sdk-python-0.69.0/tests/api_resources/beta/test_models.py000066400000000000000000000162161506653454500255320ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations import os from typing import Any, cast import pytest from anthropic import Anthropic, AsyncAnthropic from tests.utils import assert_matches_type from anthropic.pagination import SyncPage, AsyncPage from anthropic.types.beta import BetaModelInfo base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") class TestModels: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize def test_method_retrieve(self, client: Anthropic) -> None: model = client.beta.models.retrieve( model_id="model_id", ) assert_matches_type(BetaModelInfo, model, path=["response"]) @parametrize def test_method_retrieve_with_all_params(self, client: Anthropic) -> None: model = client.beta.models.retrieve( model_id="model_id", betas=["string"], ) assert_matches_type(BetaModelInfo, model, path=["response"]) @parametrize def test_raw_response_retrieve(self, client: Anthropic) -> None: response = client.beta.models.with_raw_response.retrieve( model_id="model_id", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" model = response.parse() assert_matches_type(BetaModelInfo, model, path=["response"]) @parametrize def test_streaming_response_retrieve(self, client: Anthropic) -> None: with client.beta.models.with_streaming_response.retrieve( model_id="model_id", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" model = response.parse() assert_matches_type(BetaModelInfo, model, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize def test_path_params_retrieve(self, client: Anthropic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `model_id` but received ''"): client.beta.models.with_raw_response.retrieve( model_id="", ) @parametrize def test_method_list(self, client: Anthropic) -> None: model = client.beta.models.list() assert_matches_type(SyncPage[BetaModelInfo], model, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Anthropic) -> None: model = client.beta.models.list( after_id="after_id", before_id="before_id", limit=1, betas=["string"], ) assert_matches_type(SyncPage[BetaModelInfo], model, path=["response"]) @parametrize def test_raw_response_list(self, client: Anthropic) -> None: response = client.beta.models.with_raw_response.list() assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" model = response.parse() assert_matches_type(SyncPage[BetaModelInfo], model, path=["response"]) @parametrize def test_streaming_response_list(self, client: Anthropic) -> None: with client.beta.models.with_streaming_response.list() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" model = response.parse() assert_matches_type(SyncPage[BetaModelInfo], model, path=["response"]) assert cast(Any, response.is_closed) is True class TestAsyncModels: parametrize = pytest.mark.parametrize( "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] ) @parametrize async def test_method_retrieve(self, async_client: AsyncAnthropic) -> None: model = await async_client.beta.models.retrieve( model_id="model_id", ) assert_matches_type(BetaModelInfo, model, path=["response"]) @parametrize async def test_method_retrieve_with_all_params(self, async_client: AsyncAnthropic) -> None: model = await async_client.beta.models.retrieve( model_id="model_id", betas=["string"], ) assert_matches_type(BetaModelInfo, model, path=["response"]) @parametrize async def test_raw_response_retrieve(self, async_client: AsyncAnthropic) -> None: response = await async_client.beta.models.with_raw_response.retrieve( model_id="model_id", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" model = response.parse() assert_matches_type(BetaModelInfo, model, path=["response"]) @parametrize async def test_streaming_response_retrieve(self, async_client: AsyncAnthropic) -> None: async with async_client.beta.models.with_streaming_response.retrieve( model_id="model_id", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" model = await response.parse() assert_matches_type(BetaModelInfo, model, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize async def test_path_params_retrieve(self, async_client: AsyncAnthropic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `model_id` but received ''"): await async_client.beta.models.with_raw_response.retrieve( model_id="", ) @parametrize async def test_method_list(self, async_client: AsyncAnthropic) -> None: model = await async_client.beta.models.list() assert_matches_type(AsyncPage[BetaModelInfo], model, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncAnthropic) -> None: model = await async_client.beta.models.list( after_id="after_id", before_id="before_id", limit=1, betas=["string"], ) assert_matches_type(AsyncPage[BetaModelInfo], model, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncAnthropic) -> None: response = await async_client.beta.models.with_raw_response.list() assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" model = response.parse() assert_matches_type(AsyncPage[BetaModelInfo], model, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncAnthropic) -> None: async with async_client.beta.models.with_streaming_response.list() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" model = await response.parse() assert_matches_type(AsyncPage[BetaModelInfo], model, path=["response"]) assert cast(Any, response.is_closed) is True anthropic-sdk-python-0.69.0/tests/api_resources/messages/000077500000000000000000000000001506653454500235245ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/tests/api_resources/messages/__init__.py000066400000000000000000000001261506653454500256340ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. anthropic-sdk-python-0.69.0/tests/api_resources/messages/test_batches.py000066400000000000000000000505651506653454500265610ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations import os import json from typing import Any, cast import httpx import pytest from respx import MockRouter from anthropic import Anthropic, AsyncAnthropic from tests.utils import assert_matches_type from anthropic.pagination import SyncPage, AsyncPage from anthropic.types.messages import ( MessageBatch, DeletedMessageBatch, ) base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") class TestBatches: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize def test_method_create(self, client: Anthropic) -> None: batch = client.messages.batches.create( requests=[ { "custom_id": "my-custom-id-1", "params": { "max_tokens": 1024, "messages": [ { "content": "Hello, world", "role": "user", } ], "model": "claude-sonnet-4-20250514", }, } ], ) assert_matches_type(MessageBatch, batch, path=["response"]) @parametrize def test_raw_response_create(self, client: Anthropic) -> None: response = client.messages.batches.with_raw_response.create( requests=[ { "custom_id": "my-custom-id-1", "params": { "max_tokens": 1024, "messages": [ { "content": "Hello, world", "role": "user", } ], "model": "claude-sonnet-4-20250514", }, } ], ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(MessageBatch, batch, path=["response"]) @parametrize def test_streaming_response_create(self, client: Anthropic) -> None: with client.messages.batches.with_streaming_response.create( requests=[ { "custom_id": "my-custom-id-1", "params": { "max_tokens": 1024, "messages": [ { "content": "Hello, world", "role": "user", } ], "model": "claude-sonnet-4-20250514", }, } ], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(MessageBatch, batch, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize def test_method_retrieve(self, client: Anthropic) -> None: batch = client.messages.batches.retrieve( "message_batch_id", ) assert_matches_type(MessageBatch, batch, path=["response"]) @parametrize def test_raw_response_retrieve(self, client: Anthropic) -> None: response = client.messages.batches.with_raw_response.retrieve( "message_batch_id", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(MessageBatch, batch, path=["response"]) @parametrize def test_streaming_response_retrieve(self, client: Anthropic) -> None: with client.messages.batches.with_streaming_response.retrieve( "message_batch_id", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(MessageBatch, batch, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize def test_path_params_retrieve(self, client: Anthropic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `message_batch_id` but received ''"): client.messages.batches.with_raw_response.retrieve( "", ) @parametrize def test_method_list(self, client: Anthropic) -> None: batch = client.messages.batches.list() assert_matches_type(SyncPage[MessageBatch], batch, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Anthropic) -> None: batch = client.messages.batches.list( after_id="after_id", before_id="before_id", limit=1, ) assert_matches_type(SyncPage[MessageBatch], batch, path=["response"]) @parametrize def test_raw_response_list(self, client: Anthropic) -> None: response = client.messages.batches.with_raw_response.list() assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(SyncPage[MessageBatch], batch, path=["response"]) @parametrize def test_streaming_response_list(self, client: Anthropic) -> None: with client.messages.batches.with_streaming_response.list() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(SyncPage[MessageBatch], batch, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize def test_method_delete(self, client: Anthropic) -> None: batch = client.messages.batches.delete( "message_batch_id", ) assert_matches_type(DeletedMessageBatch, batch, path=["response"]) @parametrize def test_raw_response_delete(self, client: Anthropic) -> None: response = client.messages.batches.with_raw_response.delete( "message_batch_id", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(DeletedMessageBatch, batch, path=["response"]) @parametrize def test_streaming_response_delete(self, client: Anthropic) -> None: with client.messages.batches.with_streaming_response.delete( "message_batch_id", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(DeletedMessageBatch, batch, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize def test_path_params_delete(self, client: Anthropic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `message_batch_id` but received ''"): client.messages.batches.with_raw_response.delete( "", ) @parametrize def test_method_cancel(self, client: Anthropic) -> None: batch = client.messages.batches.cancel( "message_batch_id", ) assert_matches_type(MessageBatch, batch, path=["response"]) @parametrize def test_raw_response_cancel(self, client: Anthropic) -> None: response = client.messages.batches.with_raw_response.cancel( "message_batch_id", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(MessageBatch, batch, path=["response"]) @parametrize def test_streaming_response_cancel(self, client: Anthropic) -> None: with client.messages.batches.with_streaming_response.cancel( "message_batch_id", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(MessageBatch, batch, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize def test_path_params_cancel(self, client: Anthropic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `message_batch_id` but received ''"): client.messages.batches.with_raw_response.cancel( "", ) @pytest.mark.respx(base_url=base_url) @pytest.mark.parametrize("client", [False], indirect=True) def test_method_results(self, client: Anthropic, respx_mock: MockRouter) -> None: respx_mock.get("/v1/messages/batches/message_batch_id").mock( return_value=httpx.Response(200, json={"results_url": "/v1/messages/batches/message_batch_id/results"}) ) respx_mock.get("/v1/messages/batches/message_batch_id/results").mock( return_value=httpx.Response( 200, content="\n".join([json.dumps({"foo": "bar"}), json.dumps({"bar": "baz"})]) ) ) results = client.beta.messages.batches.results( message_batch_id="message_batch_id", ) assert results.http_response is not None assert not results.http_response.is_stream_consumed i = -1 for result in results: i += 1 if i == 0: assert result.to_dict() == {"foo": "bar"} elif i == 1: assert result.to_dict() == {"bar": "baz"} else: raise RuntimeError(f"iterated too many times, expected 2 times but got {i + 1}") assert i == 1 assert results.http_response.is_stream_consumed class TestAsyncBatches: parametrize = pytest.mark.parametrize( "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] ) @parametrize async def test_method_create(self, async_client: AsyncAnthropic) -> None: batch = await async_client.messages.batches.create( requests=[ { "custom_id": "my-custom-id-1", "params": { "max_tokens": 1024, "messages": [ { "content": "Hello, world", "role": "user", } ], "model": "claude-sonnet-4-20250514", }, } ], ) assert_matches_type(MessageBatch, batch, path=["response"]) @parametrize async def test_raw_response_create(self, async_client: AsyncAnthropic) -> None: response = await async_client.messages.batches.with_raw_response.create( requests=[ { "custom_id": "my-custom-id-1", "params": { "max_tokens": 1024, "messages": [ { "content": "Hello, world", "role": "user", } ], "model": "claude-sonnet-4-20250514", }, } ], ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(MessageBatch, batch, path=["response"]) @parametrize async def test_streaming_response_create(self, async_client: AsyncAnthropic) -> None: async with async_client.messages.batches.with_streaming_response.create( requests=[ { "custom_id": "my-custom-id-1", "params": { "max_tokens": 1024, "messages": [ { "content": "Hello, world", "role": "user", } ], "model": "claude-sonnet-4-20250514", }, } ], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = await response.parse() assert_matches_type(MessageBatch, batch, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize async def test_method_retrieve(self, async_client: AsyncAnthropic) -> None: batch = await async_client.messages.batches.retrieve( "message_batch_id", ) assert_matches_type(MessageBatch, batch, path=["response"]) @parametrize async def test_raw_response_retrieve(self, async_client: AsyncAnthropic) -> None: response = await async_client.messages.batches.with_raw_response.retrieve( "message_batch_id", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(MessageBatch, batch, path=["response"]) @parametrize async def test_streaming_response_retrieve(self, async_client: AsyncAnthropic) -> None: async with async_client.messages.batches.with_streaming_response.retrieve( "message_batch_id", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = await response.parse() assert_matches_type(MessageBatch, batch, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize async def test_path_params_retrieve(self, async_client: AsyncAnthropic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `message_batch_id` but received ''"): await async_client.messages.batches.with_raw_response.retrieve( "", ) @parametrize async def test_method_list(self, async_client: AsyncAnthropic) -> None: batch = await async_client.messages.batches.list() assert_matches_type(AsyncPage[MessageBatch], batch, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncAnthropic) -> None: batch = await async_client.messages.batches.list( after_id="after_id", before_id="before_id", limit=1, ) assert_matches_type(AsyncPage[MessageBatch], batch, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncAnthropic) -> None: response = await async_client.messages.batches.with_raw_response.list() assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(AsyncPage[MessageBatch], batch, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncAnthropic) -> None: async with async_client.messages.batches.with_streaming_response.list() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = await response.parse() assert_matches_type(AsyncPage[MessageBatch], batch, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize async def test_method_delete(self, async_client: AsyncAnthropic) -> None: batch = await async_client.messages.batches.delete( "message_batch_id", ) assert_matches_type(DeletedMessageBatch, batch, path=["response"]) @parametrize async def test_raw_response_delete(self, async_client: AsyncAnthropic) -> None: response = await async_client.messages.batches.with_raw_response.delete( "message_batch_id", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(DeletedMessageBatch, batch, path=["response"]) @parametrize async def test_streaming_response_delete(self, async_client: AsyncAnthropic) -> None: async with async_client.messages.batches.with_streaming_response.delete( "message_batch_id", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = await response.parse() assert_matches_type(DeletedMessageBatch, batch, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize async def test_path_params_delete(self, async_client: AsyncAnthropic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `message_batch_id` but received ''"): await async_client.messages.batches.with_raw_response.delete( "", ) @parametrize async def test_method_cancel(self, async_client: AsyncAnthropic) -> None: batch = await async_client.messages.batches.cancel( "message_batch_id", ) assert_matches_type(MessageBatch, batch, path=["response"]) @parametrize async def test_raw_response_cancel(self, async_client: AsyncAnthropic) -> None: response = await async_client.messages.batches.with_raw_response.cancel( "message_batch_id", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = response.parse() assert_matches_type(MessageBatch, batch, path=["response"]) @parametrize async def test_streaming_response_cancel(self, async_client: AsyncAnthropic) -> None: async with async_client.messages.batches.with_streaming_response.cancel( "message_batch_id", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" batch = await response.parse() assert_matches_type(MessageBatch, batch, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize async def test_path_params_cancel(self, async_client: AsyncAnthropic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `message_batch_id` but received ''"): await async_client.messages.batches.with_raw_response.cancel( "", ) @pytest.mark.respx(base_url=base_url) @pytest.mark.parametrize("async_client", [False], indirect=True) async def test_method_results(self, async_client: AsyncAnthropic, respx_mock: MockRouter) -> None: respx_mock.get("/v1/messages/batches/message_batch_id").mock( return_value=httpx.Response(200, json={"results_url": "/v1/messages/batches/message_batch_id/results"}) ) respx_mock.get("/v1/messages/batches/message_batch_id/results").mock( return_value=httpx.Response( 200, content="\n".join([json.dumps({"foo": "bar"}), json.dumps({"bar": "baz"})]) ) ) results = await async_client.beta.messages.batches.results( message_batch_id="message_batch_id", ) assert results.http_response is not None assert not results.http_response.is_stream_consumed i = -1 async for result in results: i += 1 if i == 0: assert result.to_dict() == {"foo": "bar"} elif i == 1: assert result.to_dict() == {"bar": "baz"} else: raise RuntimeError(f"iterated too many times, expected 2 times but got {i + 1}") assert i == 1 assert results.http_response.is_stream_consumed anthropic-sdk-python-0.69.0/tests/api_resources/test_completions.py000066400000000000000000000223041506653454500256630ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations import os from typing import Any, cast import pytest from anthropic import Anthropic, AsyncAnthropic from tests.utils import assert_matches_type from anthropic.types import Completion base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") class TestCompletions: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize def test_method_create_overload_1(self, client: Anthropic) -> None: completion = client.completions.create( max_tokens_to_sample=256, model="claude-3-7-sonnet-latest", prompt="\n\nHuman: Hello, world!\n\nAssistant:", ) assert_matches_type(Completion, completion, path=["response"]) @parametrize def test_method_create_with_all_params_overload_1(self, client: Anthropic) -> None: completion = client.completions.create( max_tokens_to_sample=256, model="claude-3-7-sonnet-latest", prompt="\n\nHuman: Hello, world!\n\nAssistant:", metadata={"user_id": "13803d75-b4b5-4c3e-b2a2-6f21399b021b"}, stop_sequences=["string"], stream=False, temperature=1, top_k=5, top_p=0.7, betas=["string"], ) assert_matches_type(Completion, completion, path=["response"]) @parametrize def test_raw_response_create_overload_1(self, client: Anthropic) -> None: response = client.completions.with_raw_response.create( max_tokens_to_sample=256, model="claude-3-7-sonnet-latest", prompt="\n\nHuman: Hello, world!\n\nAssistant:", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" completion = response.parse() assert_matches_type(Completion, completion, path=["response"]) @parametrize def test_streaming_response_create_overload_1(self, client: Anthropic) -> None: with client.completions.with_streaming_response.create( max_tokens_to_sample=256, model="claude-3-7-sonnet-latest", prompt="\n\nHuman: Hello, world!\n\nAssistant:", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" completion = response.parse() assert_matches_type(Completion, completion, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize def test_method_create_overload_2(self, client: Anthropic) -> None: completion_stream = client.completions.create( max_tokens_to_sample=256, model="claude-3-7-sonnet-latest", prompt="\n\nHuman: Hello, world!\n\nAssistant:", stream=True, ) completion_stream.response.close() @parametrize def test_method_create_with_all_params_overload_2(self, client: Anthropic) -> None: completion_stream = client.completions.create( max_tokens_to_sample=256, model="claude-3-7-sonnet-latest", prompt="\n\nHuman: Hello, world!\n\nAssistant:", stream=True, metadata={"user_id": "13803d75-b4b5-4c3e-b2a2-6f21399b021b"}, stop_sequences=["string"], temperature=1, top_k=5, top_p=0.7, betas=["string"], ) completion_stream.response.close() @parametrize def test_raw_response_create_overload_2(self, client: Anthropic) -> None: response = client.completions.with_raw_response.create( max_tokens_to_sample=256, model="claude-3-7-sonnet-latest", prompt="\n\nHuman: Hello, world!\n\nAssistant:", stream=True, ) assert response.http_request.headers.get("X-Stainless-Lang") == "python" stream = response.parse() stream.close() @parametrize def test_streaming_response_create_overload_2(self, client: Anthropic) -> None: with client.completions.with_streaming_response.create( max_tokens_to_sample=256, model="claude-3-7-sonnet-latest", prompt="\n\nHuman: Hello, world!\n\nAssistant:", stream=True, ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" stream = response.parse() stream.close() assert cast(Any, response.is_closed) is True class TestAsyncCompletions: parametrize = pytest.mark.parametrize( "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] ) @parametrize async def test_method_create_overload_1(self, async_client: AsyncAnthropic) -> None: completion = await async_client.completions.create( max_tokens_to_sample=256, model="claude-3-7-sonnet-latest", prompt="\n\nHuman: Hello, world!\n\nAssistant:", ) assert_matches_type(Completion, completion, path=["response"]) @parametrize async def test_method_create_with_all_params_overload_1(self, async_client: AsyncAnthropic) -> None: completion = await async_client.completions.create( max_tokens_to_sample=256, model="claude-3-7-sonnet-latest", prompt="\n\nHuman: Hello, world!\n\nAssistant:", metadata={"user_id": "13803d75-b4b5-4c3e-b2a2-6f21399b021b"}, stop_sequences=["string"], stream=False, temperature=1, top_k=5, top_p=0.7, betas=["string"], ) assert_matches_type(Completion, completion, path=["response"]) @parametrize async def test_raw_response_create_overload_1(self, async_client: AsyncAnthropic) -> None: response = await async_client.completions.with_raw_response.create( max_tokens_to_sample=256, model="claude-3-7-sonnet-latest", prompt="\n\nHuman: Hello, world!\n\nAssistant:", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" completion = response.parse() assert_matches_type(Completion, completion, path=["response"]) @parametrize async def test_streaming_response_create_overload_1(self, async_client: AsyncAnthropic) -> None: async with async_client.completions.with_streaming_response.create( max_tokens_to_sample=256, model="claude-3-7-sonnet-latest", prompt="\n\nHuman: Hello, world!\n\nAssistant:", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" completion = await response.parse() assert_matches_type(Completion, completion, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize async def test_method_create_overload_2(self, async_client: AsyncAnthropic) -> None: completion_stream = await async_client.completions.create( max_tokens_to_sample=256, model="claude-3-7-sonnet-latest", prompt="\n\nHuman: Hello, world!\n\nAssistant:", stream=True, ) await completion_stream.response.aclose() @parametrize async def test_method_create_with_all_params_overload_2(self, async_client: AsyncAnthropic) -> None: completion_stream = await async_client.completions.create( max_tokens_to_sample=256, model="claude-3-7-sonnet-latest", prompt="\n\nHuman: Hello, world!\n\nAssistant:", stream=True, metadata={"user_id": "13803d75-b4b5-4c3e-b2a2-6f21399b021b"}, stop_sequences=["string"], temperature=1, top_k=5, top_p=0.7, betas=["string"], ) await completion_stream.response.aclose() @parametrize async def test_raw_response_create_overload_2(self, async_client: AsyncAnthropic) -> None: response = await async_client.completions.with_raw_response.create( max_tokens_to_sample=256, model="claude-3-7-sonnet-latest", prompt="\n\nHuman: Hello, world!\n\nAssistant:", stream=True, ) assert response.http_request.headers.get("X-Stainless-Lang") == "python" stream = response.parse() await stream.close() @parametrize async def test_streaming_response_create_overload_2(self, async_client: AsyncAnthropic) -> None: async with async_client.completions.with_streaming_response.create( max_tokens_to_sample=256, model="claude-3-7-sonnet-latest", prompt="\n\nHuman: Hello, world!\n\nAssistant:", stream=True, ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" stream = await response.parse() await stream.close() assert cast(Any, response.is_closed) is True anthropic-sdk-python-0.69.0/tests/api_resources/test_messages.py000066400000000000000000000666101506653454500251460ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations import os from typing import Any, cast import pytest from anthropic import Anthropic, AsyncAnthropic from tests.utils import assert_matches_type from anthropic.types import ( Message, MessageTokensCount, ) from anthropic.resources.messages import DEPRECATED_MODELS base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") class TestMessages: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize def test_method_create_overload_1(self, client: Anthropic) -> None: message = client.messages.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", ) assert_matches_type(Message, message, path=["response"]) @parametrize def test_method_create_with_all_params_overload_1(self, client: Anthropic) -> None: message = client.messages.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", metadata={"user_id": "13803d75-b4b5-4c3e-b2a2-6f21399b021b"}, service_tier="auto", stop_sequences=["string"], stream=False, system=[ { "text": "Today's date is 2024-06-01.", "type": "text", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "citations": [ { "cited_text": "cited_text", "document_index": 0, "document_title": "x", "end_char_index": 0, "start_char_index": 0, "type": "char_location", } ], } ], temperature=1, thinking={ "budget_tokens": 1024, "type": "enabled", }, tool_choice={ "type": "auto", "disable_parallel_tool_use": True, }, tools=[ { "input_schema": { "type": "object", "properties": { "location": { "description": "The city and state, e.g. San Francisco, CA", "type": "string", }, "unit": { "description": "Unit for the output - one of (celsius, fahrenheit)", "type": "string", }, }, "required": ["location"], }, "name": "name", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "description": "Get the current weather in a given location", "type": "custom", } ], top_k=5, top_p=0.7, ) assert_matches_type(Message, message, path=["response"]) @parametrize def test_raw_response_create_overload_1(self, client: Anthropic) -> None: response = client.messages.with_raw_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" message = response.parse() assert_matches_type(Message, message, path=["response"]) @parametrize def test_streaming_response_create_overload_1(self, client: Anthropic) -> None: with client.messages.with_streaming_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" message = response.parse() assert_matches_type(Message, message, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize def test_method_create_overload_2(self, client: Anthropic) -> None: message_stream = client.messages.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", stream=True, ) message_stream.response.close() @parametrize def test_method_create_with_all_params_overload_2(self, client: Anthropic) -> None: message_stream = client.messages.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", stream=True, metadata={"user_id": "13803d75-b4b5-4c3e-b2a2-6f21399b021b"}, service_tier="auto", stop_sequences=["string"], system=[ { "text": "Today's date is 2024-06-01.", "type": "text", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "citations": [ { "cited_text": "cited_text", "document_index": 0, "document_title": "x", "end_char_index": 0, "start_char_index": 0, "type": "char_location", } ], } ], temperature=1, thinking={ "budget_tokens": 1024, "type": "enabled", }, tool_choice={ "type": "auto", "disable_parallel_tool_use": True, }, tools=[ { "input_schema": { "type": "object", "properties": { "location": { "description": "The city and state, e.g. San Francisco, CA", "type": "string", }, "unit": { "description": "Unit for the output - one of (celsius, fahrenheit)", "type": "string", }, }, "required": ["location"], }, "name": "name", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "description": "Get the current weather in a given location", "type": "custom", } ], top_k=5, top_p=0.7, ) message_stream.response.close() @parametrize def test_raw_response_create_overload_2(self, client: Anthropic) -> None: response = client.messages.with_raw_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", stream=True, ) assert response.http_request.headers.get("X-Stainless-Lang") == "python" stream = response.parse() stream.close() @parametrize def test_streaming_response_create_overload_2(self, client: Anthropic) -> None: with client.messages.with_streaming_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", stream=True, ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" stream = response.parse() stream.close() assert cast(Any, response.is_closed) is True @parametrize def test_deprecated_model_warning(self, client: Anthropic) -> None: for deprecated_model in DEPRECATED_MODELS: with pytest.warns(DeprecationWarning, match=f"The model '{deprecated_model}' is deprecated"): client.messages.create( max_tokens=1024, messages=[{"role": "user", "content": "Hello"}], model=deprecated_model, ) @parametrize def test_method_count_tokens(self, client: Anthropic) -> None: message = client.messages.count_tokens( messages=[ { "content": "string", "role": "user", } ], model="claude-3-7-sonnet-latest", ) assert_matches_type(MessageTokensCount, message, path=["response"]) @parametrize def test_method_count_tokens_with_all_params(self, client: Anthropic) -> None: message = client.messages.count_tokens( messages=[ { "content": "string", "role": "user", } ], model="claude-3-7-sonnet-latest", system=[ { "text": "Today's date is 2024-06-01.", "type": "text", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "citations": [ { "cited_text": "cited_text", "document_index": 0, "document_title": "x", "end_char_index": 0, "start_char_index": 0, "type": "char_location", } ], } ], thinking={ "budget_tokens": 1024, "type": "enabled", }, tool_choice={ "type": "auto", "disable_parallel_tool_use": True, }, tools=[ { "input_schema": { "type": "object", "properties": { "location": { "description": "The city and state, e.g. San Francisco, CA", "type": "string", }, "unit": { "description": "Unit for the output - one of (celsius, fahrenheit)", "type": "string", }, }, "required": ["location"], }, "name": "name", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "description": "Get the current weather in a given location", "type": "custom", } ], ) assert_matches_type(MessageTokensCount, message, path=["response"]) @parametrize def test_raw_response_count_tokens(self, client: Anthropic) -> None: response = client.messages.with_raw_response.count_tokens( messages=[ { "content": "string", "role": "user", } ], model="claude-3-7-sonnet-latest", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" message = response.parse() assert_matches_type(MessageTokensCount, message, path=["response"]) @parametrize def test_streaming_response_count_tokens(self, client: Anthropic) -> None: with client.messages.with_streaming_response.count_tokens( messages=[ { "content": "string", "role": "user", } ], model="claude-3-7-sonnet-latest", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" message = response.parse() assert_matches_type(MessageTokensCount, message, path=["response"]) assert cast(Any, response.is_closed) is True class TestAsyncMessages: parametrize = pytest.mark.parametrize( "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] ) @parametrize async def test_method_create_overload_1(self, async_client: AsyncAnthropic) -> None: message = await async_client.messages.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", ) assert_matches_type(Message, message, path=["response"]) @parametrize async def test_method_create_with_all_params_overload_1(self, async_client: AsyncAnthropic) -> None: message = await async_client.messages.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", metadata={"user_id": "13803d75-b4b5-4c3e-b2a2-6f21399b021b"}, service_tier="auto", stop_sequences=["string"], stream=False, system=[ { "text": "Today's date is 2024-06-01.", "type": "text", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "citations": [ { "cited_text": "cited_text", "document_index": 0, "document_title": "x", "end_char_index": 0, "start_char_index": 0, "type": "char_location", } ], } ], temperature=1, thinking={ "budget_tokens": 1024, "type": "enabled", }, tool_choice={ "type": "auto", "disable_parallel_tool_use": True, }, tools=[ { "input_schema": { "type": "object", "properties": { "location": { "description": "The city and state, e.g. San Francisco, CA", "type": "string", }, "unit": { "description": "Unit for the output - one of (celsius, fahrenheit)", "type": "string", }, }, "required": ["location"], }, "name": "name", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "description": "Get the current weather in a given location", "type": "custom", } ], top_k=5, top_p=0.7, ) assert_matches_type(Message, message, path=["response"]) @parametrize async def test_raw_response_create_overload_1(self, async_client: AsyncAnthropic) -> None: response = await async_client.messages.with_raw_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" message = response.parse() assert_matches_type(Message, message, path=["response"]) @parametrize async def test_streaming_response_create_overload_1(self, async_client: AsyncAnthropic) -> None: async with async_client.messages.with_streaming_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" message = await response.parse() assert_matches_type(Message, message, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize async def test_method_create_overload_2(self, async_client: AsyncAnthropic) -> None: message_stream = await async_client.messages.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", stream=True, ) await message_stream.response.aclose() @parametrize async def test_method_create_with_all_params_overload_2(self, async_client: AsyncAnthropic) -> None: message_stream = await async_client.messages.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", stream=True, metadata={"user_id": "13803d75-b4b5-4c3e-b2a2-6f21399b021b"}, service_tier="auto", stop_sequences=["string"], system=[ { "text": "Today's date is 2024-06-01.", "type": "text", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "citations": [ { "cited_text": "cited_text", "document_index": 0, "document_title": "x", "end_char_index": 0, "start_char_index": 0, "type": "char_location", } ], } ], temperature=1, thinking={ "budget_tokens": 1024, "type": "enabled", }, tool_choice={ "type": "auto", "disable_parallel_tool_use": True, }, tools=[ { "input_schema": { "type": "object", "properties": { "location": { "description": "The city and state, e.g. San Francisco, CA", "type": "string", }, "unit": { "description": "Unit for the output - one of (celsius, fahrenheit)", "type": "string", }, }, "required": ["location"], }, "name": "name", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "description": "Get the current weather in a given location", "type": "custom", } ], top_k=5, top_p=0.7, ) await message_stream.response.aclose() @parametrize async def test_raw_response_create_overload_2(self, async_client: AsyncAnthropic) -> None: response = await async_client.messages.with_raw_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", stream=True, ) assert response.http_request.headers.get("X-Stainless-Lang") == "python" stream = response.parse() await stream.close() @parametrize async def test_streaming_response_create_overload_2(self, async_client: AsyncAnthropic) -> None: async with async_client.messages.with_streaming_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", stream=True, ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" stream = await response.parse() await stream.close() assert cast(Any, response.is_closed) is True @parametrize async def test_deprecated_model_warning(self, async_client: AsyncAnthropic) -> None: for deprecated_model in DEPRECATED_MODELS: with pytest.warns(DeprecationWarning, match=f"The model '{deprecated_model}' is deprecated"): await async_client.messages.create( max_tokens=1024, messages=[{"role": "user", "content": "Hello"}], model=deprecated_model, ) @parametrize async def test_method_count_tokens(self, async_client: AsyncAnthropic) -> None: message = await async_client.messages.count_tokens( messages=[ { "content": "string", "role": "user", } ], model="claude-3-7-sonnet-latest", ) assert_matches_type(MessageTokensCount, message, path=["response"]) @parametrize async def test_method_count_tokens_with_all_params(self, async_client: AsyncAnthropic) -> None: message = await async_client.messages.count_tokens( messages=[ { "content": "string", "role": "user", } ], model="claude-3-7-sonnet-latest", system=[ { "text": "Today's date is 2024-06-01.", "type": "text", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "citations": [ { "cited_text": "cited_text", "document_index": 0, "document_title": "x", "end_char_index": 0, "start_char_index": 0, "type": "char_location", } ], } ], thinking={ "budget_tokens": 1024, "type": "enabled", }, tool_choice={ "type": "auto", "disable_parallel_tool_use": True, }, tools=[ { "input_schema": { "type": "object", "properties": { "location": { "description": "The city and state, e.g. San Francisco, CA", "type": "string", }, "unit": { "description": "Unit for the output - one of (celsius, fahrenheit)", "type": "string", }, }, "required": ["location"], }, "name": "name", "cache_control": { "type": "ephemeral", "ttl": "5m", }, "description": "Get the current weather in a given location", "type": "custom", } ], ) assert_matches_type(MessageTokensCount, message, path=["response"]) @parametrize async def test_raw_response_count_tokens(self, async_client: AsyncAnthropic) -> None: response = await async_client.messages.with_raw_response.count_tokens( messages=[ { "content": "string", "role": "user", } ], model="claude-3-7-sonnet-latest", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" message = response.parse() assert_matches_type(MessageTokensCount, message, path=["response"]) @parametrize async def test_streaming_response_count_tokens(self, async_client: AsyncAnthropic) -> None: async with async_client.messages.with_streaming_response.count_tokens( messages=[ { "content": "string", "role": "user", } ], model="claude-3-7-sonnet-latest", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" message = await response.parse() assert_matches_type(MessageTokensCount, message, path=["response"]) assert cast(Any, response.is_closed) is True anthropic-sdk-python-0.69.0/tests/api_resources/test_models.py000066400000000000000000000157531506653454500246240ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations import os from typing import Any, cast import pytest from anthropic import Anthropic, AsyncAnthropic from tests.utils import assert_matches_type from anthropic.types import ModelInfo from anthropic.pagination import SyncPage, AsyncPage base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") class TestModels: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize def test_method_retrieve(self, client: Anthropic) -> None: model = client.models.retrieve( model_id="model_id", ) assert_matches_type(ModelInfo, model, path=["response"]) @parametrize def test_method_retrieve_with_all_params(self, client: Anthropic) -> None: model = client.models.retrieve( model_id="model_id", betas=["string"], ) assert_matches_type(ModelInfo, model, path=["response"]) @parametrize def test_raw_response_retrieve(self, client: Anthropic) -> None: response = client.models.with_raw_response.retrieve( model_id="model_id", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" model = response.parse() assert_matches_type(ModelInfo, model, path=["response"]) @parametrize def test_streaming_response_retrieve(self, client: Anthropic) -> None: with client.models.with_streaming_response.retrieve( model_id="model_id", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" model = response.parse() assert_matches_type(ModelInfo, model, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize def test_path_params_retrieve(self, client: Anthropic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `model_id` but received ''"): client.models.with_raw_response.retrieve( model_id="", ) @parametrize def test_method_list(self, client: Anthropic) -> None: model = client.models.list() assert_matches_type(SyncPage[ModelInfo], model, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Anthropic) -> None: model = client.models.list( after_id="after_id", before_id="before_id", limit=1, betas=["string"], ) assert_matches_type(SyncPage[ModelInfo], model, path=["response"]) @parametrize def test_raw_response_list(self, client: Anthropic) -> None: response = client.models.with_raw_response.list() assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" model = response.parse() assert_matches_type(SyncPage[ModelInfo], model, path=["response"]) @parametrize def test_streaming_response_list(self, client: Anthropic) -> None: with client.models.with_streaming_response.list() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" model = response.parse() assert_matches_type(SyncPage[ModelInfo], model, path=["response"]) assert cast(Any, response.is_closed) is True class TestAsyncModels: parametrize = pytest.mark.parametrize( "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] ) @parametrize async def test_method_retrieve(self, async_client: AsyncAnthropic) -> None: model = await async_client.models.retrieve( model_id="model_id", ) assert_matches_type(ModelInfo, model, path=["response"]) @parametrize async def test_method_retrieve_with_all_params(self, async_client: AsyncAnthropic) -> None: model = await async_client.models.retrieve( model_id="model_id", betas=["string"], ) assert_matches_type(ModelInfo, model, path=["response"]) @parametrize async def test_raw_response_retrieve(self, async_client: AsyncAnthropic) -> None: response = await async_client.models.with_raw_response.retrieve( model_id="model_id", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" model = response.parse() assert_matches_type(ModelInfo, model, path=["response"]) @parametrize async def test_streaming_response_retrieve(self, async_client: AsyncAnthropic) -> None: async with async_client.models.with_streaming_response.retrieve( model_id="model_id", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" model = await response.parse() assert_matches_type(ModelInfo, model, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize async def test_path_params_retrieve(self, async_client: AsyncAnthropic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `model_id` but received ''"): await async_client.models.with_raw_response.retrieve( model_id="", ) @parametrize async def test_method_list(self, async_client: AsyncAnthropic) -> None: model = await async_client.models.list() assert_matches_type(AsyncPage[ModelInfo], model, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncAnthropic) -> None: model = await async_client.models.list( after_id="after_id", before_id="before_id", limit=1, betas=["string"], ) assert_matches_type(AsyncPage[ModelInfo], model, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncAnthropic) -> None: response = await async_client.models.with_raw_response.list() assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" model = response.parse() assert_matches_type(AsyncPage[ModelInfo], model, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncAnthropic) -> None: async with async_client.models.with_streaming_response.list() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" model = await response.parse() assert_matches_type(AsyncPage[ModelInfo], model, path=["response"]) assert cast(Any, response.is_closed) is True anthropic-sdk-python-0.69.0/tests/conftest.py000066400000000000000000000056621506653454500212620ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations import os import logging from typing import TYPE_CHECKING, Iterator, AsyncIterator import httpx import pytest from pytest_asyncio import is_async_test from anthropic import Anthropic, AsyncAnthropic, DefaultAioHttpClient from anthropic._utils import is_dict if TYPE_CHECKING: from _pytest.fixtures import FixtureRequest # pyright: ignore[reportPrivateImportUsage] pytest.register_assert_rewrite("tests.utils") logging.getLogger("anthropic").setLevel(logging.DEBUG) # automatically add `pytest.mark.asyncio()` to all of our async tests # so we don't have to add that boilerplate everywhere def pytest_collection_modifyitems(items: list[pytest.Function]) -> None: pytest_asyncio_tests = (item for item in items if is_async_test(item)) session_scope_marker = pytest.mark.asyncio(loop_scope="session") for async_test in pytest_asyncio_tests: async_test.add_marker(session_scope_marker, append=False) # We skip tests that use both the aiohttp client and respx_mock as respx_mock # doesn't support custom transports. for item in items: if "async_client" not in item.fixturenames or "respx_mock" not in item.fixturenames: continue if not hasattr(item, "callspec"): continue async_client_param = item.callspec.params.get("async_client") if is_dict(async_client_param) and async_client_param.get("http_client") == "aiohttp": item.add_marker(pytest.mark.skip(reason="aiohttp client is not compatible with respx_mock")) base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") api_key = "my-anthropic-api-key" @pytest.fixture(scope="session") def client(request: FixtureRequest) -> Iterator[Anthropic]: strict = getattr(request, "param", True) if not isinstance(strict, bool): raise TypeError(f"Unexpected fixture parameter type {type(strict)}, expected {bool}") with Anthropic(base_url=base_url, api_key=api_key, _strict_response_validation=strict) as client: yield client @pytest.fixture(scope="session") async def async_client(request: FixtureRequest) -> AsyncIterator[AsyncAnthropic]: param = getattr(request, "param", True) # defaults strict = True http_client: None | httpx.AsyncClient = None if isinstance(param, bool): strict = param elif is_dict(param): strict = param.get("strict", True) assert isinstance(strict, bool) http_client_type = param.get("http_client", "httpx") if http_client_type == "aiohttp": http_client = DefaultAioHttpClient() else: raise TypeError(f"Unexpected fixture parameter type {type(param)}, expected bool or dict") async with AsyncAnthropic( base_url=base_url, api_key=api_key, _strict_response_validation=strict, http_client=http_client ) as client: yield client anthropic-sdk-python-0.69.0/tests/decoders/000077500000000000000000000000001506653454500206425ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/tests/decoders/test_jsonl.py000066400000000000000000000051401506653454500234000ustar00rootroot00000000000000from __future__ import annotations from typing import Any, Iterator, AsyncIterator from typing_extensions import TypeVar import httpx import pytest from anthropic._decoders.jsonl import JSONLDecoder, AsyncJSONLDecoder _T = TypeVar("_T") @pytest.mark.asyncio @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"]) async def test_basic(sync: bool) -> None: def body() -> Iterator[bytes]: yield b'{"foo":true}\n' yield b'{"bar":false}\n' iterator = make_jsonl_iterator( content=body(), sync=sync, line_type=object, ) assert await iter_next(iterator) == {"foo": True} assert await iter_next(iterator) == {"bar": False} await assert_empty_iter(iterator) @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"]) async def test_new_lines_in_json( sync: bool, ) -> None: def body() -> Iterator[bytes]: yield b'{"content":"Hello, world!\\nHow are you doing?"}' iterator = make_jsonl_iterator(content=body(), sync=sync, line_type=object) assert await iter_next(iterator) == {"content": "Hello, world!\nHow are you doing?"} @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"]) async def test_multi_byte_character_multiple_chunks( sync: bool, ) -> None: def body() -> Iterator[bytes]: yield b'{"content":"' # bytes taken from the string 'известни' and arbitrarily split # so that some multi-byte characters span multiple chunks yield b"\xd0" yield b"\xb8\xd0\xb7\xd0" yield b"\xb2\xd0\xb5\xd1\x81\xd1\x82\xd0\xbd\xd0\xb8" yield b'"}\n' iterator = make_jsonl_iterator(content=body(), sync=sync, line_type=object) assert await iter_next(iterator) == {"content": "известни"} async def to_aiter(iter: Iterator[bytes]) -> AsyncIterator[bytes]: for chunk in iter: yield chunk async def iter_next(iter: Iterator[_T] | AsyncIterator[_T]) -> _T: if isinstance(iter, AsyncIterator): return await iter.__anext__() return next(iter) async def assert_empty_iter(decoder: JSONLDecoder[Any] | AsyncJSONLDecoder[Any]) -> None: with pytest.raises((StopAsyncIteration, RuntimeError)): await iter_next(decoder) def make_jsonl_iterator( content: Iterator[bytes], *, sync: bool, line_type: type[_T], ) -> JSONLDecoder[_T] | AsyncJSONLDecoder[_T]: if sync: return JSONLDecoder(line_type=line_type, raw_iterator=content, http_response=httpx.Response(200)) return AsyncJSONLDecoder(line_type=line_type, raw_iterator=to_aiter(content), http_response=httpx.Response(200)) anthropic-sdk-python-0.69.0/tests/lib/000077500000000000000000000000001506653454500176205ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/tests/lib/__init__.py000066400000000000000000000000001506653454500217170ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/tests/lib/snapshots.py000066400000000000000000000112571506653454500222220ustar00rootroot00000000000000from __future__ import annotations import os import json from typing import Any, List, Callable, Awaitable, cast from typing_extensions import TypeVar import httpx from respx import MockRouter from inline_snapshot import outsource, get_snapshot_value from anthropic import Anthropic, AsyncAnthropic from anthropic._utils._utils import is_list _T = TypeVar("_T") def make_snapshot_request( func: Callable[[Anthropic], _T], *, content_snapshot: Any, respx_mock: MockRouter, mock_client: Anthropic, path: str, ) -> _T: live = os.environ.get("ANTHROPIC_LIVE") == "1" collected: list[str] = [] if live: def _on_response(response: httpx.Response) -> None: collected.append(json.dumps(json.loads(response.read()))) respx_mock.stop() client = Anthropic( http_client=httpx.Client( event_hooks={ "response": [_on_response], } ) ) else: responses = get_snapshot_value(content_snapshot) assert is_list(responses) curr = 0 def get_response(_request: httpx.Request) -> httpx.Response: nonlocal curr content = responses[curr] assert isinstance(content, str) curr += 1 return httpx.Response( 200, content=content, headers={"content-type": "application/json"}, ) respx_mock.post(path).mock(side_effect=get_response) client = mock_client result = func(client) if not live: return result client.close() if len(collected) == 1: assert collected[0] == content_snapshot else: assert collected == content_snapshot return result def make_stream_snapshot_request( func: Callable[[Anthropic], _T], *, content_snapshot: Any, respx_mock: MockRouter, mock_client: Anthropic, path: str, ) -> _T: live = os.environ.get("ANTHROPIC_LIVE") == "1" collected: list[str] = [] if live: def _on_response(response: httpx.Response) -> None: response.read() collected.append(response.text) respx_mock.stop() client = Anthropic( http_client=httpx.Client( event_hooks={ "response": [_on_response], } ) ) else: response_contents = get_snapshot_value(content_snapshot) assert is_list(response_contents) response_contents = cast( List[str], response_contents, ) curr = 0 def get_response(_request: httpx.Request) -> httpx.Response: nonlocal curr content = response_contents[curr] assert isinstance(content, str) curr += 1 return httpx.Response( 200, content=content.encode("utf-8"), headers={"content-type": "text/event-stream"}, ) respx_mock.post(path).mock(side_effect=get_response) client = mock_client result = func(client) if not live: return result assert outsource(collected) == content_snapshot return result async def make_async_snapshot_request( func: Callable[[AsyncAnthropic], Awaitable[_T]], *, content_snapshot: Any, respx_mock: MockRouter, mock_client: AsyncAnthropic, path: str, ) -> _T: live = os.environ.get("ANTHROPIC_LIVE") == "1" collected: list[str] = [] if live: async def _on_response(response: httpx.Response) -> None: collected.append(json.dumps(json.loads(await response.aread()))) respx_mock.stop() client = AsyncAnthropic( http_client=httpx.AsyncClient( event_hooks={ "response": [_on_response], } ) ) else: responses = get_snapshot_value(content_snapshot) assert is_list(responses) curr = 0 def get_response(_request: httpx.Request) -> httpx.Response: nonlocal curr content = responses[curr] assert isinstance(content, str) curr += 1 return httpx.Response( 200, content=content, headers={"content-type": "application/json"}, ) respx_mock.post(path).mock(side_effect=get_response) client = mock_client result = await func(client) if not live: return result await client.close() if len(collected) == 1: assert collected[0] == content_snapshot else: assert collected == content_snapshot return result anthropic-sdk-python-0.69.0/tests/lib/streaming/000077500000000000000000000000001506653454500216115ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/tests/lib/streaming/__init__.py000066400000000000000000000000001506653454500237100ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/tests/lib/streaming/fixtures/000077500000000000000000000000001506653454500234625ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/tests/lib/streaming/fixtures/basic_response.txt000066400000000000000000000020261506653454500272220ustar00rootroot00000000000000event: message_start data: {"type":"message_start","message":{"id":"msg_4QpJur2dWWDjF6C758FbBw5vm12BaVipnK","type":"message","role":"assistant","content":[],"model":"claude-3-opus-latest","stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":11,"output_tokens":1}}} event: content_block_start data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}} event: ping data: {"type": "ping"} event: content_block_delta data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hello"}} event: content_block_delta data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" there"}} event: content_block_delta data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"!"}} event: content_block_stop data: {"type":"content_block_stop","index":0} event: message_delta data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":6}} event: message_stop data: {"type":"message_stop"}anthropic-sdk-python-0.69.0/tests/lib/streaming/fixtures/incomplete_partial_json_response.txt000066400000000000000000000046201506653454500330470ustar00rootroot00000000000000event: message_start data: {"type":"message_start","message":{"id":"msg_01UdjYBBipA9omjYhicnevgq","type":"message","role":"assistant","model":"claude-3-7-sonnet-20250219","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":450,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":1,"service_tier":"standard"}} } event: content_block_start data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} } event: ping data: {"type": "ping"} event: content_block_delta data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"I"} } event: content_block_delta data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"'ll create a comprehensive tax guide for"} } event: content_block_delta data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" someone with multiple W2s an"} } event: content_block_delta data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"d save it in a file called taxes.txt. Let"} } event: content_block_delta data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" me do that for you now."} } event: content_block_stop data: {"type":"content_block_stop","index":0 } event: content_block_start data: {"type":"content_block_start","index":1,"content_block":{"type":"tool_use","id":"toolu_01EKqbqmZrGRXy18eN7m9kvY","name":"make_file","input":{}} } event: content_block_delta data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":""} } event: content_block_delta data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"{\"filename\": \"taxes.txt"} } event: content_block_delta data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"\", \"lines_of_text\": [\n\"# COMPREHENSIVE TAX GUIDE FOR INDIVIDUALS WITH MULTIPLE W-2s\",\n\"\",\n\"## INTRODUCTION\",\n\"\","} } event: content_block_delta data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"\n\"Filing taxes"} } event: message_delta data: {"type":"message_delta","delta":{"stop_reason":"max_tokens","stop_sequence":null},"usage":{"output_tokens":124} } event: message_stop data: {"type":"message_stop" }anthropic-sdk-python-0.69.0/tests/lib/streaming/fixtures/tool_use_response.txt000066400000000000000000000036651506653454500300040ustar00rootroot00000000000000event: message_start data: {"type":"message_start","message":{"id":"msg_019Q1hrJbZG26Fb9BQhrkHEr","type":"message","role":"assistant","model":"claude-sonnet-4-20250514","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":377,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":1,"service_tier":"standard"}}} event: content_block_start data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}} event: ping data: {"type": "ping"} event: content_block_delta data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"I"}} event: content_block_delta data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"'ll check the current weather in Paris for you."}} event: content_block_stop data: {"type":"content_block_stop","index":0} event: content_block_start data: {"type":"content_block_start","index":1,"content_block":{"type":"tool_use","id":"toolu_01NRLabsLyVHZPKxbKvkfSMn","name":"get_weather","input":{}}} event: content_block_delta data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":""}} event: content_block_delta data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"{\"locati"}} event: content_block_delta data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"on\": \"P"}} event: content_block_delta data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"ar"}} event: content_block_delta data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"is\"}"}} event: content_block_stop data: {"type":"content_block_stop","index":1} event: message_delta data: {"type":"message_delta","delta":{"stop_reason":"tool_use","stop_sequence":null},"usage":{"output_tokens":65}} event: message_stop data: {"type":"message_stop"}anthropic-sdk-python-0.69.0/tests/lib/streaming/helpers.py000066400000000000000000000015571506653454500236350ustar00rootroot00000000000000from __future__ import annotations import os from typing import TypeVar, Iterator from typing_extensions import AsyncIterator _T = TypeVar("_T") def load_fixture(fixture_name: str) -> str: """Load a fixture file from the fixtures directory.""" current_dir = os.path.dirname(os.path.abspath(__file__)) fixtures_dir = os.path.join(current_dir, "fixtures") with open(os.path.join(fixtures_dir, fixture_name), "r") as f: return f.read() def get_response(fixture_name: str) -> Iterator[bytes]: """Convert a fixture file into a stream of bytes for testing.""" content = load_fixture(fixture_name) for line in content.splitlines(): yield line.encode() + b"\n" async def to_async_iter(iter: Iterator[_T]) -> AsyncIterator[_T]: """Convert a synchronous iterator to an asynchronous one.""" for event in iter: yield event anthropic-sdk-python-0.69.0/tests/lib/streaming/test_beta_messages.py000066400000000000000000000354011506653454500260270ustar00rootroot00000000000000from __future__ import annotations import os import json import inspect from typing import Any, Set, Dict, TypeVar, cast from unittest import TestCase import httpx import pytest from respx import MockRouter from anthropic import Anthropic, AsyncAnthropic from anthropic._compat import PYDANTIC_V1 from anthropic.types.beta.beta_message import BetaMessage from anthropic.lib.streaming._beta_types import BetaMessageStreamEvent from anthropic.resources.messages.messages import DEPRECATED_MODELS from anthropic.lib.streaming._beta_messages import TRACKS_TOOL_INPUT, BetaMessageStream, BetaAsyncMessageStream from .helpers import get_response, to_async_iter base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") api_key = "my-anthropic-api-key" sync_client = Anthropic(base_url=base_url, api_key=api_key, _strict_response_validation=True) async_client = AsyncAnthropic(base_url=base_url, api_key=api_key, _strict_response_validation=True) _T = TypeVar("_T") # Expected message fixtures EXPECTED_BASIC_MESSAGE = { "id": "msg_4QpJur2dWWDjF6C758FbBw5vm12BaVipnK", "model": "claude-3-opus-latest", "role": "assistant", "stop_reason": "end_turn", "type": "message", "content": [{"type": "text", "text": "Hello there!"}], "usage": {"input_tokens": 11, "output_tokens": 6}, } EXPECTED_BASIC_EVENT_TYPES = [ "message_start", "content_block_start", "content_block_delta", "text", "content_block_delta", "text", "content_block_delta", "text", "content_block_stop", "message_delta", ] EXPECTED_TOOL_USE_MESSAGE = { "id": "msg_019Q1hrJbZG26Fb9BQhrkHEr", "model": "claude-sonnet-4-20250514", "role": "assistant", "stop_reason": "tool_use", "type": "message", "content": [ {"type": "text", "text": "I'll check the current weather in Paris for you."}, { "type": "tool_use", "id": "toolu_01NRLabsLyVHZPKxbKvkfSMn", "name": "get_weather", "input": {"location": "Paris"}, }, ], "usage": { "input_tokens": 377, "output_tokens": 65, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "service_tier": "standard", }, } EXPECTED_TOOL_USE_EVENT_TYPES = [ "message_start", "content_block_start", "content_block_delta", "text", "content_block_delta", "text", "content_block_stop", "content_block_start", "content_block_delta", "input_json", "content_block_delta", "input_json", "content_block_delta", "input_json", "content_block_delta", "input_json", "content_block_delta", "input_json", "content_block_stop", "message_delta", ] EXPECTED_INCOMPLETE_MESSAGE = { "id": "msg_01UdjYBBipA9omjYhicnevgq", "model": "claude-3-7-sonnet-20250219", "role": "assistant", "stop_reason": "max_tokens", "type": "message", "content": [ { "type": "text", "text": "I'll create a comprehensive tax guide for someone with multiple W2s and save it in a file called taxes.txt. Let me do that for you now.", }, { "type": "tool_use", "id": "toolu_01EKqbqmZrGRXy18eN7m9kvY", "name": "make_file", "input": { "filename": "taxes.txt", "lines_of_text": [ "# COMPREHENSIVE TAX GUIDE FOR INDIVIDUALS WITH MULTIPLE W-2s", "", "## INTRODUCTION", "", ], }, }, ], "usage": { "input_tokens": 450, "output_tokens": 124, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "service_tier": "standard", }, } EXPECTED_INCOMPLETE_EVENT_TYPES = [ "message_start", "content_block_start", "content_block_delta", "text", "content_block_delta", "text", "content_block_delta", "text", "content_block_delta", "text", "content_block_delta", "text", "content_block_stop", "content_block_start", "content_block_delta", "input_json", "content_block_delta", "input_json", "content_block_delta", "input_json", "content_block_delta", "input_json", "message_delta", ] def assert_message_matches(message: BetaMessage, expected: Dict[str, Any]) -> None: actual_message_json = message.model_dump_json( indent=2, exclude_none=True, exclude={"content": {"__all__": {"__json_buf"}}} ) test_case = TestCase() test_case.maxDiff = None test_case.assertEqual(expected, json.loads(actual_message_json)) def assert_basic_response(events: list[BetaMessageStreamEvent], message: BetaMessage) -> None: assert_message_matches(message, EXPECTED_BASIC_MESSAGE) assert [e.type for e in events] == EXPECTED_BASIC_EVENT_TYPES def assert_tool_use_response(events: list[BetaMessageStreamEvent], message: BetaMessage) -> None: assert_message_matches(message, EXPECTED_TOOL_USE_MESSAGE) assert [e.type for e in events] == EXPECTED_TOOL_USE_EVENT_TYPES def assert_incomplete_partial_input_response(events: list[BetaMessageStreamEvent], message: BetaMessage) -> None: assert_message_matches(message, EXPECTED_INCOMPLETE_MESSAGE) assert [e.type for e in events] == EXPECTED_INCOMPLETE_EVENT_TYPES class TestSyncMessages: @pytest.mark.respx(base_url=base_url) def test_basic_response(self, respx_mock: MockRouter) -> None: respx_mock.post("/v1/messages").mock( return_value=httpx.Response(200, content=get_response("basic_response.txt")) ) with sync_client.beta.messages.stream( max_tokens=1024, messages=[ { "role": "user", "content": "Say hello there!", } ], model="claude-3-opus-latest", ) as stream: assert isinstance(cast(Any, stream), BetaMessageStream) assert_basic_response([event for event in stream], stream.get_final_message()) @pytest.mark.respx(base_url=base_url) def test_tool_use(self, respx_mock: MockRouter) -> None: respx_mock.post("/v1/messages").mock( return_value=httpx.Response(200, content=get_response("tool_use_response.txt")) ) with sync_client.beta.messages.stream( max_tokens=1024, messages=[ { "role": "user", "content": "Say hello there!", } ], model="claude-sonnet-4-20250514", ) as stream: assert isinstance(cast(Any, stream), BetaMessageStream) assert_tool_use_response([event for event in stream], stream.get_final_message()) @pytest.mark.respx(base_url=base_url) def test_context_manager(self, respx_mock: MockRouter) -> None: respx_mock.post("/v1/messages").mock( return_value=httpx.Response(200, content=get_response("basic_response.txt")) ) with sync_client.beta.messages.stream( max_tokens=1024, messages=[ { "role": "user", "content": "Say hello there!", } ], model="claude-3-opus-latest", ) as stream: assert not stream.response.is_closed # response should be closed even if the body isn't read assert stream.response.is_closed @pytest.mark.respx(base_url=base_url) def test_deprecated_model_warning_stream(self, respx_mock: MockRouter) -> None: for deprecated_model in DEPRECATED_MODELS: respx_mock.post("/v1/messages").mock( return_value=httpx.Response(200, content=get_response("basic_response.txt")) ) with pytest.warns(DeprecationWarning, match=f"The model '{deprecated_model}' is deprecated"): with sync_client.beta.messages.stream( max_tokens=1024, messages=[{"role": "user", "content": "Hello"}], model=deprecated_model, ) as stream: # Consume the stream to ensure the warning is triggered stream.until_done() class TestAsyncMessages: @pytest.mark.asyncio @pytest.mark.respx(base_url=base_url) async def test_basic_response(self, respx_mock: MockRouter) -> None: respx_mock.post("/v1/messages").mock( return_value=httpx.Response(200, content=to_async_iter(get_response("basic_response.txt"))) ) async with async_client.beta.messages.stream( max_tokens=1024, messages=[ { "role": "user", "content": "Say hello there!", } ], model="claude-opus-4-0", ) as stream: assert isinstance(cast(Any, stream), BetaAsyncMessageStream) assert_basic_response([event async for event in stream], await stream.get_final_message()) @pytest.mark.asyncio @pytest.mark.respx(base_url=base_url) async def test_context_manager(self, respx_mock: MockRouter) -> None: respx_mock.post("/v1/messages").mock( return_value=httpx.Response(200, content=to_async_iter(get_response("basic_response.txt"))) ) async with async_client.beta.messages.stream( max_tokens=1024, messages=[ { "role": "user", "content": "Say hello there!", } ], model="claude-3-opus-latest", ) as stream: assert not stream.response.is_closed # response should be closed even if the body isn't read assert stream.response.is_closed @pytest.mark.asyncio @pytest.mark.respx(base_url=base_url) async def test_deprecated_model_warning_stream(self, respx_mock: MockRouter) -> None: for deprecated_model in DEPRECATED_MODELS: respx_mock.post("/v1/messages").mock( return_value=httpx.Response(200, content=to_async_iter(get_response("basic_response.txt"))) ) with pytest.warns(DeprecationWarning, match=f"The model '{deprecated_model}' is deprecated"): async with async_client.beta.messages.stream( max_tokens=1024, messages=[{"role": "user", "content": "Hello"}], model=deprecated_model, ) as stream: # Consume the stream to ensure the warning is triggered await stream.get_final_message() @pytest.mark.asyncio @pytest.mark.respx(base_url=base_url) async def test_tool_use(self, respx_mock: MockRouter) -> None: respx_mock.post("/v1/messages").mock( return_value=httpx.Response(200, content=to_async_iter(get_response("tool_use_response.txt"))) ) async with async_client.beta.messages.stream( max_tokens=1024, messages=[ { "role": "user", "content": "Say hello there!", } ], model="claude-sonnet-4-20250514", ) as stream: assert isinstance(cast(Any, stream), BetaAsyncMessageStream) assert_tool_use_response([event async for event in stream], await stream.get_final_message()) @pytest.mark.asyncio @pytest.mark.respx(base_url=base_url) async def test_incomplete_response(self, respx_mock: MockRouter) -> None: respx_mock.post("/v1/messages").mock( return_value=httpx.Response( 200, content=to_async_iter(get_response("incomplete_partial_json_response.txt")) ) ) async with async_client.beta.messages.stream( max_tokens=1024, messages=[ { "role": "user", "content": "Say hello there!", } ], model="claude-sonnet-4-20250514", ) as stream: assert isinstance(cast(Any, stream), BetaAsyncMessageStream) assert_incomplete_partial_input_response( [event async for event in stream], await stream.get_final_message() ) @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"]) def test_stream_method_definition_in_sync(sync: bool) -> None: client: Anthropic | AsyncAnthropic = sync_client if sync else async_client sig = inspect.signature(client.beta.messages.stream) generated_sig = inspect.signature(client.beta.messages.create) errors: list[str] = [] for name, generated_param in generated_sig.parameters.items(): if name == "stream": # intentionally excluded continue custom_param = sig.parameters.get(name) if not custom_param: errors.append(f"the `{name}` param is missing") continue if custom_param.annotation != generated_param.annotation: errors.append( f"types for the `{name}` param are do not match; generated={repr(generated_param.annotation)} custom={repr(custom_param.annotation)}" ) continue if errors: raise AssertionError( f"{len(errors)} errors encountered with the {'sync' if sync else 'async'} client `messages.stream()` method:\n\n" + "\n\n".join(errors) ) # go through all the ContentBlock types to make sure the type alias is up to date # with any type that has an input property of type object def test_tracks_tool_input_type_alias_is_up_to_date() -> None: # only run this on Pydantic v2 if PYDANTIC_V1: pytest.skip("This test is only applicable for Pydantic v2") from typing import get_args from pydantic import BaseModel from anthropic.types.beta.beta_content_block import BetaContentBlock # Get the content block union type content_block_union = get_args(BetaContentBlock)[0] # Get all types from BetaContentBlock union content_block_types = get_args(content_block_union) # Types that should have an input property types_with_input: Set[Any] = set() # Check each type to see if it has an input property in its model_fields for block_type in content_block_types: if issubclass(block_type, BaseModel) and "input" in block_type.model_fields: types_with_input.add(block_type) # Get the types included in TRACKS_TOOL_INPUT tracked_types = TRACKS_TOOL_INPUT # Make sure all types with input are tracked for block_type in types_with_input: assert block_type in tracked_types, ( f"ContentBlock type {block_type.__name__} has an input property, " f"but is not included in TRACKS_TOOL_INPUT. You probably need to update the TRACKS_TOOL_INPUT type alias." ) anthropic-sdk-python-0.69.0/tests/lib/streaming/test_messages.py000066400000000000000000000276711506653454500250460ustar00rootroot00000000000000from __future__ import annotations import os import inspect from typing import Any, Set, TypeVar, cast import httpx import pytest from respx import MockRouter from anthropic import Stream, Anthropic, AsyncStream, AsyncAnthropic from anthropic._compat import PYDANTIC_V1 from anthropic.lib.streaming import MessageStreamEvent from anthropic.types.message import Message from anthropic.resources.messages import DEPRECATED_MODELS from anthropic.lib.streaming._messages import TRACKS_TOOL_INPUT from .helpers import get_response, to_async_iter base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") api_key = "my-anthropic-api-key" sync_client = Anthropic(base_url=base_url, api_key=api_key, _strict_response_validation=True) async_client = AsyncAnthropic(base_url=base_url, api_key=api_key, _strict_response_validation=True) _T = TypeVar("_T") def assert_basic_response(events: list[MessageStreamEvent], message: Message) -> None: assert message.id == "msg_4QpJur2dWWDjF6C758FbBw5vm12BaVipnK" assert message.model == "claude-3-opus-latest" assert message.role == "assistant" assert message.stop_reason == "end_turn" assert message.stop_sequence is None assert message.type == "message" assert len(message.content) == 1 content = message.content[0] assert content.type == "text" assert content.text == "Hello there!" assert [e.type for e in events] == [ "message_start", "content_block_start", "content_block_delta", "text", "content_block_delta", "text", "content_block_delta", "text", "content_block_stop", "message_delta", ] def assert_tool_use_response(events: list[MessageStreamEvent], message: Message) -> None: assert message.id == "msg_019Q1hrJbZG26Fb9BQhrkHEr" assert message.model == "claude-sonnet-4-20250514" assert message.role == "assistant" assert message.stop_reason == "tool_use" assert message.stop_sequence is None assert message.type == "message" assert len(message.content) == 2 content = message.content[0] assert content.type == "text" assert content.text == "I'll check the current weather in Paris for you." tool_use = message.content[1] assert tool_use.type == "tool_use" assert tool_use.id == "toolu_01NRLabsLyVHZPKxbKvkfSMn" assert tool_use.name == "get_weather" assert tool_use.input == { "location": "Paris", } assert message.usage.input_tokens == 377 assert message.usage.output_tokens == 65 assert message.usage.cache_creation_input_tokens == 0 assert message.usage.cache_read_input_tokens == 0 assert message.usage.service_tier == "standard" assert message.usage.server_tool_use == None assert [e.type for e in events] == [ "message_start", "content_block_start", "content_block_delta", "text", "content_block_delta", "text", "content_block_stop", "content_block_start", "content_block_delta", "input_json", "content_block_delta", "input_json", "content_block_delta", "input_json", "content_block_delta", "input_json", "content_block_delta", "input_json", "content_block_stop", "message_delta", ] class TestSyncMessages: @pytest.mark.respx(base_url=base_url) def test_basic_response(self, respx_mock: MockRouter) -> None: respx_mock.post("/v1/messages").mock( return_value=httpx.Response(200, content=get_response("basic_response.txt")) ) with sync_client.messages.stream( max_tokens=1024, messages=[ { "role": "user", "content": "Say hello there!", } ], model="claude-3-opus-latest", ) as stream: with pytest.warns(DeprecationWarning): assert isinstance(cast(Any, stream), Stream) assert_basic_response([event for event in stream], stream.get_final_message()) @pytest.mark.respx(base_url=base_url) def test_context_manager(self, respx_mock: MockRouter) -> None: respx_mock.post("/v1/messages").mock( return_value=httpx.Response(200, content=get_response("basic_response.txt")) ) with sync_client.messages.stream( max_tokens=1024, messages=[ { "role": "user", "content": "Say hello there!", } ], model="claude-3-opus-latest", ) as stream: assert not stream.response.is_closed # response should be closed even if the body isn't read assert stream.response.is_closed @pytest.mark.respx(base_url=base_url) def test_deprecated_model_warning_stream(self, respx_mock: MockRouter) -> None: for deprecated_model in DEPRECATED_MODELS: respx_mock.post("/v1/messages").mock( return_value=httpx.Response(200, content=get_response("basic_response.txt")) ) with pytest.warns(DeprecationWarning, match=f"The model '{deprecated_model}' is deprecated"): with sync_client.messages.stream( max_tokens=1024, messages=[{"role": "user", "content": "Hello"}], model=deprecated_model, ) as stream: # Consume the stream to ensure the warning is triggered stream.until_done() @pytest.mark.respx(base_url=base_url) def test_tool_use(self, respx_mock: MockRouter) -> None: respx_mock.post("/v1/messages").mock( return_value=httpx.Response(200, content=get_response("tool_use_response.txt")) ) with sync_client.messages.stream( max_tokens=1024, messages=[ { "role": "user", "content": "Say hello there!", } ], model="claude-sonnet-4-20250514", ) as stream: with pytest.warns(DeprecationWarning): assert isinstance(cast(Any, stream), Stream) assert_tool_use_response([event for event in stream], stream.get_final_message()) class TestAsyncMessages: @pytest.mark.asyncio @pytest.mark.respx(base_url=base_url) async def test_basic_response(self, respx_mock: MockRouter) -> None: respx_mock.post("/v1/messages").mock( return_value=httpx.Response(200, content=to_async_iter(get_response("basic_response.txt"))) ) async with async_client.messages.stream( max_tokens=1024, messages=[ { "role": "user", "content": "Say hello there!", } ], model="claude-3-opus-latest", ) as stream: with pytest.warns(DeprecationWarning): assert isinstance(cast(Any, stream), AsyncStream) assert_basic_response([event async for event in stream], await stream.get_final_message()) @pytest.mark.asyncio @pytest.mark.respx(base_url=base_url) async def test_context_manager(self, respx_mock: MockRouter) -> None: respx_mock.post("/v1/messages").mock( return_value=httpx.Response(200, content=to_async_iter(get_response("basic_response.txt"))) ) async with async_client.messages.stream( max_tokens=1024, messages=[ { "role": "user", "content": "Say hello there!", } ], model="claude-3-opus-latest", ) as stream: assert not stream.response.is_closed # response should be closed even if the body isn't read assert stream.response.is_closed @pytest.mark.asyncio @pytest.mark.respx(base_url=base_url) async def test_deprecated_model_warning_stream(self, respx_mock: MockRouter) -> None: for deprecated_model in DEPRECATED_MODELS: respx_mock.post("/v1/messages").mock( return_value=httpx.Response(200, content=to_async_iter(get_response("basic_response.txt"))) ) with pytest.warns(DeprecationWarning, match=f"The model '{deprecated_model}' is deprecated"): async with async_client.messages.stream( max_tokens=1024, messages=[{"role": "user", "content": "Hello"}], model=deprecated_model, ) as stream: # Consume the stream to ensure the warning is triggered await stream.get_final_message() @pytest.mark.asyncio @pytest.mark.respx(base_url=base_url) async def test_tool_use(self, respx_mock: MockRouter) -> None: respx_mock.post("/v1/messages").mock( return_value=httpx.Response(200, content=to_async_iter(get_response("tool_use_response.txt"))) ) async with async_client.messages.stream( max_tokens=1024, messages=[ { "role": "user", "content": "Say hello there!", } ], model="claude-sonnet-4-20250514", ) as stream: with pytest.warns(DeprecationWarning): assert isinstance(cast(Any, stream), AsyncStream) assert_tool_use_response([event async for event in stream], await stream.get_final_message()) @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"]) def test_stream_method_definition_in_sync(sync: bool) -> None: client: Anthropic | AsyncAnthropic = sync_client if sync else async_client sig = inspect.signature(client.messages.stream) generated_sig = inspect.signature(client.messages.create) errors: list[str] = [] for name, generated_param in generated_sig.parameters.items(): if name == "stream": # intentionally excluded continue custom_param = sig.parameters.get(name) if not custom_param: errors.append(f"the `{name}` param is missing") continue if custom_param.annotation != generated_param.annotation: errors.append( f"types for the `{name}` param are do not match; generated={repr(generated_param.annotation)} custom={repr(custom_param.annotation)}" ) continue if errors: raise AssertionError( f"{len(errors)} errors encountered with the {'sync' if sync else 'async'} client `messages.stream()` method:\n\n" + "\n\n".join(errors) ) # go through all the ContentBlock types to make sure the type alias is up to date # with any type that has an input property of type object @pytest.mark.skipif(PYDANTIC_V1, reason="only applicable in pydantic v2") def test_tracks_tool_input_type_alias_is_up_to_date() -> None: from typing import get_args from pydantic import BaseModel from anthropic.types.content_block import ContentBlock # Get the content block union type content_block_union = get_args(ContentBlock)[0] # Get all types from ContentBlock union content_block_types = get_args(content_block_union) # Types that should have an input property types_with_input: Set[Any] = set() # Check each type to see if it has an input property in its model_fields for block_type in content_block_types: if issubclass(block_type, BaseModel) and "input" in block_type.model_fields: types_with_input.add(block_type) # Get the types included in TRACKS_TOOL_INPUT tracked_types = TRACKS_TOOL_INPUT # Make sure all types with input are tracked for block_type in types_with_input: assert block_type in tracked_types, ( f"ContentBlock type {block_type.__name__} has an input property, " f"but is not included in TRACKS_TOOL_INPUT. You probably need to update the TRACKS_TOOL_INPUT type alias." ) anthropic-sdk-python-0.69.0/tests/lib/streaming/test_partial_json.py000066400000000000000000000136061506653454500257150ustar00rootroot00000000000000import copy from typing import List, cast import httpx from anthropic.types.tool_use_block import ToolUseBlock from anthropic.types.beta.beta_usage import BetaUsage from anthropic.types.beta.beta_message import BetaMessage from anthropic.lib.streaming._beta_messages import accumulate_event from anthropic.types.beta.beta_tool_use_block import BetaToolUseBlock from anthropic.types.beta.beta_input_json_delta import BetaInputJSONDelta from anthropic.types.beta.beta_raw_content_block_delta_event import BetaRawContentBlockDeltaEvent class TestPartialJson: def test_trailing_strings_mode_header(self) -> None: """Test behavior differences with and without the beta header for JSON parsing.""" message = BetaMessage( id="msg_123", type="message", role="assistant", content=[BetaToolUseBlock(type="tool_use", input={}, id="tool_123", name="test_tool")], model="claude-3-7-sonnet-20250219", stop_reason=None, stop_sequence=None, usage=BetaUsage(input_tokens=10, output_tokens=10), ) # Test case 1: Complete JSON complete_json = '{"key": "value"}' event_complete = BetaRawContentBlockDeltaEvent( type="content_block_delta", index=0, delta=BetaInputJSONDelta(type="input_json_delta", partial_json=complete_json), ) # Both modes should handle complete JSON the same way message1 = accumulate_event( event=event_complete, current_snapshot=copy.deepcopy(message), request_headers=httpx.Headers({"some-header": "value"}), ) message2 = accumulate_event( event=event_complete, current_snapshot=copy.deepcopy(message), request_headers=httpx.Headers({"anthropic-beta": "fine-grained-tool-streaming-2025-05-14"}), ) # Both should parse complete JSON correctly assert cast(ToolUseBlock, message1.content[0]).input == {"key": "value"} assert cast(ToolUseBlock, message2.content[0]).input == {"key": "value"} # Test case 2: Incomplete JSON with trailing string that will be treated differently # Here we want to create a situation where regular mode and trailing strings mode behave differently incomplete_json = '{"items": ["item1", "item2"], "unfinished_field": "incomplete value' event_incomplete = BetaRawContentBlockDeltaEvent( type="content_block_delta", index=0, delta=BetaInputJSONDelta(type="input_json_delta", partial_json=incomplete_json), ) # Without beta header (standard mode) message_standard = accumulate_event( event=event_incomplete, current_snapshot=copy.deepcopy(message), request_headers=httpx.Headers({"some-header": "value"}), ) # With beta header (trailing strings mode) message_trailing = accumulate_event( event=event_incomplete, current_snapshot=copy.deepcopy(message), request_headers=httpx.Headers({"anthropic-beta": "fine-grained-tool-streaming-2025-05-14"}), ) # Get the tool use blocks standard_tool = cast(ToolUseBlock, message_standard.content[0]) trailing_tool = cast(ToolUseBlock, message_trailing.content[0]) # Both should have the valid complete part of the JSON assert isinstance(standard_tool.input, dict) assert isinstance(trailing_tool.input, dict) standard_input = standard_tool.input # type: ignore trailing_input = trailing_tool.input # type: ignore # The input should have the items array in both cases items_standard = cast(List[str], standard_input["items"]) items_trailing = cast(List[str], trailing_input["items"]) assert items_standard == ["item1", "item2"] assert items_trailing == ["item1", "item2"] # The key difference is how they handle the incomplete field: # Standard mode should not include the incomplete field assert "unfinished_field" not in standard_input # Trailing strings mode should include the incomplete field assert "unfinished_field" in trailing_input assert trailing_input["unfinished_field"] == "incomplete value" # test that with invalid JSON we throw the correct error def test_partial_json_with_invalid_json(self) -> None: """Test that invalid JSON raises an error.""" message = BetaMessage( id="msg_123", type="message", role="assistant", content=[BetaToolUseBlock(type="tool_use", input={}, id="tool_123", name="test_tool")], model="claude-3-7-sonnet-20250219", stop_reason=None, stop_sequence=None, usage=BetaUsage(input_tokens=10, output_tokens=10), ) # Invalid JSON input invalid_json = '{"key": "value", "incomplete_field": bad_value' event_invalid = BetaRawContentBlockDeltaEvent( type="content_block_delta", index=0, delta=BetaInputJSONDelta(type="input_json_delta", partial_json=invalid_json), ) # Expect an error when trying to accumulate the invalid JSON try: accumulate_event( event=event_invalid, current_snapshot=copy.deepcopy(message), request_headers=httpx.Headers({"anthropic-beta": "fine-grained-tool-streaming-2025-05-14"}), ) raise AssertionError("Expected ValueError for invalid JSON, but no error was raised.") except ValueError as e: assert str(e).startswith( "Unable to parse tool parameter JSON from model. Please retry your request or adjust your prompt." ) except Exception as e: raise AssertionError(f"Unexpected error type: {type(e).__name__} with message: {str(e)}") from e anthropic-sdk-python-0.69.0/tests/lib/test_bedrock.py000066400000000000000000000137751506653454500226570ustar00rootroot00000000000000import re import typing as t import tempfile from typing import TypedDict, cast from typing_extensions import Protocol import httpx import pytest from respx import MockRouter from anthropic import AnthropicBedrock, AsyncAnthropicBedrock sync_client = AnthropicBedrock( aws_region="us-east-1", aws_access_key="example-access-key", aws_secret_key="example-secret-key", ) async_client = AsyncAnthropicBedrock( aws_region="us-east-1", aws_access_key="example-access-key", aws_secret_key="example-secret-key", ) class MockRequestCall(Protocol): request: httpx.Request class AwsConfigProfile(TypedDict): # Available regions: https://docs.aws.amazon.com/global-infrastructure/latest/regions/aws-regions.html#available-regions name: t.Union[t.Literal["default"], str] region: str def profile_to_ini(profile: AwsConfigProfile) -> str: """ Convert an AWS config profile to an INI format string. """ profile_name = profile["name"] if profile["name"] == "default" else f"profile {profile['name']}" return f"[{profile_name}]\nregion = {profile['region']}\n" @pytest.fixture def profiles() -> t.List[AwsConfigProfile]: return [ {"name": "default", "region": "us-east-2"}, ] @pytest.fixture def mock_aws_config( profiles: t.List[AwsConfigProfile], monkeypatch: t.Any, ) -> t.Iterable[None]: with tempfile.NamedTemporaryFile(mode="w+", delete=True) as temp_file: for profile in profiles: temp_file.write(profile_to_ini(profile)) temp_file.flush() monkeypatch.setenv("AWS_CONFIG_FILE", str(temp_file.name)) yield @pytest.mark.filterwarnings("ignore::DeprecationWarning") @pytest.mark.respx() def test_messages_retries(respx_mock: MockRouter) -> None: respx_mock.post(re.compile(r"https://bedrock-runtime\.us-east-1\.amazonaws\.com/model/.*/invoke")).mock( side_effect=[ httpx.Response(500, json={"error": "server error"}, headers={"retry-after-ms": "10"}), httpx.Response(200, json={"foo": "bar"}), ] ) sync_client.messages.create( max_tokens=1024, messages=[ { "role": "user", "content": "Say hello there!", } ], model="anthropic.claude-3-5-sonnet-20241022-v2:0", ) calls = cast("list[MockRequestCall]", respx_mock.calls) assert len(calls) == 2 assert ( calls[0].request.url == "https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-3-5-sonnet-20241022-v2:0/invoke" ) assert ( calls[1].request.url == "https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-3-5-sonnet-20241022-v2:0/invoke" ) @pytest.mark.filterwarnings("ignore::DeprecationWarning") @pytest.mark.respx() @pytest.mark.asyncio() async def test_messages_retries_async(respx_mock: MockRouter) -> None: respx_mock.post(re.compile(r"https://bedrock-runtime\.us-east-1\.amazonaws\.com/model/.*/invoke")).mock( side_effect=[ httpx.Response(500, json={"error": "server error"}, headers={"retry-after-ms": "10"}), httpx.Response(200, json={"foo": "bar"}), ] ) await async_client.messages.create( max_tokens=1024, messages=[ { "role": "user", "content": "Say hello there!", } ], model="anthropic.claude-3-5-sonnet-20241022-v2:0", ) calls = cast("list[MockRequestCall]", respx_mock.calls) assert len(calls) == 2 assert ( calls[0].request.url == "https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-3-5-sonnet-20241022-v2:0/invoke" ) assert ( calls[1].request.url == "https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-3-5-sonnet-20241022-v2:0/invoke" ) @pytest.mark.filterwarnings("ignore::DeprecationWarning") @pytest.mark.respx() def test_application_inference_profile(respx_mock: MockRouter) -> None: respx_mock.post(re.compile(r"https://bedrock-runtime\.us-east-1\.amazonaws\.com/model/.*/invoke")).mock( side_effect=[ httpx.Response(500, json={"error": "server error"}, headers={"retry-after-ms": "10"}), httpx.Response(200, json={"foo": "bar"}), ] ) sync_client.messages.create( max_tokens=1024, messages=[ { "role": "user", "content": "Say hello there!", } ], model="arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/jf2sje1c0jnb", ) calls = cast("list[MockRequestCall]", respx_mock.calls) assert len(calls) == 2 assert ( calls[0].request.url == "https://bedrock-runtime.us-east-1.amazonaws.com/model/arn:aws:bedrock:us-east-1:123456789012:application-inference-profile%2Fjf2sje1c0jnb/invoke" ) assert ( calls[1].request.url == "https://bedrock-runtime.us-east-1.amazonaws.com/model/arn:aws:bedrock:us-east-1:123456789012:application-inference-profile%2Fjf2sje1c0jnb/invoke" ) def test_region_infer_from_profile( mock_aws_config: None, # noqa: ARG001 profiles: t.List[AwsConfigProfile], ) -> None: client = AnthropicBedrock() assert client.aws_region == profiles[0]["region"] @pytest.mark.parametrize( "profiles, aws_profile", [ pytest.param([{"name": "default", "region": "us-east-2"}], "default", id="default profile"), pytest.param( [{"name": "default", "region": "us-east-2"}, {"name": "custom", "region": "us-west-1"}], "custom", id="custom profile", ), ], ) def test_region_infer_from_specified_profile( mock_aws_config: None, # noqa: ARG001 profiles: t.List[AwsConfigProfile], aws_profile: str, monkeypatch: t.Any, ) -> None: monkeypatch.setenv("AWS_PROFILE", aws_profile) client = AnthropicBedrock() assert client.aws_region == next(profile for profile in profiles if profile["name"] == aws_profile)["region"] anthropic-sdk-python-0.69.0/tests/lib/test_vertex.py000066400000000000000000000260321506653454500225510ustar00rootroot00000000000000from __future__ import annotations import os from typing import cast from typing_extensions import Protocol import httpx import pytest from respx import MockRouter from anthropic import AnthropicVertex, AsyncAnthropicVertex base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") class MockRequestCall(Protocol): request: httpx.Request class TestAnthropicVertex: client = AnthropicVertex(region="region", project_id="project", access_token="my-access-token") @pytest.mark.respx() def test_messages_retries(self, respx_mock: MockRouter) -> None: request_url = "https://region-aiplatform.googleapis.com/v1/projects/project/locations/region/publishers/anthropic/models/claude-3-sonnet@20240229:rawPredict" respx_mock.post(request_url).mock( side_effect=[ httpx.Response(500, json={"error": "server error"}, headers={"retry-after-ms": "10"}), httpx.Response(200, json={"foo": "bar"}), ] ) self.client.messages.create( max_tokens=1024, messages=[ { "role": "user", "content": "Say hello there!", } ], model="claude-3-sonnet@20240229", ) calls = cast("list[MockRequestCall]", respx_mock.calls) assert len(calls) == 2 assert calls[0].request.url == request_url assert calls[1].request.url == request_url def test_copy(self) -> None: copied = self.client.copy() assert id(copied) != id(self.client) copied = self.client.copy(region="another-region", project_id="another-project") assert copied.region == "another-region" assert self.client.region == "region" assert copied.project_id == "another-project" assert self.client.project_id == "project" def test_with_options(self) -> None: copied = self.client.with_options(region="another-region", project_id="another-project") assert copied.region == "another-region" assert self.client.region == "region" assert copied.project_id == "another-project" assert self.client.project_id == "project" def test_copy_default_options(self) -> None: # options that have a default are overridden correctly copied = self.client.copy(max_retries=7) assert copied.max_retries == 7 assert self.client.max_retries == 2 copied2 = copied.copy(max_retries=6) assert copied2.max_retries == 6 assert copied.max_retries == 7 # timeout assert isinstance(self.client.timeout, httpx.Timeout) copied = self.client.copy(timeout=None) assert copied.timeout is None assert isinstance(self.client.timeout, httpx.Timeout) def test_copy_default_headers(self) -> None: client = AnthropicVertex( base_url=base_url, region="region", project_id="project", _strict_response_validation=True, default_headers={"X-Foo": "bar"}, ) assert client.default_headers["X-Foo"] == "bar" # does not override the already given value when not specified copied = client.copy() assert copied.default_headers["X-Foo"] == "bar" # merges already given headers copied = client.copy(default_headers={"X-Bar": "stainless"}) assert copied.default_headers["X-Foo"] == "bar" assert copied.default_headers["X-Bar"] == "stainless" # uses new values for any already given headers copied = client.copy(default_headers={"X-Foo": "stainless"}) assert copied.default_headers["X-Foo"] == "stainless" # set_default_headers # completely overrides already set values copied = client.copy(set_default_headers={}) assert copied.default_headers.get("X-Foo") is None copied = client.copy(set_default_headers={"X-Bar": "Robert"}) assert copied.default_headers["X-Bar"] == "Robert" with pytest.raises( ValueError, match="`default_headers` and `set_default_headers` arguments are mutually exclusive", ): client.copy(set_default_headers={}, default_headers={"X-Foo": "Bar"}) def test_global_region_base_url(self) -> None: """Test that global region uses the correct base URL.""" client = AnthropicVertex(region="global", project_id="test-project", access_token="fake-token") assert str(client.base_url).rstrip("/") == "https://aiplatform.googleapis.com/v1" @pytest.mark.parametrize("region", ["us-central1", "europe-west1", "asia-southeast1"]) def test_regional_base_url(self, region: str) -> None: """Test that regional endpoints use the correct base URL format.""" client = AnthropicVertex(region=region, project_id="test-project", access_token="fake-token") expected_url = f"https://{region}-aiplatform.googleapis.com/v1" assert str(client.base_url).rstrip("/") == expected_url def test_env_var_base_url_override(self, monkeypatch: pytest.MonkeyPatch) -> None: """Test that ANTHROPIC_VERTEX_BASE_URL environment variable does not override client arg.""" test_url = "https://custom-endpoint.googleapis.com/v1" monkeypatch.setenv("ANTHROPIC_VERTEX_BASE_URL", test_url) client = AnthropicVertex( region="global", # we expect this to get ignored since the user is providing a base_url project_id="test-project", access_token="fake-token", base_url="https://test.googleapis.com/v1", ) assert str(client.base_url).rstrip("/") == "https://test.googleapis.com/v1" class TestAsyncAnthropicVertex: client = AsyncAnthropicVertex(region="region", project_id="project", access_token="my-access-token") @pytest.mark.respx() @pytest.mark.asyncio() async def test_messages_retries(self, respx_mock: MockRouter) -> None: request_url = "https://region-aiplatform.googleapis.com/v1/projects/project/locations/region/publishers/anthropic/models/claude-3-sonnet@20240229:rawPredict" respx_mock.post(request_url).mock( side_effect=[ httpx.Response(500, json={"error": "server error"}, headers={"retry-after-ms": "10"}), httpx.Response(200, json={"foo": "bar"}), ] ) await self.client.with_options(timeout=0.2).messages.create( max_tokens=1024, messages=[ { "role": "user", "content": "Say hello there!", } ], model="claude-3-sonnet@20240229", ) calls = cast("list[MockRequestCall]", respx_mock.calls) assert len(calls) == 2 assert calls[0].request.url == request_url assert calls[1].request.url == request_url def test_copy(self) -> None: copied = self.client.copy() assert id(copied) != id(self.client) copied = self.client.copy(region="another-region", project_id="another-project") assert copied.region == "another-region" assert self.client.region == "region" assert copied.project_id == "another-project" assert self.client.project_id == "project" def test_with_options(self) -> None: copied = self.client.with_options(region="another-region", project_id="another-project") assert copied.region == "another-region" assert self.client.region == "region" assert copied.project_id == "another-project" assert self.client.project_id == "project" def test_copy_default_options(self) -> None: # options that have a default are overridden correctly copied = self.client.copy(max_retries=7) assert copied.max_retries == 7 assert self.client.max_retries == 2 copied2 = copied.copy(max_retries=6) assert copied2.max_retries == 6 assert copied.max_retries == 7 # timeout assert isinstance(self.client.timeout, httpx.Timeout) copied = self.client.copy(timeout=None) assert copied.timeout is None assert isinstance(self.client.timeout, httpx.Timeout) def test_copy_default_headers(self) -> None: client = AsyncAnthropicVertex( base_url=base_url, region="region", project_id="project", _strict_response_validation=True, default_headers={"X-Foo": "bar"}, ) assert client.default_headers["X-Foo"] == "bar" # does not override the already given value when not specified copied = client.copy() assert copied.default_headers["X-Foo"] == "bar" # merges already given headers copied = client.copy(default_headers={"X-Bar": "stainless"}) assert copied.default_headers["X-Foo"] == "bar" assert copied.default_headers["X-Bar"] == "stainless" # uses new values for any already given headers copied = client.copy(default_headers={"X-Foo": "stainless"}) assert copied.default_headers["X-Foo"] == "stainless" # set_default_headers # completely overrides already set values copied = client.copy(set_default_headers={}) assert copied.default_headers.get("X-Foo") is None copied = client.copy(set_default_headers={"X-Bar": "Robert"}) assert copied.default_headers["X-Bar"] == "Robert" with pytest.raises( ValueError, match="`default_headers` and `set_default_headers` arguments are mutually exclusive", ): client.copy(set_default_headers={}, default_headers={"X-Foo": "Bar"}) def test_global_region_base_url(self) -> None: """Test that global region uses the correct base URL.""" client = AsyncAnthropicVertex(region="global", project_id="test-project", access_token="fake-token") assert str(client.base_url).rstrip("/") == "https://aiplatform.googleapis.com/v1" def test_regional_base_url(self) -> None: """Test that regional endpoints use the correct base URL format.""" test_regions = ["us-central1", "europe-west1", "asia-southeast1"] for region in test_regions: client = AsyncAnthropicVertex(region=region, project_id="test-project", access_token="fake-token") expected_url = f"https://{region}-aiplatform.googleapis.com/v1" assert str(client.base_url).rstrip("/") == expected_url def test_env_var_base_url_override(self, monkeypatch: pytest.MonkeyPatch) -> None: """Test that ANTHROPIC_VERTEX_BASE_URL environment variable does not override client arg.""" test_url = "https://custom-endpoint.googleapis.com/v1" monkeypatch.setenv("ANTHROPIC_VERTEX_BASE_URL", test_url) client = AsyncAnthropicVertex( region="global", # we expect this to get ignored since the user is providing a base_url project_id="test-project", access_token="fake-token", base_url="https://test.googleapis.com/v1", ) assert str(client.base_url).rstrip("/") == "https://test.googleapis.com/v1" anthropic-sdk-python-0.69.0/tests/lib/tools/000077500000000000000000000000001506653454500207605ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/tests/lib/tools/__init__.py000066400000000000000000000000001506653454500230570ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/tests/lib/tools/__inline_snapshot__/000077500000000000000000000000001506653454500247515ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/tests/lib/tools/__inline_snapshot__/test_runners/000077500000000000000000000000001506653454500275045ustar00rootroot00000000000000TestSyncRunTools.test_max_iterations/000077500000000000000000000000001506653454500367735ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/tests/lib/tools/__inline_snapshot__/test_runnersef758469-6fa6-454c-b2e6-19d0b450a8c5.json000066400000000000000000000027411506653454500444730ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools.test_max_iterations[ "{\"id\": \"msg_0184u1shM6AjCNAaoknBoEpf\", \"type\": \"message\", \"role\": \"assistant\", \"model\": \"claude-3-5-sonnet-20241022\", \"content\": [{\"type\": \"text\", \"text\": \"I'll help you check the weather for each city one by one. I'll use Fahrenheit units by default. Let me check them sequentially.\\n\\nFirst, let's check San Francisco:\"}, {\"type\": \"tool_use\", \"id\": \"toolu_01GiQJzt5d2ThB4fSUsRCSML\", \"name\": \"get_weather\", \"input\": {\"location\": \"San Francisco, CA\", \"units\": \"f\"}}], \"stop_reason\": \"tool_use\", \"stop_sequence\": null, \"usage\": {\"input_tokens\": 518, \"cache_creation_input_tokens\": 0, \"cache_read_input_tokens\": 0, \"cache_creation\": {\"ephemeral_5m_input_tokens\": 0, \"ephemeral_1h_input_tokens\": 0}, \"output_tokens\": 114, \"service_tier\": \"standard\"}}", "{\"id\": \"msg_015zyD3V5WXG8r3hgkUaNGCZ\", \"type\": \"message\", \"role\": \"assistant\", \"model\": \"claude-3-5-sonnet-20241022\", \"content\": [{\"type\": \"text\", \"text\": \"Now for New York:\"}, {\"type\": \"tool_use\", \"id\": \"toolu_015yzRQ92SwYGz5Veoq7A3P7\", \"name\": \"get_weather\", \"input\": {\"location\": \"New York, NY\", \"units\": \"f\"}}], \"stop_reason\": \"tool_use\", \"stop_sequence\": null, \"usage\": {\"input_tokens\": 671, \"cache_creation_input_tokens\": 0, \"cache_read_input_tokens\": 0, \"cache_creation\": {\"ephemeral_5m_input_tokens\": 0, \"ephemeral_1h_input_tokens\": 0}, \"output_tokens\": 80, \"service_tier\": \"standard\"}}" ]TestSyncRunTools.test_streaming_call_sync_events/000077500000000000000000000000001506653454500413515ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/tests/lib/tools/__inline_snapshot__/test_runners9cb114c8-69bd-4111-841b-edee30333afd.json000066400000000000000000000174331506653454500471630ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools.test_streaming_call_sync_events[ "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"id\":\"msg_01YRiDgGtAnVWtzGJqRSZjAn\",\"type\":\"message\",\"role\":\"assistant\",\"model\":\"claude-3-5-sonnet-20241022\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":473,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":2,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"I'll\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" help you check the weather in\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" San Francisco. Since\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" the location parameter\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" requires city and state format\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\", I'll use \\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"San Francisco, CA\\\".\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" I'll show\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" you the temperature\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" in both Celsius an\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"d Fahrenheit.\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_012hgxfzW99WoVYezL1WcYey\",\"name\":\"get_weather\",\"input\":{}} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"l\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ocation\\\": \\\"S\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"an Franc\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"isco, C\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"A\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"units\\\":\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" \\\"c\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1 }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":2,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01NuZ5a7BDewKGEjC5XMchFi\",\"name\":\"get_weather\",\"input\":{}} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"location\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\": \\\"San Fran\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"cisco, CA\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"unit\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"s\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\": \\\"f\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":2 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":473,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":175} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"id\":\"msg_01FXBHYjKkNTFc6PnCiarAoh\",\"type\":\"message\",\"role\":\"assistant\",\"model\":\"claude-3-5-sonnet-20241022\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":766,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":2,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"The\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" weather in San Francisco,\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" CA is currently\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" sunny with a temperature of \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"20\u00b0C (68\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"\u00b0F).\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":766,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":27} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n" ]test_streaming_call_sync/000077500000000000000000000000001506653454500345045ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/tests/lib/tools/__inline_snapshot__/test_runnerse2140c0f-07db-47ee-b86b-c2ec476866d5.json000066400000000000000000000110411506653454500423230ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/tests/lib/tools/__inline_snapshot__/test_runners/test_streaming_call_sync[ "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"id\":\"msg_013ABQ6nbL2CSWP8qCEzyrzd\",\"type\":\"message\",\"role\":\"assistant\",\"model\":\"claude-3-5-sonnet-20241022\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":473,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":2,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"I'll\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" help you check the weather in San Francisco. Let\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" me look that up for you.\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01Lyjynae6j6wHfNVRKaMRK5\",\"name\":\"get_weather\",\"input\":{}} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"location\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\": \\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"San Francis\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"co, CA\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"unit\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"s\\\": \\\"f\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":473,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":93} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"id\":\"msg_01FtWrpBLsm99NpQCoFrhuf9\",\"type\":\"message\",\"role\":\"assistant\",\"model\":\"claude-3-5-sonnet-20241022\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":605,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":2,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"The\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" weather in San Francisco is currently \"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"68\u00b0F and sunny.\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":605,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":18} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n" ]test_streaming_call_sync_events/000077500000000000000000000000001506653454500360705ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/tests/lib/tools/__inline_snapshot__/test_runners9cb114c8-69bd-4111-841b-edee30333afd.json000066400000000000000000000164441506653454500437030ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/tests/lib/tools/__inline_snapshot__/test_runners/test_streaming_call_sync_events[ "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"id\":\"msg_01DfDUn6fFzYyGNjmWmA9XVK\",\"type\":\"message\",\"role\":\"assistant\",\"model\":\"claude-3-5-sonnet-20241022\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":473,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":2,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"I'll\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" help you check the weather in San Francisco\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\". Since the location parameter needs to be more\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" specific, I'll use \\\"San Francisco, CA\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" and I'll show you the temperature in both\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" Celsius and Fahrenheit.\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01QYZ2sgjBq1oG8iryEt8QjR\",\"name\":\"get_weather\",\"input\":{}} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"location\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\": \\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"San Francisc\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"o, CA\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"unit\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"s\\\":\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" \\\"c\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1 }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":2,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01Lu9hbRKgrZqvHFutZxCNnZ\",\"name\":\"get_weather\",\"input\":{}} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"loc\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"at\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"io\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n\\\": \\\"San \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"Francisco\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", CA\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"units\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\": \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"f\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":2 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":473,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":176} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"id\":\"msg_014L4v4PaF8RoEXeryKARnCp\",\"type\":\"message\",\"role\":\"assistant\",\"model\":\"claude-3-5-sonnet-20241022\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":767,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":2,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"The\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" weather in San Francisco, CA is\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" currently sunny with a temperature of 20\u00b0C (68\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"\u00b0F).\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":767,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":27} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n" ]anthropic-sdk-python-0.69.0/tests/lib/tools/test_functions.py000066400000000000000000000410711506653454500244040ustar00rootroot00000000000000from __future__ import annotations from typing import Any, cast import pytest from pydantic import BaseModel from anthropic import beta_tool from anthropic._compat import PYDANTIC_V1 from anthropic.lib.tools._beta_functions import BaseFunctionTool from anthropic.types.beta.beta_tool_param import InputSchema @pytest.mark.skipif(PYDANTIC_V1, reason="only applicable in pydantic v2") class TestFunctionTool: def test_basic_function_schema_conversion(self) -> None: """Test basic function schema conversion with simple types.""" def get_weather(location: str, unit: str = "celsius") -> str: """Get the weather for a specific location.""" return f"Weather in {location} is 20 degrees {unit}" function_tool = beta_tool(get_weather) assert function_tool.name == "get_weather" assert function_tool.description == "Get the weather for a specific location." assert function_tool.input_schema == { "additionalProperties": False, "type": "object", "properties": { "location": {"title": "Location", "type": "string"}, "unit": {"title": "Unit", "type": "string", "default": "celsius"}, }, "required": ["location"], } assert function_tool(location="CA") == "Weather in CA is 20 degrees celsius" # invalid types should be allowed because __call__ should just be the original function assert function_tool(location=cast(Any, 1)) == "Weather in 1 is 20 degrees celsius" def test_function_with_multiple_types(self) -> None: """Test function schema conversion with various Python types.""" def simple_function( name: str, age: int, ) -> str: """A simple function with basic parameter types.""" return f"Person: {name}, {age} years old" function_tool = beta_tool(simple_function) # Test that we can create the tool and call it assert function_tool.name == "simple_function" assert function_tool.description == "A simple function with basic parameter types." # Test calling the function result = function_tool.call( { "name": "John", "age": 25, } ) assert result == "Person: John, 25 years old" # Test schema structure expected_schema = { "additionalProperties": False, "type": "object", "properties": { "name": {"title": "Name", "type": "string"}, "age": {"title": "Age", "type": "integer"}, }, "required": ["name", "age"], } assert function_tool.input_schema == expected_schema def test_function_call_with_valid_input(self) -> None: def add_numbers(a: int, b: int) -> str: """Add two numbers together.""" return str(a + b) function_tool = beta_tool(add_numbers) result = function_tool.call({"a": 5, "b": 3}) assert result == "8" @pytest.mark.parametrize( "input_data, expected_error_type, expected_error_msg", [ pytest.param( {"a": "not a number", "b": 3}, ValueError, "Invalid arguments for function add_numbers", id="invalid_argument_type", ), pytest.param( {"b": 3}, ValueError, "Invalid arguments for function add_numbers", id="missing_required_argument", ), pytest.param( None, TypeError, "Input must be a dictionary, got NoneType", id="invalid_input_object", ), ], ) def test_function_call_with_invalid_input( self, input_data: dict[str, Any], expected_error_type: type[BaseException], expected_error_msg: str ) -> None: def add_numbers(a: int, b: int) -> str: return str(a + b) function_tool = beta_tool(add_numbers) with pytest.raises(expected_error_type, match=expected_error_msg): function_tool.call(input_data) def test_custom_name_and_description(self) -> None: def some_function(x: int) -> str: """Original description.""" return str(x * 2) function_tool = beta_tool(some_function, name="custom_name", description="Custom description") assert function_tool.name == "custom_name" assert function_tool.description == "Custom description" def test_custom_input_schema_with_dict(self) -> None: def some_function(x: int) -> str: return str(x * 2) custom_schema: InputSchema = { "additionalProperties": False, "type": "object", "properties": {"x": {"type": "number", "description": "A number to double"}}, "required": ["x"], } function_tool = beta_tool(some_function, input_schema=custom_schema) assert function_tool.input_schema == custom_schema def test_custom_input_schema_with_pydantic_model(self) -> None: class WeatherInput(BaseModel): location: str unit: str = "celsius" def get_weather(location: str, unit: str = "celsius") -> str: # noqa: ARG001 return f"Weather in {location}" # Pass the Pydantic model class directly as input_schema function_tool = beta_tool(get_weather, input_schema=WeatherInput) # Pydantic model schemas include additional metadata schema = function_tool.input_schema assert schema == { "title": "WeatherInput", "type": "object", "properties": { "location": {"title": "Location", "type": "string"}, "unit": {"title": "Unit", "type": "string", "default": "celsius"}, }, "required": ["location"], } def test_to_dict_method(self) -> None: def simple_func(message: str) -> str: """A simple function.""" return message function_tool = beta_tool(simple_func) tool_param = function_tool.to_dict() assert tool_param == { "name": "simple_func", "description": "A simple function.", "input_schema": { "additionalProperties": False, "type": "object", "properties": {"message": {"title": "Message", "type": "string"}}, "required": ["message"], }, } def test_function_without_docstring(self) -> None: def no_docs(x: int) -> str: # noqa: ARG001 return "" function_tool = beta_tool(no_docs) assert function_tool.description == "" def test_function_without_type_hints(self) -> None: def no_types(x, y=10): # pyright: ignore[reportUnknownParameterType, reportMissingParameterType] return x + y # pyright: ignore[reportUnknownVariableType] function_tool = beta_tool(no_types) # type: ignore # Should still create a schema, though less precise (uses Any type) assert function_tool.input_schema == { "additionalProperties": False, "type": "object", "properties": { "x": {"title": "X"}, # Any type gets title but no type "y": {"title": "Y", "default": 10}, }, "required": ["x"], } @pytest.mark.parametrize( "docstring", [ pytest.param( ( """Get detailed weather information for a location. This function retrieves current weather conditions and optionally includes a forecast for the specified location. Args: location: The city or location to get weather for. unit: Temperature unit, either 'celsius' or 'fahrenheit'. include_forecast: Whether to include forecast data. Returns: Weather information as a formatted string Examples: >>> get_weather_detailed("London") "London: 15°C, partly cloudy" >>> get_weather_detailed("New York", "fahrenheit", True) "New York: 59°F, sunny. Tomorrow: 62°F, cloudy" """ ), id="google_style_docstring", ), pytest.param( ( """Get detailed weather information for a location. This function retrieves current weather conditions and optionally includes a forecast for the specified location. :param location: The city or location to get weather for. :type location: str :param unit: Temperature unit, either 'celsius' or 'fahrenheit'. :type unit: str :param include_forecast: Whether to include forecast data. :type include_forecast: bool :returns: Weather information as a formatted string. :rtype: str :example: >>> get_weather_detailed("London") "London: 15°C, partly cloudy" >>> get_weather_detailed("New York", "fahrenheit", True) "New York: 59°F, sunny. Tomorrow: 62°F, cloudy """ ), id="rest_style_docstring", ), pytest.param( ( """Get detailed weather information for a location. This function retrieves current weather conditions and optionally includes a forecast for the specified location. Parameters ---------- location : str The city or location to get weather for. unit : str Temperature unit, either 'celsius' or 'fahrenheit'. include_forecast : bool Whether to include forecast data. Returns ------- str Weather information as a formatted string. Examples -------- >>> get_weather_detailed("London") "London: 15°C, partly cloudy" >>> get_weather_detailed("New York", "fahrenheit", True) "New York: 59°F, sunny. Tomorrow: 62°F, cloudy" """ ), id="numpy_style_docstring", ), pytest.param( ( """Get detailed weather information for a location. This function retrieves current weather conditions and optionally includes a forecast for the specified location. @param location: The city or location to get weather for. @type location: str @param unit: Temperature unit, either 'celsius' or 'fahrenheit'. @type unit: str @param include_forecast: Whether to include forecast data. @type include_forecast: bool @return: Weather information as a formatted string. @rtype: str @example: >>> get_weather_detailed("London") "London: 15°C, partly cloudy" >>> get_weather_detailed("New York", "fahrenheit", True) "New York: 59°F, sunny. Tomorrow: 62°F, cloudy" """ ), id="epydoc_style_docstring", ), ], ) def test_docstring_parsing_with_parameters(self, docstring: str) -> None: def get_weather_detailed(location: str, unit: str = "celsius", include_forecast: bool = False) -> str: # noqa: ARG001 return f"Weather for {location}" get_weather_detailed.__doc__ = docstring function_tool = beta_tool(get_weather_detailed) expected_description = ( "Get detailed weather information for a location.\n\n" "This function retrieves current weather conditions and optionally\n" "includes a forecast for the specified location." ) expected_schema = { "additionalProperties": False, "type": "object", "properties": { "location": { "title": "Location", "type": "string", "description": "The city or location to get weather for.", }, "unit": { "title": "Unit", "type": "string", "default": "celsius", "description": "Temperature unit, either 'celsius' or 'fahrenheit'.", }, "include_forecast": { "title": "Include Forecast", "type": "boolean", "default": False, "description": "Whether to include forecast data.", }, }, "required": ["location"], } assert function_tool.description == expected_description assert function_tool.input_schema == expected_schema def test_decorator_without_parentheses(self) -> None: """Test using @function_tool decorator without parentheses.""" @beta_tool def multiply(x: int, y: int) -> str: """Multiply two numbers.""" return str(x * y) assert multiply.name == "multiply" assert multiply.description == "Multiply two numbers." assert multiply.call({"x": 3, "y": 4}) == "12" expected_schema = { "additionalProperties": False, "type": "object", "properties": { "x": {"title": "X", "type": "integer"}, "y": {"title": "Y", "type": "integer"}, }, "required": ["x", "y"], } assert multiply.input_schema == expected_schema def test_decorator_with_parentheses(self) -> None: """Test using @function_tool() decorator with parentheses.""" @beta_tool() def divide(a: float, b: float) -> str: """Divide two numbers.""" return str(a / b) assert divide.name == "divide" assert divide.description == "Divide two numbers." assert divide.call({"a": 10.0, "b": 2.0}) == "5.0" def test_decorator_with_custom_parameters(self) -> None: """Test using @function_tool() decorator with custom name and description.""" @beta_tool(name="custom_calculator", description="A custom calculator function") def calculate(value: int) -> str: """Original description that should be overridden.""" return str(value * 2) assert calculate.name == "custom_calculator" assert calculate.description == "A custom calculator function" assert calculate.call({"value": 5}) == "10" def test_docstring_parsing_simple(self) -> None: """Test that simple docstrings still work correctly.""" def simple_add(a: int, b: int) -> str: """Add two numbers together.""" return str(a + b) function_tool = beta_tool(simple_add) assert function_tool.description == "Add two numbers together." assert _get_parameters_info(function_tool) == {} # Schema should not have descriptions for parameters expected_schema = { "additionalProperties": False, "type": "object", "properties": {"a": {"title": "A", "type": "integer"}, "b": {"title": "B", "type": "integer"}}, "required": ["a", "b"], } assert function_tool.input_schema == expected_schema def _get_parameters_info(fn: BaseFunctionTool[Any]) -> dict[str, str]: param_info: dict[str, str] = {} for param in fn._parsed_docstring.params: if param.description: param_info[param.arg_name] = param.description.strip() return param_info anthropic-sdk-python-0.69.0/tests/lib/tools/test_runners.py000066400000000000000000000621661506653454500241000ustar00rootroot00000000000000import json import logging from typing import Any, Dict, List, Union from typing_extensions import Literal, TypeVar import pytest from respx import MockRouter from inline_snapshot import external, snapshot from anthropic import Anthropic, AsyncAnthropic, beta_tool, beta_async_tool from anthropic._utils import assert_signatures_in_sync from anthropic._compat import PYDANTIC_V1 from anthropic.lib.tools import BetaFunctionToolResultType from anthropic.types.beta.beta_message import BetaMessage from anthropic.types.beta.beta_message_param import BetaMessageParam from anthropic.types.beta.beta_tool_result_block_param import BetaToolResultBlockParam from ..utils import print_obj from ...conftest import base_url from ..snapshots import make_snapshot_request, make_async_snapshot_request, make_stream_snapshot_request _T = TypeVar("_T") # all the snapshots in this file are auto-generated from the live API # # you can update them with # # `ANTHROPIC_LIVE=1 pytest --inline-snapshot=fix -p no:xdist -o addopts=""` snapshots = { "basic": { "responses": snapshot( [ '{"id": "msg_01Lf1uRSXq1sB9df6EigSkXA", "type": "message", "role": "assistant", "model": "claude-3-5-sonnet-20241022", "content": [{"type": "text", "text": "I\'ll help you check the weather in San Francisco. I\'ll use the get_weather function, and I\'ll show you the temperature in both Celsius and Fahrenheit for completeness."}, {"type": "tool_use", "id": "toolu_013bzsyqF4LyvJj6CF5gYCEn", "name": "get_weather", "input": {"location": "San Francisco, CA", "units": "c"}}, {"type": "tool_use", "id": "toolu_01Ugb5BSmDUth8vbdkUsNYrs", "name": "get_weather", "input": {"location": "San Francisco, CA", "units": "f"}}], "stop_reason": "tool_use", "stop_sequence": null, "usage": {"input_tokens": 473, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, "output_tokens": 169, "service_tier": "standard"}}', '{"id": "msg_01SUujjdE6BMF3CYWCTR4vHF", "type": "message", "role": "assistant", "model": "claude-3-5-sonnet-20241022", "content": [{"type": "text", "text": "The weather in San Francisco is currently sunny with a temperature of 20\\u00b0C (68\\u00b0F)."}], "stop_reason": "end_turn", "stop_sequence": null, "usage": {"input_tokens": 760, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, "output_tokens": 25, "service_tier": "standard"}}', ] ), "result": snapshot("""\ BetaMessage( container=None, content=[ BetaTextBlock( citations=None, text='The weather in San Francisco is currently sunny with a temperature of 20°C (68°F).', type='text' ) ], context_management=None, id='msg_01SUujjdE6BMF3CYWCTR4vHF', model='claude-3-5-sonnet-20241022', role='assistant', stop_reason='end_turn', stop_sequence=None, type='message', usage=BetaUsage( cache_creation=BetaCacheCreation(ephemeral_1h_input_tokens=0, ephemeral_5m_input_tokens=0), cache_creation_input_tokens=0, cache_read_input_tokens=0, input_tokens=760, output_tokens=25, server_tool_use=None, service_tier='standard' ) ) """), }, "custom": { "responses": snapshot( [ '{"id": "msg_01QebvpjSMHnjRVYDQpthDCM", "type": "message", "role": "assistant", "model": "claude-3-5-sonnet-20241022", "content": [{"type": "text", "text": "I\'ll help you check the weather in San Francisco using the get_weather function. Since you want it in Celsius, I\'ll use \'c\' for the units."}, {"type": "tool_use", "id": "toolu_01W8QFaZz5X8w6UezBfvJaHG", "name": "get_weather", "input": {"location": "San Francisco, CA", "units": "c"}}], "stop_reason": "tool_use", "stop_sequence": null, "usage": {"input_tokens": 476, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, "output_tokens": 110, "service_tier": "standard"}}', '{"id": "msg_01GQD2QBjkCMtD8rEfbF7J7y", "type": "message", "role": "assistant", "model": "claude-3-5-sonnet-20241022", "content": [{"type": "text", "text": "The weather in San Francisco is currently 20\\u00b0C and it\'s sunny."}], "stop_reason": "end_turn", "stop_sequence": null, "usage": {"input_tokens": 625, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, "output_tokens": 20, "service_tier": "standard"}}', ] ), "result": snapshot("""\ BetaMessage( container=None, content=[ BetaTextBlock( citations=None, text="The weather in San Francisco is currently 20°C and it's sunny.", type='text' ) ], context_management=None, id='msg_01GQD2QBjkCMtD8rEfbF7J7y', model='claude-3-5-sonnet-20241022', role='assistant', stop_reason='end_turn', stop_sequence=None, type='message', usage=BetaUsage( cache_creation=BetaCacheCreation(ephemeral_1h_input_tokens=0, ephemeral_5m_input_tokens=0), cache_creation_input_tokens=0, cache_read_input_tokens=0, input_tokens=625, output_tokens=20, server_tool_use=None, service_tier='standard' ) ) """), }, "streaming": { "result": snapshot("""\ BetaMessage( container=None, content=[ BetaTextBlock(citations=None, text='The weather in San Francisco is currently 68°F and sunny.', type='text') ], context_management=None, id='msg_01FtWrpBLsm99NpQCoFrhuf9', model='claude-3-5-sonnet-20241022', role='assistant', stop_reason='end_turn', stop_sequence=None, type='message', usage=BetaUsage( cache_creation=BetaCacheCreation(ephemeral_1h_input_tokens=0, ephemeral_5m_input_tokens=0), cache_creation_input_tokens=0, cache_read_input_tokens=0, input_tokens=605, output_tokens=18, server_tool_use=None, service_tier='standard' ) ) """) }, "tool_call": { "responses": snapshot( [ '{"id": "msg_01CcxTJKA7URvATmjs9yemNw", "type": "message", "role": "assistant", "model": "claude-3-5-sonnet-20241022", "content": [{"type": "text", "text": "I\'ll help you check the weather in San Francisco using Celsius units."}, {"type": "tool_use", "id": "toolu_01X4rAg6afq9WTkdXDwNdo9g", "name": "get_weather", "input": {"location": "SF", "units": "c"}}], "stop_reason": "tool_use", "stop_sequence": null, "usage": {"input_tokens": 414, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, "output_tokens": 86, "service_tier": "standard"}}', '{"id": "msg_01Hswpqi8rjN9k6Erfof4NML", "type": "message", "role": "assistant", "model": "claude-3-5-sonnet-20241022", "content": [{"type": "text", "text": "The weather in San Francisco is currently 20\\u00b0C and it\'s sunny."}], "stop_reason": "end_turn", "stop_sequence": null, "usage": {"input_tokens": 536, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, "output_tokens": 20, "service_tier": "standard"}}', ] ), }, "tool_call_error": { "responses": snapshot( [ '{"id": "msg_01UCU1h4ayreA2Ridzbpk5ut", "type": "message", "role": "assistant", "model": "claude-3-5-sonnet-20241022", "content": [{"type": "text", "text": "I\'ll help you check the weather in San Francisco. Since the location format should include the state, I\'ll use \\"San Francisco, CA\\". I\'ll provide the temperature in both Celsius and Fahrenheit for completeness."}, {"type": "tool_use", "id": "toolu_01ECouLXJaT6yocMNDstufPc", "name": "get_weather", "input": {"location": "San Francisco, CA", "units": "c"}}, {"type": "tool_use", "id": "toolu_01FHQTcVXvPoLL3bzxsAUtJJ", "name": "get_weather", "input": {"location": "San Francisco, CA", "units": "f"}}], "stop_reason": "tool_use", "stop_sequence": null, "usage": {"input_tokens": 473, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, "output_tokens": 176, "service_tier": "standard"}}', '{"id": "msg_01PYwhqAdduuZYymTokQ4JQU", "type": "message", "role": "assistant", "model": "claude-3-5-sonnet-20241022", "content": [{"type": "text", "text": "The weather in San Francisco, CA is currently sunny with a temperature of 68\\u00b0F."}], "stop_reason": "end_turn", "stop_sequence": null, "usage": {"input_tokens": 749, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, "output_tokens": 23, "service_tier": "standard"}}', ] ) }, } @pytest.mark.skipif(PYDANTIC_V1, reason="tool runner not supported with pydantic v1") class TestSyncRunTools: @pytest.mark.respx(base_url=base_url) def test_basic_call_sync(self, client: Anthropic, respx_mock: MockRouter, monkeypatch: pytest.MonkeyPatch) -> None: @beta_tool def get_weather(location: str, units: Literal["c", "f"]) -> BetaFunctionToolResultType: """Lookup the weather for a given city in either celsius or fahrenheit Args: location: The city and state, e.g. San Francisco, CA units: Unit for the output, either 'c' for celsius or 'f' for fahrenheit Returns: A dictionary containing the location, temperature, and weather condition. """ return json.dumps(_get_weather(location, units)) message = make_snapshot_request( lambda c: c.beta.messages.tool_runner( max_tokens=1024, model="claude-3-5-sonnet-latest", tools=[get_weather], messages=[{"role": "user", "content": "What is the weather in SF?"}], ).until_done(), content_snapshot=snapshots["basic"]["responses"], path="/v1/messages", mock_client=client, respx_mock=respx_mock, ) assert print_obj(message, monkeypatch) == snapshots["basic"]["result"] @pytest.mark.respx(base_url=base_url) def test_tool_call_error( self, client: Anthropic, respx_mock: MockRouter, monkeypatch: pytest.MonkeyPatch, caplog: pytest.LogCaptureFixture, ) -> None: called = None @beta_tool def get_weather(location: str, units: Literal["c", "f"]) -> BetaFunctionToolResultType: """Lookup the weather for a given city in either celsius or fahrenheit Args: location: The city and state, e.g. San Francisco, CA units: Unit for the output, either 'c' for celsius or 'f' for fahrenheit Returns: A dictionary containing the location, temperature, and weather condition. """ nonlocal called if called is None: called = True raise RuntimeError("Unexpected error, try again") return json.dumps(_get_weather(location, units)) def tool_runner(client: Anthropic) -> List[Union[BetaMessageParam, None]]: runner = client.beta.messages.tool_runner( max_tokens=1024, model="claude-3-5-sonnet-latest", tools=[get_weather], messages=[{"role": "user", "content": "What is the weather in SF?"}], ) actual_responses: List[Union[BetaMessageParam, None]] = [] for _ in runner: tool_call_response = runner.generate_tool_call_response() if tool_call_response is not None: actual_responses.append(tool_call_response) return actual_responses with caplog.at_level(logging.ERROR): message = make_snapshot_request( tool_runner, content_snapshot=snapshots["tool_call_error"]["responses"], path="/v1/messages", mock_client=client, respx_mock=respx_mock, ) assert caplog.record_tuples == [ ( "anthropic.lib.tools._beta_runner", logging.ERROR, "Error occurred while calling tool: get_weather", ), ] assert print_obj(message, monkeypatch) == snapshot("""\ [ { 'role': 'user', 'content': [ { 'type': 'tool_result', 'tool_use_id': 'toolu_01ECouLXJaT6yocMNDstufPc', 'content': "RuntimeError('Unexpected error, try again')", 'is_error': True }, { 'type': 'tool_result', 'tool_use_id': 'toolu_01FHQTcVXvPoLL3bzxsAUtJJ', 'content': '{"location": "San Francisco, CA", "temperature": "68\\\\u00b0F", "condition": "Sunny"}' } ] } ] """) @pytest.mark.respx(base_url=base_url) def test_custom_message_handling( self, client: Anthropic, respx_mock: MockRouter, monkeypatch: pytest.MonkeyPatch ) -> None: @beta_tool def get_weather(location: str, units: Literal["c", "f"]) -> BetaFunctionToolResultType: """Lookup the weather for a given city in either celsius or fahrenheit Args: location: The city and state, e.g. San Francisco, CA units: Unit for the output, either 'c' for celsius or 'f' for fahrenheit Returns: A dictionary containing the location, temperature, and weather condition. """ return json.dumps(_get_weather(location, units)) def custom_message_handling(client: Anthropic) -> BetaMessage: runner = client.beta.messages.tool_runner( model="claude-3-5-sonnet-latest", messages=[{"role": "user", "content": "What's the weather in SF in Celsius?"}], tools=[get_weather], max_tokens=1024, ) for message in runner: # handle only where there is a tool call if message.content[0].type == "tool_use": runner.append_messages( BetaMessageParam( role="assistant", content=[ BetaToolResultBlockParam( tool_use_id=message.content[0].id, content="The weather in San Francisco, CA is currently sunny with a temperature of 20°C.", type="tool_result", ) ], ), ) return runner.until_done() message = make_snapshot_request( custom_message_handling, content_snapshot=snapshots["custom"]["responses"], path="/v1/messages", mock_client=client, respx_mock=respx_mock, ) assert print_obj(message, monkeypatch) == snapshots["custom"]["result"] @pytest.mark.respx(base_url=base_url) def test_tool_call_caching(self, client: Anthropic, respx_mock: MockRouter) -> None: called = None @beta_tool def get_weather(location: str, units: Literal["c", "f"]) -> BetaFunctionToolResultType: nonlocal called """Lookup the weather for a given city in either celsius or fahrenheit Args: location: The city and state, e.g. San Francisco, CA units: Unit for the output, either 'c' for celsius or 'f' for fahrenheit Returns: A dictionary containing the location, temperature, and weather condition. """ if called is None: called = True return json.dumps(_get_weather(location, units)) raise RuntimeError("This tool should not be called again") def tool_runner(client: Anthropic) -> None: runner = client.beta.messages.tool_runner( model="claude-3-5-sonnet-latest", messages=[{"role": "user", "content": "What's the weather in SF in Celsius?"}], tools=[get_weather], max_tokens=1024, ) for _ in runner: response1 = runner.generate_tool_call_response() response2 = runner.generate_tool_call_response() if response1 is not None: assert response1 is response2 make_snapshot_request( tool_runner, content_snapshot=snapshots["tool_call"]["responses"], path="/v1/messages", mock_client=client, respx_mock=respx_mock, ) @pytest.mark.respx(base_url=base_url) def test_streaming_call_sync( self, client: Anthropic, respx_mock: MockRouter, monkeypatch: pytest.MonkeyPatch ) -> None: @beta_tool def get_weather(location: str, units: Literal["c", "f"]) -> BetaFunctionToolResultType: """Lookup the weather for a given city in either celsius or fahrenheit Args: location: The city and state, e.g. San Francisco, CA units: Unit for the output, either 'c' for celsius or 'f' for fahrenheit Returns: A dictionary containing the location, temperature, and weather condition. """ return json.dumps(_get_weather(location, units)) last_response_messsage = make_stream_snapshot_request( lambda c: c.beta.messages.tool_runner( max_tokens=1024, model="claude-3-5-sonnet-latest", tools=[get_weather], messages=[{"role": "user", "content": "What is the weather in SF?"}], stream=True, ).until_done(), content_snapshot=snapshot(external("uuid:e2140c0f-07db-47ee-b86b-c2ec476866d5.json")), path="/v1/messages", mock_client=client, respx_mock=respx_mock, ) assert print_obj(last_response_messsage, monkeypatch) == snapshots["streaming"]["result"] @pytest.mark.respx(base_url=base_url) def test_max_iterations(self, client: Anthropic, respx_mock: MockRouter, monkeypatch: pytest.MonkeyPatch) -> None: @beta_tool def get_weather(location: str, units: Literal["c", "f"]) -> BetaFunctionToolResultType: """Lookup the weather for a given city in either celsius or fahrenheit Args: location: The city and state, e.g. San Francisco, CA units: Unit for the output, either 'c' for celsius or 'f' for fahrenheit Returns: A dictionary containing the location, temperature, and weather condition. """ return json.dumps(_get_weather(location, units)) def get_weather_answers(client: Anthropic) -> List[Union[BetaMessageParam, None]]: runner = client.beta.messages.tool_runner( max_tokens=1024, model="claude-3-5-sonnet-latest", tools=[get_weather], messages=[ { "role": "user", "content": ( "What's the weather in San Francisco, New York, London, Tokyo and Paris?" "If you need to use tools, call only one tool at a time. Wait for the tool’s" "response before making another call. Never call multiple tools at once." ), } ], max_iterations=2, ) answers: List[Union[BetaMessageParam, None]] = [] for _ in runner: answers.append(runner.generate_tool_call_response()) return answers answers = make_snapshot_request( get_weather_answers, content_snapshot=snapshot(external("uuid:ef758469-6fa6-454c-b2e6-19d0b450a8c5.json")), path="/v1/messages", mock_client=client, respx_mock=respx_mock, ) assert print_obj(answers, monkeypatch) == snapshot("""\ [ { 'role': 'user', 'content': [ { 'type': 'tool_result', 'tool_use_id': 'toolu_01GiQJzt5d2ThB4fSUsRCSML', 'content': '{"location": "San Francisco, CA", "temperature": "68\\\\u00b0F", "condition": "Sunny"}' } ] }, { 'role': 'user', 'content': [ { 'type': 'tool_result', 'tool_use_id': 'toolu_015yzRQ92SwYGz5Veoq7A3P7', 'content': '{"location": "New York, NY", "temperature": "68\\\\u00b0F", "condition": "Sunny"}' } ] } ] """) @pytest.mark.respx(base_url=base_url) def test_streaming_call_sync_events(self, client: Anthropic, respx_mock: MockRouter) -> None: @beta_tool def get_weather(location: str, units: Literal["c", "f"]) -> BetaFunctionToolResultType: """Lookup the weather for a given city in either celsius or fahrenheit Args: location: The city and state, e.g. San Francisco, CA units: Unit for the output, either 'c' for celsius or 'f' for fahrenheit Returns: A dictionary containing the location, temperature, and weather condition. """ return json.dumps(_get_weather(location, units)) def accumulate_events(client: Anthropic) -> List[str]: events: list[str] = [] runner = client.beta.messages.tool_runner( max_tokens=1024, model="claude-3-5-sonnet-latest", tools=[get_weather], messages=[{"role": "user", "content": "What is the weather in SF?"}], stream=True, ) for stream in runner: for event in stream: events.append(event.type) return events events = make_stream_snapshot_request( accumulate_events, content_snapshot=snapshot(external("uuid:9cb114c8-69bd-4111-841b-edee30333afd.json")), path="/v1/messages", mock_client=client, respx_mock=respx_mock, ) assert set(events) == snapshot( { "content_block_delta", "content_block_start", "content_block_stop", "input_json", "message_delta", "message_start", "message_stop", "text", } ) @pytest.mark.skipif(PYDANTIC_V1, reason="tool runner not supported with pydantic v1") @pytest.mark.respx(base_url=base_url) async def test_basic_call_async( async_client: AsyncAnthropic, respx_mock: MockRouter, monkeypatch: pytest.MonkeyPatch ) -> None: @beta_async_tool async def get_weather(location: str, units: Literal["c", "f"]) -> BetaFunctionToolResultType: """Lookup the weather for a given city in either celsius or fahrenheit Args: location: The city and state, e.g. San Francisco, CA units: Unit for the output, either 'c' for celsius or 'f' for fahrenheit Returns: A dictionary containing the location, temperature, and weather condition. """ return json.dumps(_get_weather(location, units)) message = await make_async_snapshot_request( lambda c: c.beta.messages.tool_runner( max_tokens=1024, model="claude-3-5-sonnet-latest", tools=[get_weather], messages=[{"role": "user", "content": "What is the weather in SF?"}], ).until_done(), content_snapshot=snapshots["basic"]["responses"], path="/v1/messages", mock_client=async_client, respx_mock=respx_mock, ) assert print_obj(message, monkeypatch) == snapshots["basic"]["result"] def _get_weather(location: str, units: Literal["c", "f"]) -> Dict[str, Any]: # Simulate a weather API call print(f"Fetching weather for {location} in {units}") if units == "c": return { "location": location, "temperature": "20°C", "condition": "Sunny", } else: return { "location": location, "temperature": "68°F", "condition": "Sunny", } @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"]) def test_parse_method_in_sync(sync: bool, client: Anthropic, async_client: AsyncAnthropic) -> None: checking_client: "Anthropic | AsyncAnthropic" = client if sync else async_client assert_signatures_in_sync( checking_client.beta.messages.create, checking_client.beta.messages.tool_runner, exclude_params={ "tools", # TODO "stream", }, ) anthropic-sdk-python-0.69.0/tests/lib/utils.py000066400000000000000000000042161506653454500213350ustar00rootroot00000000000000from __future__ import annotations import io import inspect from typing import Any, Iterable from typing_extensions import TypeAlias import rich import pytest import pydantic ReprArgs: TypeAlias = "Iterable[tuple[str | None, Any]]" def print_obj(obj: object, monkeypatch: pytest.MonkeyPatch) -> str: """Pretty print an object to a string""" # monkeypatch pydantic model printing so that model fields # are always printed in the same order so we can reliably # use this for snapshot tests original_repr = pydantic.BaseModel.__repr_args__ def __repr_args__(self: pydantic.BaseModel) -> ReprArgs: return sorted(original_repr(self), key=lambda arg: arg[0] or arg) with monkeypatch.context() as m: m.setattr(pydantic.BaseModel, "__repr_args__", __repr_args__) string = rich_print_str(obj) # we remove all `fn_name..` occurrences # so that we can share the same snapshots between # pydantic v1 and pydantic v2 as their output for # generic models differs, e.g. # # v2: `GenericModel[test_generic_model..Location]` # v1: `GenericModel[Location]` return clear_locals(string, stacklevel=2) def get_caller_name(*, stacklevel: int = 1) -> str: frame = inspect.currentframe() assert frame is not None for i in range(stacklevel): frame = frame.f_back assert frame is not None, f"no {i}th frame" return frame.f_code.co_name def clear_locals(string: str, *, stacklevel: int) -> str: caller = get_caller_name(stacklevel=stacklevel + 1) return string.replace(f"{caller}..", "") def get_snapshot_value(snapshot: Any) -> Any: if not hasattr(snapshot, "_old_value"): return snapshot old = snapshot._old_value if not hasattr(old, "value"): return old loader = getattr(old.value, "_load_value", None) return loader() if loader else old.value def rich_print_str(obj: object) -> str: """Like `rich.print()` but returns the string instead""" buf = io.StringIO() console = rich.console.Console(file=buf, width=120) console.print(obj) return buf.getvalue() anthropic-sdk-python-0.69.0/tests/sample_file.txt000066400000000000000000000000161506653454500220700ustar00rootroot00000000000000Hello, world! anthropic-sdk-python-0.69.0/tests/test_client.py000066400000000000000000002217331506653454500217510ustar00rootroot00000000000000# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations import gc import os import sys import json import asyncio import inspect import tracemalloc from typing import Any, Union, cast from unittest import mock from typing_extensions import Literal import httpx import pytest from respx import MockRouter from pydantic import ValidationError from anthropic import Anthropic, AsyncAnthropic, APIResponseValidationError from anthropic._types import Omit from anthropic._utils import asyncify from anthropic._models import BaseModel, FinalRequestOptions from anthropic._streaming import Stream, AsyncStream from anthropic._exceptions import APIStatusError, APITimeoutError, APIResponseValidationError from anthropic._base_client import ( DEFAULT_TIMEOUT, HTTPX_DEFAULT_TIMEOUT, BaseClient, OtherPlatform, DefaultHttpxClient, DefaultAsyncHttpxClient, get_platform, make_request_options, ) from .utils import update_env base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") api_key = "my-anthropic-api-key" def _get_params(client: BaseClient[Any, Any]) -> dict[str, str]: request = client._build_request(FinalRequestOptions(method="get", url="/foo")) url = httpx.URL(request.url) return dict(url.params) def _low_retry_timeout(*_args: Any, **_kwargs: Any) -> float: return 0.1 def _get_open_connections(client: Anthropic | AsyncAnthropic) -> int: transport = client._client._transport assert isinstance(transport, httpx.HTTPTransport) or isinstance(transport, httpx.AsyncHTTPTransport) pool = transport._pool return len(pool._requests) class TestAnthropic: client = Anthropic(base_url=base_url, api_key=api_key, _strict_response_validation=True) @pytest.mark.respx(base_url=base_url) def test_raw_response(self, respx_mock: MockRouter) -> None: respx_mock.post("/foo").mock(return_value=httpx.Response(200, json={"foo": "bar"})) response = self.client.post("/foo", cast_to=httpx.Response) assert response.status_code == 200 assert isinstance(response, httpx.Response) assert response.json() == {"foo": "bar"} @pytest.mark.respx(base_url=base_url) def test_raw_response_for_binary(self, respx_mock: MockRouter) -> None: respx_mock.post("/foo").mock( return_value=httpx.Response(200, headers={"Content-Type": "application/binary"}, content='{"foo": "bar"}') ) response = self.client.post("/foo", cast_to=httpx.Response) assert response.status_code == 200 assert isinstance(response, httpx.Response) assert response.json() == {"foo": "bar"} def test_copy(self) -> None: copied = self.client.copy() assert id(copied) != id(self.client) copied = self.client.copy(api_key="another my-anthropic-api-key") assert copied.api_key == "another my-anthropic-api-key" assert self.client.api_key == "my-anthropic-api-key" def test_copy_default_options(self) -> None: # options that have a default are overridden correctly copied = self.client.copy(max_retries=7) assert copied.max_retries == 7 assert self.client.max_retries == 2 copied2 = copied.copy(max_retries=6) assert copied2.max_retries == 6 assert copied.max_retries == 7 # timeout assert isinstance(self.client.timeout, httpx.Timeout) copied = self.client.copy(timeout=None) assert copied.timeout is None assert isinstance(self.client.timeout, httpx.Timeout) def test_copy_default_headers(self) -> None: client = Anthropic( base_url=base_url, api_key=api_key, _strict_response_validation=True, default_headers={"X-Foo": "bar"} ) assert client.default_headers["X-Foo"] == "bar" # does not override the already given value when not specified copied = client.copy() assert copied.default_headers["X-Foo"] == "bar" # merges already given headers copied = client.copy(default_headers={"X-Bar": "stainless"}) assert copied.default_headers["X-Foo"] == "bar" assert copied.default_headers["X-Bar"] == "stainless" # uses new values for any already given headers copied = client.copy(default_headers={"X-Foo": "stainless"}) assert copied.default_headers["X-Foo"] == "stainless" # set_default_headers # completely overrides already set values copied = client.copy(set_default_headers={}) assert copied.default_headers.get("X-Foo") is None copied = client.copy(set_default_headers={"X-Bar": "Robert"}) assert copied.default_headers["X-Bar"] == "Robert" with pytest.raises( ValueError, match="`default_headers` and `set_default_headers` arguments are mutually exclusive", ): client.copy(set_default_headers={}, default_headers={"X-Foo": "Bar"}) def test_copy_default_query(self) -> None: client = Anthropic( base_url=base_url, api_key=api_key, _strict_response_validation=True, default_query={"foo": "bar"} ) assert _get_params(client)["foo"] == "bar" # does not override the already given value when not specified copied = client.copy() assert _get_params(copied)["foo"] == "bar" # merges already given params copied = client.copy(default_query={"bar": "stainless"}) params = _get_params(copied) assert params["foo"] == "bar" assert params["bar"] == "stainless" # uses new values for any already given headers copied = client.copy(default_query={"foo": "stainless"}) assert _get_params(copied)["foo"] == "stainless" # set_default_query # completely overrides already set values copied = client.copy(set_default_query={}) assert _get_params(copied) == {} copied = client.copy(set_default_query={"bar": "Robert"}) assert _get_params(copied)["bar"] == "Robert" with pytest.raises( ValueError, # TODO: update match="`default_query` and `set_default_query` arguments are mutually exclusive", ): client.copy(set_default_query={}, default_query={"foo": "Bar"}) def test_copy_signature(self) -> None: # ensure the same parameters that can be passed to the client are defined in the `.copy()` method init_signature = inspect.signature( # mypy doesn't like that we access the `__init__` property. self.client.__init__, # type: ignore[misc] ) copy_signature = inspect.signature(self.client.copy) exclude_params = {"transport", "proxies", "_strict_response_validation"} for name in init_signature.parameters.keys(): if name in exclude_params: continue copy_param = copy_signature.parameters.get(name) assert copy_param is not None, f"copy() signature is missing the {name} param" @pytest.mark.skipif(sys.version_info >= (3, 10), reason="fails because of a memory leak that started from 3.12") def test_copy_build_request(self) -> None: options = FinalRequestOptions(method="get", url="/foo") def build_request(options: FinalRequestOptions) -> None: client = self.client.copy() client._build_request(options) # ensure that the machinery is warmed up before tracing starts. build_request(options) gc.collect() tracemalloc.start(1000) snapshot_before = tracemalloc.take_snapshot() ITERATIONS = 10 for _ in range(ITERATIONS): build_request(options) gc.collect() snapshot_after = tracemalloc.take_snapshot() tracemalloc.stop() def add_leak(leaks: list[tracemalloc.StatisticDiff], diff: tracemalloc.StatisticDiff) -> None: if diff.count == 0: # Avoid false positives by considering only leaks (i.e. allocations that persist). return if diff.count % ITERATIONS != 0: # Avoid false positives by considering only leaks that appear per iteration. return for frame in diff.traceback: if any( frame.filename.endswith(fragment) for fragment in [ # to_raw_response_wrapper leaks through the @functools.wraps() decorator. # # removing the decorator fixes the leak for reasons we don't understand. "anthropic/_legacy_response.py", "anthropic/_response.py", # pydantic.BaseModel.model_dump || pydantic.BaseModel.dict leak memory for some reason. "anthropic/_compat.py", # Standard library leaks we don't care about. "/logging/__init__.py", ] ): return leaks.append(diff) leaks: list[tracemalloc.StatisticDiff] = [] for diff in snapshot_after.compare_to(snapshot_before, "traceback"): add_leak(leaks, diff) if leaks: for leak in leaks: print("MEMORY LEAK:", leak) for frame in leak.traceback: print(frame) raise AssertionError() def test_request_timeout(self) -> None: request = self.client._build_request(FinalRequestOptions(method="get", url="/foo")) timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore assert timeout == DEFAULT_TIMEOUT request = self.client._build_request( FinalRequestOptions(method="get", url="/foo", timeout=httpx.Timeout(100.0)) ) timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore assert timeout == httpx.Timeout(100.0) def test_client_timeout_option(self) -> None: client = Anthropic( base_url=base_url, api_key=api_key, _strict_response_validation=True, timeout=httpx.Timeout(0) ) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore assert timeout == httpx.Timeout(0) def test_http_client_timeout_option(self) -> None: # custom timeout given to the httpx client should be used with httpx.Client(timeout=None) as http_client: client = Anthropic( base_url=base_url, api_key=api_key, _strict_response_validation=True, http_client=http_client ) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore assert timeout == httpx.Timeout(None) # no timeout given to the httpx client should not use the httpx default with httpx.Client() as http_client: client = Anthropic( base_url=base_url, api_key=api_key, _strict_response_validation=True, http_client=http_client ) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore assert timeout == DEFAULT_TIMEOUT # explicitly passing the default timeout currently results in it being ignored with httpx.Client(timeout=HTTPX_DEFAULT_TIMEOUT) as http_client: client = Anthropic( base_url=base_url, api_key=api_key, _strict_response_validation=True, http_client=http_client ) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore assert timeout == DEFAULT_TIMEOUT # our default async def test_invalid_http_client(self) -> None: with pytest.raises(TypeError, match="Invalid `http_client` arg"): async with httpx.AsyncClient() as http_client: Anthropic( base_url=base_url, api_key=api_key, _strict_response_validation=True, http_client=cast(Any, http_client), ) def test_default_headers_option(self) -> None: client = Anthropic( base_url=base_url, api_key=api_key, _strict_response_validation=True, default_headers={"X-Foo": "bar"} ) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) assert request.headers.get("x-foo") == "bar" assert request.headers.get("x-stainless-lang") == "python" client2 = Anthropic( base_url=base_url, api_key=api_key, _strict_response_validation=True, default_headers={ "X-Foo": "stainless", "X-Stainless-Lang": "my-overriding-header", }, ) request = client2._build_request(FinalRequestOptions(method="get", url="/foo")) assert request.headers.get("x-foo") == "stainless" assert request.headers.get("x-stainless-lang") == "my-overriding-header" def test_validate_headers(self) -> None: client = Anthropic(base_url=base_url, api_key=api_key, _strict_response_validation=True) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) assert request.headers.get("X-Api-Key") == api_key with update_env(**{"ANTHROPIC_API_KEY": Omit()}): client2 = Anthropic(base_url=base_url, api_key=None, _strict_response_validation=True) with pytest.raises( TypeError, match="Could not resolve authentication method. Expected either api_key or auth_token to be set. Or for one of the `X-Api-Key` or `Authorization` headers to be explicitly omitted", ): client2._build_request(FinalRequestOptions(method="get", url="/foo")) request2 = client2._build_request(FinalRequestOptions(method="get", url="/foo", headers={"X-Api-Key": Omit()})) assert request2.headers.get("X-Api-Key") is None def test_default_query_option(self) -> None: client = Anthropic( base_url=base_url, api_key=api_key, _strict_response_validation=True, default_query={"query_param": "bar"} ) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) url = httpx.URL(request.url) assert dict(url.params) == {"query_param": "bar"} request = client._build_request( FinalRequestOptions( method="get", url="/foo", params={"foo": "baz", "query_param": "overridden"}, ) ) url = httpx.URL(request.url) assert dict(url.params) == {"foo": "baz", "query_param": "overridden"} def test_request_extra_json(self) -> None: request = self.client._build_request( FinalRequestOptions( method="post", url="/foo", json_data={"foo": "bar"}, extra_json={"baz": False}, ), ) data = json.loads(request.content.decode("utf-8")) assert data == {"foo": "bar", "baz": False} request = self.client._build_request( FinalRequestOptions( method="post", url="/foo", extra_json={"baz": False}, ), ) data = json.loads(request.content.decode("utf-8")) assert data == {"baz": False} # `extra_json` takes priority over `json_data` when keys clash request = self.client._build_request( FinalRequestOptions( method="post", url="/foo", json_data={"foo": "bar", "baz": True}, extra_json={"baz": None}, ), ) data = json.loads(request.content.decode("utf-8")) assert data == {"foo": "bar", "baz": None} def test_request_extra_headers(self) -> None: request = self.client._build_request( FinalRequestOptions( method="post", url="/foo", **make_request_options(extra_headers={"X-Foo": "Foo"}), ), ) assert request.headers.get("X-Foo") == "Foo" # `extra_headers` takes priority over `default_headers` when keys clash request = self.client.with_options(default_headers={"X-Bar": "true"})._build_request( FinalRequestOptions( method="post", url="/foo", **make_request_options( extra_headers={"X-Bar": "false"}, ), ), ) assert request.headers.get("X-Bar") == "false" def test_request_extra_query(self) -> None: request = self.client._build_request( FinalRequestOptions( method="post", url="/foo", **make_request_options( extra_query={"my_query_param": "Foo"}, ), ), ) params = dict(request.url.params) assert params == {"my_query_param": "Foo"} # if both `query` and `extra_query` are given, they are merged request = self.client._build_request( FinalRequestOptions( method="post", url="/foo", **make_request_options( query={"bar": "1"}, extra_query={"foo": "2"}, ), ), ) params = dict(request.url.params) assert params == {"bar": "1", "foo": "2"} # `extra_query` takes priority over `query` when keys clash request = self.client._build_request( FinalRequestOptions( method="post", url="/foo", **make_request_options( query={"foo": "1"}, extra_query={"foo": "2"}, ), ), ) params = dict(request.url.params) assert params == {"foo": "2"} def test_multipart_repeating_array(self, client: Anthropic) -> None: request = client._build_request( FinalRequestOptions.construct( method="post", url="/foo", headers={"Content-Type": "multipart/form-data; boundary=6b7ba517decee4a450543ea6ae821c82"}, json_data={"array": ["foo", "bar"]}, files=[("foo.txt", b"hello world")], ) ) assert request.read().split(b"\r\n") == [ b"--6b7ba517decee4a450543ea6ae821c82", b'Content-Disposition: form-data; name="array[]"', b"", b"foo", b"--6b7ba517decee4a450543ea6ae821c82", b'Content-Disposition: form-data; name="array[]"', b"", b"bar", b"--6b7ba517decee4a450543ea6ae821c82", b'Content-Disposition: form-data; name="foo.txt"; filename="upload"', b"Content-Type: application/octet-stream", b"", b"hello world", b"--6b7ba517decee4a450543ea6ae821c82--", b"", ] @pytest.mark.respx(base_url=base_url) def test_basic_union_response(self, respx_mock: MockRouter) -> None: class Model1(BaseModel): name: str class Model2(BaseModel): foo: str respx_mock.get("/foo").mock(return_value=httpx.Response(200, json={"foo": "bar"})) response = self.client.get("/foo", cast_to=cast(Any, Union[Model1, Model2])) assert isinstance(response, Model2) assert response.foo == "bar" @pytest.mark.respx(base_url=base_url) def test_union_response_different_types(self, respx_mock: MockRouter) -> None: """Union of objects with the same field name using a different type""" class Model1(BaseModel): foo: int class Model2(BaseModel): foo: str respx_mock.get("/foo").mock(return_value=httpx.Response(200, json={"foo": "bar"})) response = self.client.get("/foo", cast_to=cast(Any, Union[Model1, Model2])) assert isinstance(response, Model2) assert response.foo == "bar" respx_mock.get("/foo").mock(return_value=httpx.Response(200, json={"foo": 1})) response = self.client.get("/foo", cast_to=cast(Any, Union[Model1, Model2])) assert isinstance(response, Model1) assert response.foo == 1 @pytest.mark.respx(base_url=base_url) def test_non_application_json_content_type_for_json_data(self, respx_mock: MockRouter) -> None: """ Response that sets Content-Type to something other than application/json but returns json data """ class Model(BaseModel): foo: int respx_mock.get("/foo").mock( return_value=httpx.Response( 200, content=json.dumps({"foo": 2}), headers={"Content-Type": "application/text"}, ) ) response = self.client.get("/foo", cast_to=Model) assert isinstance(response, Model) assert response.foo == 2 def test_base_url_setter(self) -> None: client = Anthropic(base_url="https://example.com/from_init", api_key=api_key, _strict_response_validation=True) assert client.base_url == "https://example.com/from_init/" client.base_url = "https://example.com/from_setter" # type: ignore[assignment] assert client.base_url == "https://example.com/from_setter/" def test_base_url_env(self) -> None: with update_env(ANTHROPIC_BASE_URL="http://localhost:5000/from/env"): client = Anthropic(api_key=api_key, _strict_response_validation=True) assert client.base_url == "http://localhost:5000/from/env/" @pytest.mark.parametrize( "client", [ Anthropic(base_url="http://localhost:5000/custom/path/", api_key=api_key, _strict_response_validation=True), Anthropic( base_url="http://localhost:5000/custom/path/", api_key=api_key, _strict_response_validation=True, http_client=httpx.Client(), ), ], ids=["standard", "custom http client"], ) def test_base_url_trailing_slash(self, client: Anthropic) -> None: request = client._build_request( FinalRequestOptions( method="post", url="/foo", json_data={"foo": "bar"}, ), ) assert request.url == "http://localhost:5000/custom/path/foo" @pytest.mark.parametrize( "client", [ Anthropic(base_url="http://localhost:5000/custom/path/", api_key=api_key, _strict_response_validation=True), Anthropic( base_url="http://localhost:5000/custom/path/", api_key=api_key, _strict_response_validation=True, http_client=httpx.Client(), ), ], ids=["standard", "custom http client"], ) def test_base_url_no_trailing_slash(self, client: Anthropic) -> None: request = client._build_request( FinalRequestOptions( method="post", url="/foo", json_data={"foo": "bar"}, ), ) assert request.url == "http://localhost:5000/custom/path/foo" @pytest.mark.parametrize( "client", [ Anthropic(base_url="http://localhost:5000/custom/path/", api_key=api_key, _strict_response_validation=True), Anthropic( base_url="http://localhost:5000/custom/path/", api_key=api_key, _strict_response_validation=True, http_client=httpx.Client(), ), ], ids=["standard", "custom http client"], ) def test_absolute_request_url(self, client: Anthropic) -> None: request = client._build_request( FinalRequestOptions( method="post", url="https://myapi.com/foo", json_data={"foo": "bar"}, ), ) assert request.url == "https://myapi.com/foo" def test_copied_client_does_not_close_http(self) -> None: client = Anthropic(base_url=base_url, api_key=api_key, _strict_response_validation=True) assert not client.is_closed() copied = client.copy() assert copied is not client del copied assert not client.is_closed() def test_client_context_manager(self) -> None: client = Anthropic(base_url=base_url, api_key=api_key, _strict_response_validation=True) with client as c2: assert c2 is client assert not c2.is_closed() assert not client.is_closed() assert client.is_closed() @pytest.mark.respx(base_url=base_url) def test_client_response_validation_error(self, respx_mock: MockRouter) -> None: class Model(BaseModel): foo: str respx_mock.get("/foo").mock(return_value=httpx.Response(200, json={"foo": {"invalid": True}})) with pytest.raises(APIResponseValidationError) as exc: self.client.get("/foo", cast_to=Model) assert isinstance(exc.value.__cause__, ValidationError) def test_client_max_retries_validation(self) -> None: with pytest.raises(TypeError, match=r"max_retries cannot be None"): Anthropic(base_url=base_url, api_key=api_key, _strict_response_validation=True, max_retries=cast(Any, None)) @pytest.mark.respx(base_url=base_url) def test_default_stream_cls(self, respx_mock: MockRouter) -> None: class Model(BaseModel): name: str respx_mock.post("/foo").mock(return_value=httpx.Response(200, json={"foo": "bar"})) stream = self.client.post("/foo", cast_to=Model, stream=True, stream_cls=Stream[Model]) assert isinstance(stream, Stream) stream.response.close() @pytest.mark.respx(base_url=base_url) def test_received_text_for_expected_json(self, respx_mock: MockRouter) -> None: class Model(BaseModel): name: str respx_mock.get("/foo").mock(return_value=httpx.Response(200, text="my-custom-format")) strict_client = Anthropic(base_url=base_url, api_key=api_key, _strict_response_validation=True) with pytest.raises(APIResponseValidationError): strict_client.get("/foo", cast_to=Model) client = Anthropic(base_url=base_url, api_key=api_key, _strict_response_validation=False) response = client.get("/foo", cast_to=Model) assert isinstance(response, str) # type: ignore[unreachable] @pytest.mark.parametrize( "remaining_retries,retry_after,timeout", [ [3, "20", 20], [3, "0", 0.5], [3, "-10", 0.5], [3, "60", 60], [3, "61", 0.5], [3, "Fri, 29 Sep 2023 16:26:57 GMT", 20], [3, "Fri, 29 Sep 2023 16:26:37 GMT", 0.5], [3, "Fri, 29 Sep 2023 16:26:27 GMT", 0.5], [3, "Fri, 29 Sep 2023 16:27:37 GMT", 60], [3, "Fri, 29 Sep 2023 16:27:38 GMT", 0.5], [3, "99999999999999999999999999999999999", 0.5], [3, "Zun, 29 Sep 2023 16:26:27 GMT", 0.5], [3, "", 0.5], [2, "", 0.5 * 2.0], [1, "", 0.5 * 4.0], [-1100, "", 8], # test large number potentially overflowing ], ) @mock.patch("time.time", mock.MagicMock(return_value=1696004797)) def test_parse_retry_after_header(self, remaining_retries: int, retry_after: str, timeout: float) -> None: client = Anthropic(base_url=base_url, api_key=api_key, _strict_response_validation=True) headers = httpx.Headers({"retry-after": retry_after}) options = FinalRequestOptions(method="get", url="/foo", max_retries=3) calculated = client._calculate_retry_timeout(remaining_retries, options, headers) assert calculated == pytest.approx(timeout, 0.5 * 0.875) # pyright: ignore[reportUnknownMemberType] @mock.patch("anthropic._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @pytest.mark.respx(base_url=base_url) def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter, client: Anthropic) -> None: respx_mock.post("/v1/messages").mock(side_effect=httpx.TimeoutException("Test timeout error")) with pytest.raises(APITimeoutError): client.messages.with_streaming_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", ).__enter__() assert _get_open_connections(self.client) == 0 @mock.patch("anthropic._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @pytest.mark.respx(base_url=base_url) def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter, client: Anthropic) -> None: respx_mock.post("/v1/messages").mock(return_value=httpx.Response(500)) with pytest.raises(APIStatusError): client.messages.with_streaming_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", ).__enter__() assert _get_open_connections(self.client) == 0 @pytest.mark.parametrize("failures_before_success", [0, 2, 4]) @mock.patch("anthropic._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @pytest.mark.respx(base_url=base_url) @pytest.mark.parametrize("failure_mode", ["status", "exception"]) def test_retries_taken( self, client: Anthropic, failures_before_success: int, failure_mode: Literal["status", "exception"], respx_mock: MockRouter, ) -> None: client = client.with_options(max_retries=4) nb_retries = 0 def retry_handler(_request: httpx.Request) -> httpx.Response: nonlocal nb_retries if nb_retries < failures_before_success: nb_retries += 1 if failure_mode == "exception": raise RuntimeError("oops") return httpx.Response(500) return httpx.Response(200) respx_mock.post("/v1/messages").mock(side_effect=retry_handler) response = client.messages.with_raw_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", ) assert response.retries_taken == failures_before_success assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success @pytest.mark.parametrize("failures_before_success", [0, 2, 4]) @mock.patch("anthropic._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @pytest.mark.respx(base_url=base_url) def test_omit_retry_count_header( self, client: Anthropic, failures_before_success: int, respx_mock: MockRouter ) -> None: client = client.with_options(max_retries=4) nb_retries = 0 def retry_handler(_request: httpx.Request) -> httpx.Response: nonlocal nb_retries if nb_retries < failures_before_success: nb_retries += 1 return httpx.Response(500) return httpx.Response(200) respx_mock.post("/v1/messages").mock(side_effect=retry_handler) response = client.messages.with_raw_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", extra_headers={"x-stainless-retry-count": Omit()}, ) assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0 @pytest.mark.parametrize("failures_before_success", [0, 2, 4]) @mock.patch("anthropic._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @pytest.mark.respx(base_url=base_url) def test_overwrite_retry_count_header( self, client: Anthropic, failures_before_success: int, respx_mock: MockRouter ) -> None: client = client.with_options(max_retries=4) nb_retries = 0 def retry_handler(_request: httpx.Request) -> httpx.Response: nonlocal nb_retries if nb_retries < failures_before_success: nb_retries += 1 return httpx.Response(500) return httpx.Response(200) respx_mock.post("/v1/messages").mock(side_effect=retry_handler) response = client.messages.with_raw_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", extra_headers={"x-stainless-retry-count": "42"}, ) assert response.http_request.headers.get("x-stainless-retry-count") == "42" @pytest.mark.parametrize("failures_before_success", [0, 2, 4]) @mock.patch("anthropic._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @pytest.mark.respx(base_url=base_url) def test_retries_taken_new_response_class( self, client: Anthropic, failures_before_success: int, respx_mock: MockRouter ) -> None: client = client.with_options(max_retries=4) nb_retries = 0 def retry_handler(_request: httpx.Request) -> httpx.Response: nonlocal nb_retries if nb_retries < failures_before_success: nb_retries += 1 return httpx.Response(500) return httpx.Response(200) respx_mock.post("/v1/messages").mock(side_effect=retry_handler) with client.messages.with_streaming_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", ) as response: assert response.retries_taken == failures_before_success assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success 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") client = DefaultHttpxClient() mounts = tuple(client._mounts.items()) assert len(mounts) == 1 assert mounts[0][0].pattern == "https://" @pytest.mark.filterwarnings("ignore:.*deprecated.*:DeprecationWarning") def test_default_client_creation(self) -> None: # Ensure that the client can be initialized without any exceptions DefaultHttpxClient( verify=True, cert=None, trust_env=True, http1=True, http2=False, limits=httpx.Limits(max_connections=100, max_keepalive_connections=20), ) @pytest.mark.respx(base_url=base_url) def test_follow_redirects(self, respx_mock: MockRouter) -> None: # Test that the default follow_redirects=True allows following redirects respx_mock.post("/redirect").mock( return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"}) ) respx_mock.get("/redirected").mock(return_value=httpx.Response(200, json={"status": "ok"})) response = self.client.post("/redirect", body={"key": "value"}, cast_to=httpx.Response) assert response.status_code == 200 assert response.json() == {"status": "ok"} @pytest.mark.respx(base_url=base_url) def test_follow_redirects_disabled(self, respx_mock: MockRouter) -> None: # Test that follow_redirects=False prevents following redirects respx_mock.post("/redirect").mock( return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"}) ) with pytest.raises(APIStatusError) as exc_info: self.client.post( "/redirect", body={"key": "value"}, options={"follow_redirects": False}, cast_to=httpx.Response ) assert exc_info.value.response.status_code == 302 assert exc_info.value.response.headers["Location"] == f"{base_url}/redirected" class TestAsyncAnthropic: client = AsyncAnthropic(base_url=base_url, api_key=api_key, _strict_response_validation=True) @pytest.mark.respx(base_url=base_url) @pytest.mark.asyncio async def test_raw_response(self, respx_mock: MockRouter) -> None: respx_mock.post("/foo").mock(return_value=httpx.Response(200, json={"foo": "bar"})) response = await self.client.post("/foo", cast_to=httpx.Response) assert response.status_code == 200 assert isinstance(response, httpx.Response) assert response.json() == {"foo": "bar"} @pytest.mark.respx(base_url=base_url) @pytest.mark.asyncio async def test_raw_response_for_binary(self, respx_mock: MockRouter) -> None: respx_mock.post("/foo").mock( return_value=httpx.Response(200, headers={"Content-Type": "application/binary"}, content='{"foo": "bar"}') ) response = await self.client.post("/foo", cast_to=httpx.Response) assert response.status_code == 200 assert isinstance(response, httpx.Response) assert response.json() == {"foo": "bar"} def test_copy(self) -> None: copied = self.client.copy() assert id(copied) != id(self.client) copied = self.client.copy(api_key="another my-anthropic-api-key") assert copied.api_key == "another my-anthropic-api-key" assert self.client.api_key == "my-anthropic-api-key" def test_copy_default_options(self) -> None: # options that have a default are overridden correctly copied = self.client.copy(max_retries=7) assert copied.max_retries == 7 assert self.client.max_retries == 2 copied2 = copied.copy(max_retries=6) assert copied2.max_retries == 6 assert copied.max_retries == 7 # timeout assert isinstance(self.client.timeout, httpx.Timeout) copied = self.client.copy(timeout=None) assert copied.timeout is None assert isinstance(self.client.timeout, httpx.Timeout) def test_copy_default_headers(self) -> None: client = AsyncAnthropic( base_url=base_url, api_key=api_key, _strict_response_validation=True, default_headers={"X-Foo": "bar"} ) assert client.default_headers["X-Foo"] == "bar" # does not override the already given value when not specified copied = client.copy() assert copied.default_headers["X-Foo"] == "bar" # merges already given headers copied = client.copy(default_headers={"X-Bar": "stainless"}) assert copied.default_headers["X-Foo"] == "bar" assert copied.default_headers["X-Bar"] == "stainless" # uses new values for any already given headers copied = client.copy(default_headers={"X-Foo": "stainless"}) assert copied.default_headers["X-Foo"] == "stainless" # set_default_headers # completely overrides already set values copied = client.copy(set_default_headers={}) assert copied.default_headers.get("X-Foo") is None copied = client.copy(set_default_headers={"X-Bar": "Robert"}) assert copied.default_headers["X-Bar"] == "Robert" with pytest.raises( ValueError, match="`default_headers` and `set_default_headers` arguments are mutually exclusive", ): client.copy(set_default_headers={}, default_headers={"X-Foo": "Bar"}) def test_copy_default_query(self) -> None: client = AsyncAnthropic( base_url=base_url, api_key=api_key, _strict_response_validation=True, default_query={"foo": "bar"} ) assert _get_params(client)["foo"] == "bar" # does not override the already given value when not specified copied = client.copy() assert _get_params(copied)["foo"] == "bar" # merges already given params copied = client.copy(default_query={"bar": "stainless"}) params = _get_params(copied) assert params["foo"] == "bar" assert params["bar"] == "stainless" # uses new values for any already given headers copied = client.copy(default_query={"foo": "stainless"}) assert _get_params(copied)["foo"] == "stainless" # set_default_query # completely overrides already set values copied = client.copy(set_default_query={}) assert _get_params(copied) == {} copied = client.copy(set_default_query={"bar": "Robert"}) assert _get_params(copied)["bar"] == "Robert" with pytest.raises( ValueError, # TODO: update match="`default_query` and `set_default_query` arguments are mutually exclusive", ): client.copy(set_default_query={}, default_query={"foo": "Bar"}) def test_copy_signature(self) -> None: # ensure the same parameters that can be passed to the client are defined in the `.copy()` method init_signature = inspect.signature( # mypy doesn't like that we access the `__init__` property. self.client.__init__, # type: ignore[misc] ) copy_signature = inspect.signature(self.client.copy) exclude_params = {"transport", "proxies", "_strict_response_validation"} for name in init_signature.parameters.keys(): if name in exclude_params: continue copy_param = copy_signature.parameters.get(name) assert copy_param is not None, f"copy() signature is missing the {name} param" @pytest.mark.skipif(sys.version_info >= (3, 10), reason="fails because of a memory leak that started from 3.12") def test_copy_build_request(self) -> None: options = FinalRequestOptions(method="get", url="/foo") def build_request(options: FinalRequestOptions) -> None: client = self.client.copy() client._build_request(options) # ensure that the machinery is warmed up before tracing starts. build_request(options) gc.collect() tracemalloc.start(1000) snapshot_before = tracemalloc.take_snapshot() ITERATIONS = 10 for _ in range(ITERATIONS): build_request(options) gc.collect() snapshot_after = tracemalloc.take_snapshot() tracemalloc.stop() def add_leak(leaks: list[tracemalloc.StatisticDiff], diff: tracemalloc.StatisticDiff) -> None: if diff.count == 0: # Avoid false positives by considering only leaks (i.e. allocations that persist). return if diff.count % ITERATIONS != 0: # Avoid false positives by considering only leaks that appear per iteration. return for frame in diff.traceback: if any( frame.filename.endswith(fragment) for fragment in [ # to_raw_response_wrapper leaks through the @functools.wraps() decorator. # # removing the decorator fixes the leak for reasons we don't understand. "anthropic/_legacy_response.py", "anthropic/_response.py", # pydantic.BaseModel.model_dump || pydantic.BaseModel.dict leak memory for some reason. "anthropic/_compat.py", # Standard library leaks we don't care about. "/logging/__init__.py", ] ): return leaks.append(diff) leaks: list[tracemalloc.StatisticDiff] = [] for diff in snapshot_after.compare_to(snapshot_before, "traceback"): add_leak(leaks, diff) if leaks: for leak in leaks: print("MEMORY LEAK:", leak) for frame in leak.traceback: print(frame) raise AssertionError() async def test_request_timeout(self) -> None: request = self.client._build_request(FinalRequestOptions(method="get", url="/foo")) timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore assert timeout == DEFAULT_TIMEOUT request = self.client._build_request( FinalRequestOptions(method="get", url="/foo", timeout=httpx.Timeout(100.0)) ) timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore assert timeout == httpx.Timeout(100.0) async def test_client_timeout_option(self) -> None: client = AsyncAnthropic( base_url=base_url, api_key=api_key, _strict_response_validation=True, timeout=httpx.Timeout(0) ) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore assert timeout == httpx.Timeout(0) async def test_http_client_timeout_option(self) -> None: # custom timeout given to the httpx client should be used async with httpx.AsyncClient(timeout=None) as http_client: client = AsyncAnthropic( base_url=base_url, api_key=api_key, _strict_response_validation=True, http_client=http_client ) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore assert timeout == httpx.Timeout(None) # no timeout given to the httpx client should not use the httpx default async with httpx.AsyncClient() as http_client: client = AsyncAnthropic( base_url=base_url, api_key=api_key, _strict_response_validation=True, http_client=http_client ) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore assert timeout == DEFAULT_TIMEOUT # explicitly passing the default timeout currently results in it being ignored async with httpx.AsyncClient(timeout=HTTPX_DEFAULT_TIMEOUT) as http_client: client = AsyncAnthropic( base_url=base_url, api_key=api_key, _strict_response_validation=True, http_client=http_client ) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore assert timeout == DEFAULT_TIMEOUT # our default def test_invalid_http_client(self) -> None: with pytest.raises(TypeError, match="Invalid `http_client` arg"): with httpx.Client() as http_client: AsyncAnthropic( base_url=base_url, api_key=api_key, _strict_response_validation=True, http_client=cast(Any, http_client), ) def test_default_headers_option(self) -> None: client = AsyncAnthropic( base_url=base_url, api_key=api_key, _strict_response_validation=True, default_headers={"X-Foo": "bar"} ) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) assert request.headers.get("x-foo") == "bar" assert request.headers.get("x-stainless-lang") == "python" client2 = AsyncAnthropic( base_url=base_url, api_key=api_key, _strict_response_validation=True, default_headers={ "X-Foo": "stainless", "X-Stainless-Lang": "my-overriding-header", }, ) request = client2._build_request(FinalRequestOptions(method="get", url="/foo")) assert request.headers.get("x-foo") == "stainless" assert request.headers.get("x-stainless-lang") == "my-overriding-header" def test_validate_headers(self) -> None: client = AsyncAnthropic(base_url=base_url, api_key=api_key, _strict_response_validation=True) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) assert request.headers.get("X-Api-Key") == api_key with update_env(**{"ANTHROPIC_API_KEY": Omit()}): client2 = AsyncAnthropic(base_url=base_url, api_key=None, _strict_response_validation=True) with pytest.raises( TypeError, match="Could not resolve authentication method. Expected either api_key or auth_token to be set. Or for one of the `X-Api-Key` or `Authorization` headers to be explicitly omitted", ): client2._build_request(FinalRequestOptions(method="get", url="/foo")) request2 = client2._build_request(FinalRequestOptions(method="get", url="/foo", headers={"X-Api-Key": Omit()})) assert request2.headers.get("X-Api-Key") is None def test_default_query_option(self) -> None: client = AsyncAnthropic( base_url=base_url, api_key=api_key, _strict_response_validation=True, default_query={"query_param": "bar"} ) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) url = httpx.URL(request.url) assert dict(url.params) == {"query_param": "bar"} request = client._build_request( FinalRequestOptions( method="get", url="/foo", params={"foo": "baz", "query_param": "overridden"}, ) ) url = httpx.URL(request.url) assert dict(url.params) == {"foo": "baz", "query_param": "overridden"} def test_request_extra_json(self) -> None: request = self.client._build_request( FinalRequestOptions( method="post", url="/foo", json_data={"foo": "bar"}, extra_json={"baz": False}, ), ) data = json.loads(request.content.decode("utf-8")) assert data == {"foo": "bar", "baz": False} request = self.client._build_request( FinalRequestOptions( method="post", url="/foo", extra_json={"baz": False}, ), ) data = json.loads(request.content.decode("utf-8")) assert data == {"baz": False} # `extra_json` takes priority over `json_data` when keys clash request = self.client._build_request( FinalRequestOptions( method="post", url="/foo", json_data={"foo": "bar", "baz": True}, extra_json={"baz": None}, ), ) data = json.loads(request.content.decode("utf-8")) assert data == {"foo": "bar", "baz": None} def test_request_extra_headers(self) -> None: request = self.client._build_request( FinalRequestOptions( method="post", url="/foo", **make_request_options(extra_headers={"X-Foo": "Foo"}), ), ) assert request.headers.get("X-Foo") == "Foo" # `extra_headers` takes priority over `default_headers` when keys clash request = self.client.with_options(default_headers={"X-Bar": "true"})._build_request( FinalRequestOptions( method="post", url="/foo", **make_request_options( extra_headers={"X-Bar": "false"}, ), ), ) assert request.headers.get("X-Bar") == "false" def test_request_extra_query(self) -> None: request = self.client._build_request( FinalRequestOptions( method="post", url="/foo", **make_request_options( extra_query={"my_query_param": "Foo"}, ), ), ) params = dict(request.url.params) assert params == {"my_query_param": "Foo"} # if both `query` and `extra_query` are given, they are merged request = self.client._build_request( FinalRequestOptions( method="post", url="/foo", **make_request_options( query={"bar": "1"}, extra_query={"foo": "2"}, ), ), ) params = dict(request.url.params) assert params == {"bar": "1", "foo": "2"} # `extra_query` takes priority over `query` when keys clash request = self.client._build_request( FinalRequestOptions( method="post", url="/foo", **make_request_options( query={"foo": "1"}, extra_query={"foo": "2"}, ), ), ) params = dict(request.url.params) assert params == {"foo": "2"} def test_multipart_repeating_array(self, async_client: AsyncAnthropic) -> None: request = async_client._build_request( FinalRequestOptions.construct( method="post", url="/foo", headers={"Content-Type": "multipart/form-data; boundary=6b7ba517decee4a450543ea6ae821c82"}, json_data={"array": ["foo", "bar"]}, files=[("foo.txt", b"hello world")], ) ) assert request.read().split(b"\r\n") == [ b"--6b7ba517decee4a450543ea6ae821c82", b'Content-Disposition: form-data; name="array[]"', b"", b"foo", b"--6b7ba517decee4a450543ea6ae821c82", b'Content-Disposition: form-data; name="array[]"', b"", b"bar", b"--6b7ba517decee4a450543ea6ae821c82", b'Content-Disposition: form-data; name="foo.txt"; filename="upload"', b"Content-Type: application/octet-stream", b"", b"hello world", b"--6b7ba517decee4a450543ea6ae821c82--", b"", ] @pytest.mark.respx(base_url=base_url) async def test_basic_union_response(self, respx_mock: MockRouter) -> None: class Model1(BaseModel): name: str class Model2(BaseModel): foo: str respx_mock.get("/foo").mock(return_value=httpx.Response(200, json={"foo": "bar"})) response = await self.client.get("/foo", cast_to=cast(Any, Union[Model1, Model2])) assert isinstance(response, Model2) assert response.foo == "bar" @pytest.mark.respx(base_url=base_url) async def test_union_response_different_types(self, respx_mock: MockRouter) -> None: """Union of objects with the same field name using a different type""" class Model1(BaseModel): foo: int class Model2(BaseModel): foo: str respx_mock.get("/foo").mock(return_value=httpx.Response(200, json={"foo": "bar"})) response = await self.client.get("/foo", cast_to=cast(Any, Union[Model1, Model2])) assert isinstance(response, Model2) assert response.foo == "bar" respx_mock.get("/foo").mock(return_value=httpx.Response(200, json={"foo": 1})) response = await self.client.get("/foo", cast_to=cast(Any, Union[Model1, Model2])) assert isinstance(response, Model1) assert response.foo == 1 @pytest.mark.respx(base_url=base_url) async def test_non_application_json_content_type_for_json_data(self, respx_mock: MockRouter) -> None: """ Response that sets Content-Type to something other than application/json but returns json data """ class Model(BaseModel): foo: int respx_mock.get("/foo").mock( return_value=httpx.Response( 200, content=json.dumps({"foo": 2}), headers={"Content-Type": "application/text"}, ) ) response = await self.client.get("/foo", cast_to=Model) assert isinstance(response, Model) assert response.foo == 2 def test_base_url_setter(self) -> None: client = AsyncAnthropic( base_url="https://example.com/from_init", api_key=api_key, _strict_response_validation=True ) assert client.base_url == "https://example.com/from_init/" client.base_url = "https://example.com/from_setter" # type: ignore[assignment] assert client.base_url == "https://example.com/from_setter/" def test_base_url_env(self) -> None: with update_env(ANTHROPIC_BASE_URL="http://localhost:5000/from/env"): client = AsyncAnthropic(api_key=api_key, _strict_response_validation=True) assert client.base_url == "http://localhost:5000/from/env/" @pytest.mark.parametrize( "client", [ AsyncAnthropic( base_url="http://localhost:5000/custom/path/", api_key=api_key, _strict_response_validation=True ), AsyncAnthropic( base_url="http://localhost:5000/custom/path/", api_key=api_key, _strict_response_validation=True, http_client=httpx.AsyncClient(), ), ], ids=["standard", "custom http client"], ) def test_base_url_trailing_slash(self, client: AsyncAnthropic) -> None: request = client._build_request( FinalRequestOptions( method="post", url="/foo", json_data={"foo": "bar"}, ), ) assert request.url == "http://localhost:5000/custom/path/foo" @pytest.mark.parametrize( "client", [ AsyncAnthropic( base_url="http://localhost:5000/custom/path/", api_key=api_key, _strict_response_validation=True ), AsyncAnthropic( base_url="http://localhost:5000/custom/path/", api_key=api_key, _strict_response_validation=True, http_client=httpx.AsyncClient(), ), ], ids=["standard", "custom http client"], ) def test_base_url_no_trailing_slash(self, client: AsyncAnthropic) -> None: request = client._build_request( FinalRequestOptions( method="post", url="/foo", json_data={"foo": "bar"}, ), ) assert request.url == "http://localhost:5000/custom/path/foo" @pytest.mark.parametrize( "client", [ AsyncAnthropic( base_url="http://localhost:5000/custom/path/", api_key=api_key, _strict_response_validation=True ), AsyncAnthropic( base_url="http://localhost:5000/custom/path/", api_key=api_key, _strict_response_validation=True, http_client=httpx.AsyncClient(), ), ], ids=["standard", "custom http client"], ) def test_absolute_request_url(self, client: AsyncAnthropic) -> None: request = client._build_request( FinalRequestOptions( method="post", url="https://myapi.com/foo", json_data={"foo": "bar"}, ), ) assert request.url == "https://myapi.com/foo" async def test_copied_client_does_not_close_http(self) -> None: client = AsyncAnthropic(base_url=base_url, api_key=api_key, _strict_response_validation=True) assert not client.is_closed() copied = client.copy() assert copied is not client del copied await asyncio.sleep(0.2) assert not client.is_closed() async def test_client_context_manager(self) -> None: client = AsyncAnthropic(base_url=base_url, api_key=api_key, _strict_response_validation=True) async with client as c2: assert c2 is client assert not c2.is_closed() assert not client.is_closed() assert client.is_closed() @pytest.mark.respx(base_url=base_url) @pytest.mark.asyncio async def test_client_response_validation_error(self, respx_mock: MockRouter) -> None: class Model(BaseModel): foo: str respx_mock.get("/foo").mock(return_value=httpx.Response(200, json={"foo": {"invalid": True}})) with pytest.raises(APIResponseValidationError) as exc: await self.client.get("/foo", cast_to=Model) assert isinstance(exc.value.__cause__, ValidationError) async def test_client_max_retries_validation(self) -> None: with pytest.raises(TypeError, match=r"max_retries cannot be None"): AsyncAnthropic( base_url=base_url, api_key=api_key, _strict_response_validation=True, max_retries=cast(Any, None) ) @pytest.mark.respx(base_url=base_url) @pytest.mark.asyncio async def test_default_stream_cls(self, respx_mock: MockRouter) -> None: class Model(BaseModel): name: str respx_mock.post("/foo").mock(return_value=httpx.Response(200, json={"foo": "bar"})) stream = await self.client.post("/foo", cast_to=Model, stream=True, stream_cls=AsyncStream[Model]) assert isinstance(stream, AsyncStream) await stream.response.aclose() @pytest.mark.respx(base_url=base_url) @pytest.mark.asyncio async def test_received_text_for_expected_json(self, respx_mock: MockRouter) -> None: class Model(BaseModel): name: str respx_mock.get("/foo").mock(return_value=httpx.Response(200, text="my-custom-format")) strict_client = AsyncAnthropic(base_url=base_url, api_key=api_key, _strict_response_validation=True) with pytest.raises(APIResponseValidationError): await strict_client.get("/foo", cast_to=Model) client = AsyncAnthropic(base_url=base_url, api_key=api_key, _strict_response_validation=False) response = await client.get("/foo", cast_to=Model) assert isinstance(response, str) # type: ignore[unreachable] @pytest.mark.parametrize( "remaining_retries,retry_after,timeout", [ [3, "20", 20], [3, "0", 0.5], [3, "-10", 0.5], [3, "60", 60], [3, "61", 0.5], [3, "Fri, 29 Sep 2023 16:26:57 GMT", 20], [3, "Fri, 29 Sep 2023 16:26:37 GMT", 0.5], [3, "Fri, 29 Sep 2023 16:26:27 GMT", 0.5], [3, "Fri, 29 Sep 2023 16:27:37 GMT", 60], [3, "Fri, 29 Sep 2023 16:27:38 GMT", 0.5], [3, "99999999999999999999999999999999999", 0.5], [3, "Zun, 29 Sep 2023 16:26:27 GMT", 0.5], [3, "", 0.5], [2, "", 0.5 * 2.0], [1, "", 0.5 * 4.0], [-1100, "", 8], # test large number potentially overflowing ], ) @mock.patch("time.time", mock.MagicMock(return_value=1696004797)) @pytest.mark.asyncio async def test_parse_retry_after_header(self, remaining_retries: int, retry_after: str, timeout: float) -> None: client = AsyncAnthropic(base_url=base_url, api_key=api_key, _strict_response_validation=True) headers = httpx.Headers({"retry-after": retry_after}) options = FinalRequestOptions(method="get", url="/foo", max_retries=3) calculated = client._calculate_retry_timeout(remaining_retries, options, headers) assert calculated == pytest.approx(timeout, 0.5 * 0.875) # pyright: ignore[reportUnknownMemberType] @mock.patch("anthropic._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @pytest.mark.respx(base_url=base_url) async def test_retrying_timeout_errors_doesnt_leak( self, respx_mock: MockRouter, async_client: AsyncAnthropic ) -> None: respx_mock.post("/v1/messages").mock(side_effect=httpx.TimeoutException("Test timeout error")) with pytest.raises(APITimeoutError): await async_client.messages.with_streaming_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", ).__aenter__() assert _get_open_connections(self.client) == 0 @mock.patch("anthropic._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @pytest.mark.respx(base_url=base_url) async def test_retrying_status_errors_doesnt_leak( self, respx_mock: MockRouter, async_client: AsyncAnthropic ) -> None: respx_mock.post("/v1/messages").mock(return_value=httpx.Response(500)) with pytest.raises(APIStatusError): await async_client.messages.with_streaming_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", ).__aenter__() assert _get_open_connections(self.client) == 0 @pytest.mark.parametrize("failures_before_success", [0, 2, 4]) @mock.patch("anthropic._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @pytest.mark.respx(base_url=base_url) @pytest.mark.asyncio @pytest.mark.parametrize("failure_mode", ["status", "exception"]) async def test_retries_taken( self, async_client: AsyncAnthropic, failures_before_success: int, failure_mode: Literal["status", "exception"], respx_mock: MockRouter, ) -> None: client = async_client.with_options(max_retries=4) nb_retries = 0 def retry_handler(_request: httpx.Request) -> httpx.Response: nonlocal nb_retries if nb_retries < failures_before_success: nb_retries += 1 if failure_mode == "exception": raise RuntimeError("oops") return httpx.Response(500) return httpx.Response(200) respx_mock.post("/v1/messages").mock(side_effect=retry_handler) response = await client.messages.with_raw_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", ) assert response.retries_taken == failures_before_success assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success @pytest.mark.parametrize("failures_before_success", [0, 2, 4]) @mock.patch("anthropic._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @pytest.mark.respx(base_url=base_url) @pytest.mark.asyncio async def test_omit_retry_count_header( self, async_client: AsyncAnthropic, failures_before_success: int, respx_mock: MockRouter ) -> None: client = async_client.with_options(max_retries=4) nb_retries = 0 def retry_handler(_request: httpx.Request) -> httpx.Response: nonlocal nb_retries if nb_retries < failures_before_success: nb_retries += 1 return httpx.Response(500) return httpx.Response(200) respx_mock.post("/v1/messages").mock(side_effect=retry_handler) response = await client.messages.with_raw_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", extra_headers={"x-stainless-retry-count": Omit()}, ) assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0 @pytest.mark.parametrize("failures_before_success", [0, 2, 4]) @mock.patch("anthropic._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @pytest.mark.respx(base_url=base_url) @pytest.mark.asyncio async def test_overwrite_retry_count_header( self, async_client: AsyncAnthropic, failures_before_success: int, respx_mock: MockRouter ) -> None: client = async_client.with_options(max_retries=4) nb_retries = 0 def retry_handler(_request: httpx.Request) -> httpx.Response: nonlocal nb_retries if nb_retries < failures_before_success: nb_retries += 1 return httpx.Response(500) return httpx.Response(200) respx_mock.post("/v1/messages").mock(side_effect=retry_handler) response = await client.messages.with_raw_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", extra_headers={"x-stainless-retry-count": "42"}, ) assert response.http_request.headers.get("x-stainless-retry-count") == "42" @pytest.mark.parametrize("failures_before_success", [0, 2, 4]) @mock.patch("anthropic._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @pytest.mark.respx(base_url=base_url) @pytest.mark.asyncio async def test_retries_taken_new_response_class( self, async_client: AsyncAnthropic, failures_before_success: int, respx_mock: MockRouter ) -> None: client = async_client.with_options(max_retries=4) nb_retries = 0 def retry_handler(_request: httpx.Request) -> httpx.Response: nonlocal nb_retries if nb_retries < failures_before_success: nb_retries += 1 return httpx.Response(500) return httpx.Response(200) respx_mock.post("/v1/messages").mock(side_effect=retry_handler) async with client.messages.with_streaming_response.create( max_tokens=1024, messages=[ { "content": "Hello, world", "role": "user", } ], model="claude-sonnet-4-20250514", ) as response: assert response.retries_taken == failures_before_success assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success async def test_get_platform(self) -> None: platform = await asyncify(get_platform)() assert isinstance(platform, (str, OtherPlatform)) 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") client = DefaultAsyncHttpxClient() mounts = tuple(client._mounts.items()) assert len(mounts) == 1 assert mounts[0][0].pattern == "https://" @pytest.mark.filterwarnings("ignore:.*deprecated.*:DeprecationWarning") async def test_default_client_creation(self) -> None: # Ensure that the client can be initialized without any exceptions DefaultAsyncHttpxClient( verify=True, cert=None, trust_env=True, http1=True, http2=False, limits=httpx.Limits(max_connections=100, max_keepalive_connections=20), ) @pytest.mark.respx(base_url=base_url) async def test_follow_redirects(self, respx_mock: MockRouter) -> None: # Test that the default follow_redirects=True allows following redirects respx_mock.post("/redirect").mock( return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"}) ) respx_mock.get("/redirected").mock(return_value=httpx.Response(200, json={"status": "ok"})) response = await self.client.post("/redirect", body={"key": "value"}, cast_to=httpx.Response) assert response.status_code == 200 assert response.json() == {"status": "ok"} @pytest.mark.respx(base_url=base_url) async def test_follow_redirects_disabled(self, respx_mock: MockRouter) -> None: # Test that follow_redirects=False prevents following redirects respx_mock.post("/redirect").mock( return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"}) ) with pytest.raises(APIStatusError) as exc_info: await self.client.post( "/redirect", body={"key": "value"}, options={"follow_redirects": False}, cast_to=httpx.Response ) assert exc_info.value.response.status_code == 302 assert exc_info.value.response.headers["Location"] == f"{base_url}/redirected" anthropic-sdk-python-0.69.0/tests/test_deepcopy.py000066400000000000000000000030331506653454500222720ustar00rootroot00000000000000from anthropic._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 anthropic-sdk-python-0.69.0/tests/test_extract_files.py000066400000000000000000000036311506653454500233220ustar00rootroot00000000000000from __future__ import annotations from typing import Sequence import pytest from anthropic._types import FileTypes from anthropic._utils import extract_files def test_removes_files_from_input() -> None: query = {"foo": "bar"} assert extract_files(query, paths=[]) == [] assert query == {"foo": "bar"} query2 = {"foo": b"Bar", "hello": "world"} assert extract_files(query2, paths=[["foo"]]) == [("foo", b"Bar")] assert query2 == {"hello": "world"} query3 = {"foo": {"foo": {"bar": b"Bar"}}, "hello": "world"} assert extract_files(query3, paths=[["foo", "foo", "bar"]]) == [("foo[foo][bar]", b"Bar")] assert query3 == {"foo": {"foo": {}}, "hello": "world"} query4 = {"foo": {"bar": b"Bar", "baz": "foo"}, "hello": "world"} assert extract_files(query4, paths=[["foo", "bar"]]) == [("foo[bar]", b"Bar")] assert query4 == {"hello": "world", "foo": {"baz": "foo"}} def test_multiple_files() -> None: query = {"documents": [{"file": b"My first file"}, {"file": b"My second file"}]} assert extract_files(query, paths=[["documents", "", "file"]]) == [ ("documents[][file]", b"My first file"), ("documents[][file]", b"My second file"), ] assert query == {"documents": [{}, {}]} @pytest.mark.parametrize( "query,paths,expected", [ [ {"foo": {"bar": "baz"}}, [["foo", "", "bar"]], [], ], [ {"foo": ["bar", "baz"]}, [["foo", "bar"]], [], ], [ {"foo": {"bar": "baz"}}, [["foo", "foo"]], [], ], ], ids=["dict expecting array", "array expecting dict", "unknown keys"], ) def test_ignores_incorrect_paths( query: dict[str, object], paths: Sequence[Sequence[str]], expected: list[tuple[str, FileTypes]], ) -> None: assert extract_files(query, paths=paths) == expected anthropic-sdk-python-0.69.0/tests/test_files.py000066400000000000000000000030531506653454500215660ustar00rootroot00000000000000from pathlib import Path import anyio import pytest from dirty_equals import IsDict, IsList, IsBytes, IsTuple from anthropic._files import to_httpx_files, async_to_httpx_files readme_path = Path(__file__).parent.parent.joinpath("README.md") def test_pathlib_includes_file_name() -> None: result = to_httpx_files({"file": readme_path}) print(result) assert result == IsDict({"file": IsTuple("README.md", IsBytes())}) def test_tuple_input() -> None: result = to_httpx_files([("file", readme_path)]) print(result) assert result == IsList(IsTuple("file", IsTuple("README.md", IsBytes()))) @pytest.mark.asyncio async def test_async_pathlib_includes_file_name() -> None: result = await async_to_httpx_files({"file": readme_path}) print(result) assert result == IsDict({"file": IsTuple("README.md", IsBytes())}) @pytest.mark.asyncio async def test_async_supports_anyio_path() -> None: result = await async_to_httpx_files({"file": anyio.Path(readme_path)}) print(result) assert result == IsDict({"file": IsTuple("README.md", IsBytes())}) @pytest.mark.asyncio async def test_async_tuple_input() -> None: result = await async_to_httpx_files([("file", readme_path)]) print(result) assert result == IsList(IsTuple("file", IsTuple("README.md", IsBytes()))) def test_string_not_allowed() -> None: with pytest.raises(TypeError, match="Expected file types input to be a FileContent type or to be a tuple"): to_httpx_files( { "file": "foo", # type: ignore } ) anthropic-sdk-python-0.69.0/tests/test_legacy_response.py000066400000000000000000000102201506653454500236400ustar00rootroot00000000000000import json from typing import Any, Union, cast from typing_extensions import Annotated import httpx import pytest import pydantic from anthropic import Anthropic, BaseModel from anthropic._streaming import Stream from anthropic._base_client import FinalRequestOptions from anthropic._legacy_response import LegacyAPIResponse class PydanticModel(pydantic.BaseModel): ... def test_response_parse_mismatched_basemodel(client: Anthropic) -> None: response = LegacyAPIResponse( raw=httpx.Response(200, content=b"foo"), client=client, stream=False, stream_cls=None, cast_to=str, options=FinalRequestOptions.construct(method="get", url="/foo"), ) with pytest.raises( TypeError, match="Pydantic models must subclass our base model type, e.g. `from anthropic import BaseModel`", ): response.parse(to=PydanticModel) @pytest.mark.parametrize( "content, expected", [ ("false", False), ("true", True), ("False", False), ("True", True), ("TrUe", True), ("FalSe", False), ], ) def test_response_parse_bool(client: Anthropic, content: str, expected: bool) -> None: response = LegacyAPIResponse( raw=httpx.Response(200, content=content), client=client, stream=False, stream_cls=None, cast_to=str, options=FinalRequestOptions.construct(method="get", url="/foo"), ) result = response.parse(to=bool) assert result is expected def test_response_parse_custom_stream(client: Anthropic) -> None: response = LegacyAPIResponse( raw=httpx.Response(200, content=b"foo"), client=client, stream=True, stream_cls=None, cast_to=str, options=FinalRequestOptions.construct(method="get", url="/foo"), ) stream = response.parse(to=Stream[int]) assert stream._cast_to == int class CustomModel(BaseModel): foo: str bar: int def test_response_parse_custom_model(client: Anthropic) -> None: response = LegacyAPIResponse( raw=httpx.Response(200, content=json.dumps({"foo": "hello!", "bar": 2})), client=client, stream=False, stream_cls=None, cast_to=str, options=FinalRequestOptions.construct(method="get", url="/foo"), ) obj = response.parse(to=CustomModel) assert obj.foo == "hello!" assert obj.bar == 2 def test_response_basemodel_request_id(client: Anthropic) -> None: response = LegacyAPIResponse( raw=httpx.Response( 200, headers={"request-id": "my-req-id"}, content=json.dumps({"foo": "hello!", "bar": 2}), ), client=client, stream=False, stream_cls=None, cast_to=str, options=FinalRequestOptions.construct(method="get", url="/foo"), ) obj = response.parse(to=CustomModel) assert obj._request_id == "my-req-id" assert obj.foo == "hello!" assert obj.bar == 2 assert obj.to_dict() == {"foo": "hello!", "bar": 2} def test_response_parse_annotated_type(client: Anthropic) -> None: response = LegacyAPIResponse( raw=httpx.Response(200, content=json.dumps({"foo": "hello!", "bar": 2})), client=client, stream=False, stream_cls=None, cast_to=str, options=FinalRequestOptions.construct(method="get", url="/foo"), ) obj = response.parse( to=cast("type[CustomModel]", Annotated[CustomModel, "random metadata"]), ) assert obj.foo == "hello!" assert obj.bar == 2 class OtherModel(pydantic.BaseModel): a: str @pytest.mark.parametrize("client", [False], indirect=True) # loose validation def test_response_parse_expect_model_union_non_json_content(client: Anthropic) -> None: response = LegacyAPIResponse( raw=httpx.Response(200, content=b"foo", headers={"Content-Type": "application/text"}), client=client, stream=False, stream_cls=None, cast_to=str, options=FinalRequestOptions.construct(method="get", url="/foo"), ) obj = response.parse(to=cast(Any, Union[CustomModel, OtherModel])) assert isinstance(obj, str) assert obj == "foo" anthropic-sdk-python-0.69.0/tests/test_models.py000066400000000000000000000650571506653454500217630ustar00rootroot00000000000000import json from typing import TYPE_CHECKING, Any, Dict, List, Union, Optional, cast from datetime import datetime, timezone from typing_extensions import Literal, Annotated, TypeAliasType import pytest import pydantic from pydantic import Field from anthropic._utils import PropertyInfo from anthropic._compat import PYDANTIC_V1, parse_obj, model_dump, model_json from anthropic._models import BaseModel, construct_type class BasicModel(BaseModel): foo: str @pytest.mark.parametrize("value", ["hello", 1], ids=["correct type", "mismatched"]) def test_basic(value: object) -> None: m = BasicModel.construct(foo=value) assert m.foo == value def test_directly_nested_model() -> None: class NestedModel(BaseModel): nested: BasicModel m = NestedModel.construct(nested={"foo": "Foo!"}) assert m.nested.foo == "Foo!" # mismatched types m = NestedModel.construct(nested="hello!") assert cast(Any, m.nested) == "hello!" def test_optional_nested_model() -> None: class NestedModel(BaseModel): nested: Optional[BasicModel] m1 = NestedModel.construct(nested=None) assert m1.nested is None m2 = NestedModel.construct(nested={"foo": "bar"}) assert m2.nested is not None assert m2.nested.foo == "bar" # mismatched types m3 = NestedModel.construct(nested={"foo"}) assert isinstance(cast(Any, m3.nested), set) assert cast(Any, m3.nested) == {"foo"} def test_list_nested_model() -> None: class NestedModel(BaseModel): nested: List[BasicModel] m = NestedModel.construct(nested=[{"foo": "bar"}, {"foo": "2"}]) assert m.nested is not None assert isinstance(m.nested, list) assert len(m.nested) == 2 assert m.nested[0].foo == "bar" assert m.nested[1].foo == "2" # mismatched types m = NestedModel.construct(nested=True) assert cast(Any, m.nested) is True m = NestedModel.construct(nested=[False]) assert cast(Any, m.nested) == [False] def test_optional_list_nested_model() -> None: class NestedModel(BaseModel): nested: Optional[List[BasicModel]] m1 = NestedModel.construct(nested=[{"foo": "bar"}, {"foo": "2"}]) assert m1.nested is not None assert isinstance(m1.nested, list) assert len(m1.nested) == 2 assert m1.nested[0].foo == "bar" assert m1.nested[1].foo == "2" m2 = NestedModel.construct(nested=None) assert m2.nested is None # mismatched types m3 = NestedModel.construct(nested={1}) assert cast(Any, m3.nested) == {1} m4 = NestedModel.construct(nested=[False]) assert cast(Any, m4.nested) == [False] def test_list_optional_items_nested_model() -> None: class NestedModel(BaseModel): nested: List[Optional[BasicModel]] m = NestedModel.construct(nested=[None, {"foo": "bar"}]) assert m.nested is not None assert isinstance(m.nested, list) assert len(m.nested) == 2 assert m.nested[0] is None assert m.nested[1] is not None assert m.nested[1].foo == "bar" # mismatched types m3 = NestedModel.construct(nested="foo") assert cast(Any, m3.nested) == "foo" m4 = NestedModel.construct(nested=[False]) assert cast(Any, m4.nested) == [False] def test_list_mismatched_type() -> None: class NestedModel(BaseModel): nested: List[str] m = NestedModel.construct(nested=False) assert cast(Any, m.nested) is False def test_raw_dictionary() -> None: class NestedModel(BaseModel): nested: Dict[str, str] m = NestedModel.construct(nested={"hello": "world"}) assert m.nested == {"hello": "world"} # mismatched types m = NestedModel.construct(nested=False) assert cast(Any, m.nested) is False def test_nested_dictionary_model() -> None: class NestedModel(BaseModel): nested: Dict[str, BasicModel] m = NestedModel.construct(nested={"hello": {"foo": "bar"}}) assert isinstance(m.nested, dict) assert m.nested["hello"].foo == "bar" # mismatched types m = NestedModel.construct(nested={"hello": False}) assert cast(Any, m.nested["hello"]) is False def test_unknown_fields() -> None: m1 = BasicModel.construct(foo="foo", unknown=1) assert m1.foo == "foo" assert cast(Any, m1).unknown == 1 m2 = BasicModel.construct(foo="foo", unknown={"foo_bar": True}) assert m2.foo == "foo" assert cast(Any, m2).unknown == {"foo_bar": True} assert model_dump(m2) == {"foo": "foo", "unknown": {"foo_bar": True}} def test_strict_validation_unknown_fields() -> None: class Model(BaseModel): foo: str model = parse_obj(Model, dict(foo="hello!", user="Robert")) assert model.foo == "hello!" assert cast(Any, model).user == "Robert" assert model_dump(model) == {"foo": "hello!", "user": "Robert"} def test_aliases() -> None: class Model(BaseModel): my_field: int = Field(alias="myField") m = Model.construct(myField=1) assert m.my_field == 1 # mismatched types m = Model.construct(myField={"hello": False}) assert cast(Any, m.my_field) == {"hello": False} def test_repr() -> None: model = BasicModel(foo="bar") assert str(model) == "BasicModel(foo='bar')" assert repr(model) == "BasicModel(foo='bar')" def test_repr_nested_model() -> None: class Child(BaseModel): name: str age: int class Parent(BaseModel): name: str child: Child model = Parent(name="Robert", child=Child(name="Foo", age=5)) assert str(model) == "Parent(name='Robert', child=Child(name='Foo', age=5))" assert repr(model) == "Parent(name='Robert', child=Child(name='Foo', age=5))" def test_optional_list() -> None: class Submodel(BaseModel): name: str class Model(BaseModel): items: Optional[List[Submodel]] m = Model.construct(items=None) assert m.items is None m = Model.construct(items=[]) assert m.items == [] m = Model.construct(items=[{"name": "Robert"}]) assert m.items is not None assert len(m.items) == 1 assert m.items[0].name == "Robert" def test_nested_union_of_models() -> None: class Submodel1(BaseModel): bar: bool class Submodel2(BaseModel): thing: str class Model(BaseModel): foo: Union[Submodel1, Submodel2] m = Model.construct(foo={"thing": "hello"}) assert isinstance(m.foo, Submodel2) assert m.foo.thing == "hello" def test_nested_union_of_mixed_types() -> None: class Submodel1(BaseModel): bar: bool class Model(BaseModel): foo: Union[Submodel1, Literal[True], Literal["CARD_HOLDER"]] m = Model.construct(foo=True) assert m.foo is True m = Model.construct(foo="CARD_HOLDER") assert m.foo == "CARD_HOLDER" m = Model.construct(foo={"bar": False}) assert isinstance(m.foo, Submodel1) assert m.foo.bar is False def test_nested_union_multiple_variants() -> None: class Submodel1(BaseModel): bar: bool class Submodel2(BaseModel): thing: str class Submodel3(BaseModel): foo: int class Model(BaseModel): foo: Union[Submodel1, Submodel2, None, Submodel3] m = Model.construct(foo={"thing": "hello"}) assert isinstance(m.foo, Submodel2) assert m.foo.thing == "hello" m = Model.construct(foo=None) assert m.foo is None m = Model.construct() assert m.foo is None m = Model.construct(foo={"foo": "1"}) assert isinstance(m.foo, Submodel3) assert m.foo.foo == 1 def test_nested_union_invalid_data() -> None: class Submodel1(BaseModel): level: int class Submodel2(BaseModel): name: str class Model(BaseModel): foo: Union[Submodel1, Submodel2] m = Model.construct(foo=True) assert cast(bool, m.foo) is True m = Model.construct(foo={"name": 3}) if PYDANTIC_V1: assert isinstance(m.foo, Submodel2) assert m.foo.name == "3" else: assert isinstance(m.foo, Submodel1) assert m.foo.name == 3 # type: ignore def test_list_of_unions() -> None: class Submodel1(BaseModel): level: int class Submodel2(BaseModel): name: str class Model(BaseModel): items: List[Union[Submodel1, Submodel2]] m = Model.construct(items=[{"level": 1}, {"name": "Robert"}]) assert len(m.items) == 2 assert isinstance(m.items[0], Submodel1) assert m.items[0].level == 1 assert isinstance(m.items[1], Submodel2) assert m.items[1].name == "Robert" m = Model.construct(items=[{"level": -1}, 156]) assert len(m.items) == 2 assert isinstance(m.items[0], Submodel1) assert m.items[0].level == -1 assert cast(Any, m.items[1]) == 156 def test_union_of_lists() -> None: class SubModel1(BaseModel): level: int class SubModel2(BaseModel): name: str class Model(BaseModel): items: Union[List[SubModel1], List[SubModel2]] # with one valid entry m = Model.construct(items=[{"name": "Robert"}]) assert len(m.items) == 1 assert isinstance(m.items[0], SubModel2) assert m.items[0].name == "Robert" # with two entries pointing to different types m = Model.construct(items=[{"level": 1}, {"name": "Robert"}]) assert len(m.items) == 2 assert isinstance(m.items[0], SubModel1) assert m.items[0].level == 1 assert isinstance(m.items[1], SubModel1) assert cast(Any, m.items[1]).name == "Robert" # with two entries pointing to *completely* different types m = Model.construct(items=[{"level": -1}, 156]) assert len(m.items) == 2 assert isinstance(m.items[0], SubModel1) assert m.items[0].level == -1 assert cast(Any, m.items[1]) == 156 def test_dict_of_union() -> None: class SubModel1(BaseModel): name: str class SubModel2(BaseModel): foo: str class Model(BaseModel): data: Dict[str, Union[SubModel1, SubModel2]] m = Model.construct(data={"hello": {"name": "there"}, "foo": {"foo": "bar"}}) assert len(list(m.data.keys())) == 2 assert isinstance(m.data["hello"], SubModel1) assert m.data["hello"].name == "there" assert isinstance(m.data["foo"], SubModel2) assert m.data["foo"].foo == "bar" # TODO: test mismatched type def test_double_nested_union() -> None: class SubModel1(BaseModel): name: str class SubModel2(BaseModel): bar: str class Model(BaseModel): data: Dict[str, List[Union[SubModel1, SubModel2]]] m = Model.construct(data={"foo": [{"bar": "baz"}, {"name": "Robert"}]}) assert len(m.data["foo"]) == 2 entry1 = m.data["foo"][0] assert isinstance(entry1, SubModel2) assert entry1.bar == "baz" entry2 = m.data["foo"][1] assert isinstance(entry2, SubModel1) assert entry2.name == "Robert" # TODO: test mismatched type def test_union_of_dict() -> None: class SubModel1(BaseModel): name: str class SubModel2(BaseModel): foo: str class Model(BaseModel): data: Union[Dict[str, SubModel1], Dict[str, SubModel2]] m = Model.construct(data={"hello": {"name": "there"}, "foo": {"foo": "bar"}}) assert len(list(m.data.keys())) == 2 assert isinstance(m.data["hello"], SubModel1) assert m.data["hello"].name == "there" assert isinstance(m.data["foo"], SubModel1) assert cast(Any, m.data["foo"]).foo == "bar" def test_iso8601_datetime() -> None: class Model(BaseModel): created_at: datetime expected = datetime(2019, 12, 27, 18, 11, 19, 117000, tzinfo=timezone.utc) if PYDANTIC_V1: expected_json = '{"created_at": "2019-12-27T18:11:19.117000+00:00"}' else: expected_json = '{"created_at":"2019-12-27T18:11:19.117000Z"}' model = Model.construct(created_at="2019-12-27T18:11:19.117Z") assert model.created_at == expected assert model_json(model) == expected_json model = parse_obj(Model, dict(created_at="2019-12-27T18:11:19.117Z")) assert model.created_at == expected assert model_json(model) == expected_json def test_does_not_coerce_int() -> None: class Model(BaseModel): bar: int assert Model.construct(bar=1).bar == 1 assert Model.construct(bar=10.9).bar == 10.9 assert Model.construct(bar="19").bar == "19" # type: ignore[comparison-overlap] assert Model.construct(bar=False).bar is False def test_int_to_float_safe_conversion() -> None: class Model(BaseModel): float_field: float m = Model.construct(float_field=10) assert m.float_field == 10.0 assert isinstance(m.float_field, float) m = Model.construct(float_field=10.12) assert m.float_field == 10.12 assert isinstance(m.float_field, float) # number too big m = Model.construct(float_field=2**53 + 1) assert m.float_field == 2**53 + 1 assert isinstance(m.float_field, int) def test_deprecated_alias() -> None: class Model(BaseModel): resource_id: str = Field(alias="model_id") @property def model_id(self) -> str: return self.resource_id m = Model.construct(model_id="id") assert m.model_id == "id" assert m.resource_id == "id" assert m.resource_id is m.model_id m = parse_obj(Model, {"model_id": "id"}) assert m.model_id == "id" assert m.resource_id == "id" assert m.resource_id is m.model_id def test_omitted_fields() -> None: class Model(BaseModel): resource_id: Optional[str] = None m = Model.construct() assert m.resource_id is None assert "resource_id" not in m.model_fields_set m = Model.construct(resource_id=None) assert m.resource_id is None assert "resource_id" in m.model_fields_set m = Model.construct(resource_id="foo") assert m.resource_id == "foo" assert "resource_id" in m.model_fields_set def test_to_dict() -> None: class Model(BaseModel): foo: Optional[str] = Field(alias="FOO", default=None) m = Model(FOO="hello") assert m.to_dict() == {"FOO": "hello"} assert m.to_dict(use_api_names=False) == {"foo": "hello"} m2 = Model() assert m2.to_dict() == {} assert m2.to_dict(exclude_unset=False) == {"FOO": None} assert m2.to_dict(exclude_unset=False, exclude_none=True) == {} assert m2.to_dict(exclude_unset=False, exclude_defaults=True) == {} m3 = Model(FOO=None) assert m3.to_dict() == {"FOO": None} assert m3.to_dict(exclude_none=True) == {} assert m3.to_dict(exclude_defaults=True) == {} class Model2(BaseModel): created_at: datetime time_str = "2024-03-21T11:39:01.275859" m4 = Model2.construct(created_at=time_str) assert m4.to_dict(mode="python") == {"created_at": datetime.fromisoformat(time_str)} assert m4.to_dict(mode="json") == {"created_at": time_str} if PYDANTIC_V1: with pytest.raises(ValueError, match="warnings is only supported in Pydantic v2"): m.to_dict(warnings=False) def test_forwards_compat_model_dump_method() -> None: class Model(BaseModel): foo: Optional[str] = Field(alias="FOO", default=None) m = Model(FOO="hello") assert m.model_dump() == {"foo": "hello"} assert m.model_dump(include={"bar"}) == {} assert m.model_dump(exclude={"foo"}) == {} assert m.model_dump(by_alias=True) == {"FOO": "hello"} m2 = Model() assert m2.model_dump() == {"foo": None} assert m2.model_dump(exclude_unset=True) == {} assert m2.model_dump(exclude_none=True) == {} assert m2.model_dump(exclude_defaults=True) == {} m3 = Model(FOO=None) assert m3.model_dump() == {"foo": None} assert m3.model_dump(exclude_none=True) == {} if PYDANTIC_V1: with pytest.raises(ValueError, match="round_trip is only supported in Pydantic v2"): m.model_dump(round_trip=True) with pytest.raises(ValueError, match="warnings is only supported in Pydantic v2"): m.model_dump(warnings=False) def test_compat_method_no_error_for_warnings() -> None: class Model(BaseModel): foo: Optional[str] m = Model(foo="hello") assert isinstance(model_dump(m, warnings=False), dict) def test_to_json() -> None: class Model(BaseModel): foo: Optional[str] = Field(alias="FOO", default=None) m = Model(FOO="hello") assert json.loads(m.to_json()) == {"FOO": "hello"} assert json.loads(m.to_json(use_api_names=False)) == {"foo": "hello"} if PYDANTIC_V1: assert m.to_json(indent=None) == '{"FOO": "hello"}' else: assert m.to_json(indent=None) == '{"FOO":"hello"}' m2 = Model() assert json.loads(m2.to_json()) == {} assert json.loads(m2.to_json(exclude_unset=False)) == {"FOO": None} assert json.loads(m2.to_json(exclude_unset=False, exclude_none=True)) == {} assert json.loads(m2.to_json(exclude_unset=False, exclude_defaults=True)) == {} m3 = Model(FOO=None) assert json.loads(m3.to_json()) == {"FOO": None} assert json.loads(m3.to_json(exclude_none=True)) == {} if PYDANTIC_V1: with pytest.raises(ValueError, match="warnings is only supported in Pydantic v2"): m.to_json(warnings=False) def test_forwards_compat_model_dump_json_method() -> None: class Model(BaseModel): foo: Optional[str] = Field(alias="FOO", default=None) m = Model(FOO="hello") assert json.loads(m.model_dump_json()) == {"foo": "hello"} assert json.loads(m.model_dump_json(include={"bar"})) == {} assert json.loads(m.model_dump_json(include={"foo"})) == {"foo": "hello"} assert json.loads(m.model_dump_json(by_alias=True)) == {"FOO": "hello"} assert m.model_dump_json(indent=2) == '{\n "foo": "hello"\n}' m2 = Model() assert json.loads(m2.model_dump_json()) == {"foo": None} assert json.loads(m2.model_dump_json(exclude_unset=True)) == {} assert json.loads(m2.model_dump_json(exclude_none=True)) == {} assert json.loads(m2.model_dump_json(exclude_defaults=True)) == {} m3 = Model(FOO=None) assert json.loads(m3.model_dump_json()) == {"foo": None} assert json.loads(m3.model_dump_json(exclude_none=True)) == {} if PYDANTIC_V1: with pytest.raises(ValueError, match="round_trip is only supported in Pydantic v2"): m.model_dump_json(round_trip=True) with pytest.raises(ValueError, match="warnings is only supported in Pydantic v2"): m.model_dump_json(warnings=False) def test_type_compat() -> None: # our model type can be assigned to Pydantic's model type def takes_pydantic(model: pydantic.BaseModel) -> None: # noqa: ARG001 ... class OurModel(BaseModel): foo: Optional[str] = None takes_pydantic(OurModel()) def test_annotated_types() -> None: class Model(BaseModel): value: str m = construct_type( value={"value": "foo"}, type_=cast(Any, Annotated[Model, "random metadata"]), ) assert isinstance(m, Model) assert m.value == "foo" def test_discriminated_unions_invalid_data() -> None: class A(BaseModel): type: Literal["a"] data: str class B(BaseModel): type: Literal["b"] data: int m = construct_type( value={"type": "b", "data": "foo"}, type_=cast(Any, Annotated[Union[A, B], PropertyInfo(discriminator="type")]), ) assert isinstance(m, B) assert m.type == "b" assert m.data == "foo" # type: ignore[comparison-overlap] m = construct_type( value={"type": "a", "data": 100}, type_=cast(Any, Annotated[Union[A, B], PropertyInfo(discriminator="type")]), ) assert isinstance(m, A) assert m.type == "a" if PYDANTIC_V1: # pydantic v1 automatically converts inputs to strings # if the expected type is a str assert m.data == "100" else: assert m.data == 100 # type: ignore[comparison-overlap] def test_discriminated_unions_unknown_variant() -> None: class A(BaseModel): type: Literal["a"] data: str class B(BaseModel): type: Literal["b"] data: int m = construct_type( value={"type": "c", "data": None, "new_thing": "bar"}, type_=cast(Any, Annotated[Union[A, B], PropertyInfo(discriminator="type")]), ) # just chooses the first variant assert isinstance(m, A) assert m.type == "c" # type: ignore[comparison-overlap] assert m.data == None # type: ignore[unreachable] assert m.new_thing == "bar" def test_discriminated_unions_invalid_data_nested_unions() -> None: class A(BaseModel): type: Literal["a"] data: str class B(BaseModel): type: Literal["b"] data: int class C(BaseModel): type: Literal["c"] data: bool m = construct_type( value={"type": "b", "data": "foo"}, type_=cast(Any, Annotated[Union[Union[A, B], C], PropertyInfo(discriminator="type")]), ) assert isinstance(m, B) assert m.type == "b" assert m.data == "foo" # type: ignore[comparison-overlap] m = construct_type( value={"type": "c", "data": "foo"}, type_=cast(Any, Annotated[Union[Union[A, B], C], PropertyInfo(discriminator="type")]), ) assert isinstance(m, C) assert m.type == "c" assert m.data == "foo" # type: ignore[comparison-overlap] def test_discriminated_unions_with_aliases_invalid_data() -> None: class A(BaseModel): foo_type: Literal["a"] = Field(alias="type") data: str class B(BaseModel): foo_type: Literal["b"] = Field(alias="type") data: int m = construct_type( value={"type": "b", "data": "foo"}, type_=cast(Any, Annotated[Union[A, B], PropertyInfo(discriminator="foo_type")]), ) assert isinstance(m, B) assert m.foo_type == "b" assert m.data == "foo" # type: ignore[comparison-overlap] m = construct_type( value={"type": "a", "data": 100}, type_=cast(Any, Annotated[Union[A, B], PropertyInfo(discriminator="foo_type")]), ) assert isinstance(m, A) assert m.foo_type == "a" if PYDANTIC_V1: # pydantic v1 automatically converts inputs to strings # if the expected type is a str assert m.data == "100" else: assert m.data == 100 # type: ignore[comparison-overlap] def test_discriminated_unions_overlapping_discriminators_invalid_data() -> None: class A(BaseModel): type: Literal["a"] data: bool class B(BaseModel): type: Literal["a"] data: int m = construct_type( value={"type": "a", "data": "foo"}, type_=cast(Any, Annotated[Union[A, B], PropertyInfo(discriminator="type")]), ) assert isinstance(m, B) assert m.type == "a" assert m.data == "foo" # type: ignore[comparison-overlap] def test_discriminated_unions_invalid_data_uses_cache() -> None: class A(BaseModel): type: Literal["a"] data: str class B(BaseModel): type: Literal["b"] data: int UnionType = cast(Any, Union[A, B]) assert not hasattr(UnionType, "__discriminator__") m = construct_type( value={"type": "b", "data": "foo"}, type_=cast(Any, Annotated[UnionType, PropertyInfo(discriminator="type")]) ) assert isinstance(m, B) assert m.type == "b" assert m.data == "foo" # type: ignore[comparison-overlap] discriminator = UnionType.__discriminator__ assert discriminator is not None m = construct_type( value={"type": "b", "data": "foo"}, type_=cast(Any, Annotated[UnionType, PropertyInfo(discriminator="type")]) ) assert isinstance(m, B) assert m.type == "b" assert m.data == "foo" # type: ignore[comparison-overlap] # if the discriminator details object stays the same between invocations then # we hit the cache assert UnionType.__discriminator__ is discriminator @pytest.mark.skipif(PYDANTIC_V1, reason="TypeAliasType is not supported in Pydantic v1") def test_type_alias_type() -> None: Alias = TypeAliasType("Alias", str) # pyright: ignore class Model(BaseModel): alias: Alias union: Union[int, Alias] m = construct_type(value={"alias": "foo", "union": "bar"}, type_=Model) assert isinstance(m, Model) assert isinstance(m.alias, str) assert m.alias == "foo" assert isinstance(m.union, str) assert m.union == "bar" @pytest.mark.skipif(PYDANTIC_V1, reason="TypeAliasType is not supported in Pydantic v1") def test_field_named_cls() -> None: class Model(BaseModel): cls: str m = construct_type(value={"cls": "foo"}, type_=Model) assert isinstance(m, Model) assert isinstance(m.cls, str) def test_discriminated_union_case() -> None: class A(BaseModel): type: Literal["a"] data: bool class B(BaseModel): type: Literal["b"] data: List[Union[A, object]] class ModelA(BaseModel): type: Literal["modelA"] data: int class ModelB(BaseModel): type: Literal["modelB"] required: str data: Union[A, B] # when constructing ModelA | ModelB, value data doesn't match ModelB exactly - missing `required` m = construct_type( value={"type": "modelB", "data": {"type": "a", "data": True}}, type_=cast(Any, Annotated[Union[ModelA, ModelB], PropertyInfo(discriminator="type")]), ) assert isinstance(m, ModelB) def test_nested_discriminated_union() -> None: class InnerType1(BaseModel): type: Literal["type_1"] class InnerModel(BaseModel): inner_value: str class InnerType2(BaseModel): type: Literal["type_2"] some_inner_model: InnerModel class Type1(BaseModel): base_type: Literal["base_type_1"] value: Annotated[ Union[ InnerType1, InnerType2, ], PropertyInfo(discriminator="type"), ] class Type2(BaseModel): base_type: Literal["base_type_2"] T = Annotated[ Union[ Type1, Type2, ], PropertyInfo(discriminator="base_type"), ] model = construct_type( type_=T, value={ "base_type": "base_type_1", "value": { "type": "type_2", }, }, ) assert isinstance(model, Type1) assert isinstance(model.value, InnerType2) @pytest.mark.skipif(PYDANTIC_V1, reason="this is only supported in pydantic v2 for now") def test_extra_properties() -> None: class Item(BaseModel): prop: int class Model(BaseModel): __pydantic_extra__: Dict[str, Item] = Field(init=False) # pyright: ignore[reportIncompatibleVariableOverride] other: str if TYPE_CHECKING: def __getattr__(self, attr: str) -> Item: ... model = construct_type( type_=Model, value={ "a": {"prop": 1}, "other": "foo", }, ) assert isinstance(model, Model) assert model.a.prop == 1 assert isinstance(model.a, Item) assert model.other == "foo" anthropic-sdk-python-0.69.0/tests/test_qs.py000066400000000000000000000062031506653454500211070ustar00rootroot00000000000000from typing import Any, cast from functools import partial from urllib.parse import unquote import pytest from anthropic._qs import Querystring, stringify def test_empty() -> None: assert stringify({}) == "" assert stringify({"a": {}}) == "" assert stringify({"a": {"b": {"c": {}}}}) == "" def test_basic() -> None: assert stringify({"a": 1}) == "a=1" assert stringify({"a": "b"}) == "a=b" assert stringify({"a": True}) == "a=true" assert stringify({"a": False}) == "a=false" assert stringify({"a": 1.23456}) == "a=1.23456" assert stringify({"a": None}) == "" @pytest.mark.parametrize("method", ["class", "function"]) def test_nested_dotted(method: str) -> None: if method == "class": serialise = Querystring(nested_format="dots").stringify else: serialise = partial(stringify, nested_format="dots") assert unquote(serialise({"a": {"b": "c"}})) == "a.b=c" assert unquote(serialise({"a": {"b": "c", "d": "e", "f": "g"}})) == "a.b=c&a.d=e&a.f=g" assert unquote(serialise({"a": {"b": {"c": {"d": "e"}}}})) == "a.b.c.d=e" assert unquote(serialise({"a": {"b": True}})) == "a.b=true" def test_nested_brackets() -> None: assert unquote(stringify({"a": {"b": "c"}})) == "a[b]=c" assert unquote(stringify({"a": {"b": "c", "d": "e", "f": "g"}})) == "a[b]=c&a[d]=e&a[f]=g" assert unquote(stringify({"a": {"b": {"c": {"d": "e"}}}})) == "a[b][c][d]=e" assert unquote(stringify({"a": {"b": True}})) == "a[b]=true" @pytest.mark.parametrize("method", ["class", "function"]) def test_array_comma(method: str) -> None: if method == "class": serialise = Querystring(array_format="comma").stringify else: serialise = partial(stringify, array_format="comma") assert unquote(serialise({"in": ["foo", "bar"]})) == "in=foo,bar" assert unquote(serialise({"a": {"b": [True, False]}})) == "a[b]=true,false" assert unquote(serialise({"a": {"b": [True, False, None, True]}})) == "a[b]=true,false,true" def test_array_repeat() -> None: assert unquote(stringify({"in": ["foo", "bar"]})) == "in=foo&in=bar" assert unquote(stringify({"a": {"b": [True, False]}})) == "a[b]=true&a[b]=false" assert unquote(stringify({"a": {"b": [True, False, None, True]}})) == "a[b]=true&a[b]=false&a[b]=true" assert unquote(stringify({"in": ["foo", {"b": {"c": ["d", "e"]}}]})) == "in=foo&in[b][c]=d&in[b][c]=e" @pytest.mark.parametrize("method", ["class", "function"]) def test_array_brackets(method: str) -> None: if method == "class": serialise = Querystring(array_format="brackets").stringify else: serialise = partial(stringify, array_format="brackets") assert unquote(serialise({"in": ["foo", "bar"]})) == "in[]=foo&in[]=bar" assert unquote(serialise({"a": {"b": [True, False]}})) == "a[b][]=true&a[b][]=false" assert unquote(serialise({"a": {"b": [True, False, None, True]}})) == "a[b][]=true&a[b][]=false&a[b][]=true" def test_unknown_array_format() -> None: with pytest.raises(NotImplementedError, match="Unknown array_format value: foo, choose from comma, repeat"): stringify({"a": ["foo", "bar"]}, array_format=cast(Any, "foo")) anthropic-sdk-python-0.69.0/tests/test_required_args.py000066400000000000000000000057641506653454500233330ustar00rootroot00000000000000from __future__ import annotations import pytest from anthropic._utils import required_args def test_too_many_positional_params() -> None: @required_args(["a"]) def foo(a: str | None = None) -> str | None: return a with pytest.raises(TypeError, match=r"foo\(\) takes 1 argument\(s\) but 2 were given"): foo("a", "b") # type: ignore def test_positional_param() -> None: @required_args(["a"]) def foo(a: str | None = None) -> str | None: return a assert foo("a") == "a" assert foo(None) is None assert foo(a="b") == "b" with pytest.raises(TypeError, match="Missing required argument: 'a'"): foo() def test_keyword_only_param() -> None: @required_args(["a"]) def foo(*, a: str | None = None) -> str | None: return a assert foo(a="a") == "a" assert foo(a=None) is None assert foo(a="b") == "b" with pytest.raises(TypeError, match="Missing required argument: 'a'"): foo() def test_multiple_params() -> None: @required_args(["a", "b", "c"]) def foo(a: str = "", *, b: str = "", c: str = "") -> str | None: return f"{a} {b} {c}" assert foo(a="a", b="b", c="c") == "a b c" error_message = r"Missing required arguments.*" with pytest.raises(TypeError, match=error_message): foo() with pytest.raises(TypeError, match=error_message): foo(a="a") with pytest.raises(TypeError, match=error_message): foo(b="b") with pytest.raises(TypeError, match=error_message): foo(c="c") with pytest.raises(TypeError, match=r"Missing required argument: 'a'"): foo(b="a", c="c") with pytest.raises(TypeError, match=r"Missing required argument: 'b'"): foo("a", c="c") def test_multiple_variants() -> None: @required_args(["a"], ["b"]) def foo(*, a: str | None = None, b: str | None = None) -> str | None: return a if a is not None else b assert foo(a="foo") == "foo" assert foo(b="bar") == "bar" assert foo(a=None) is None assert foo(b=None) is None # TODO: this error message could probably be improved with pytest.raises( TypeError, match=r"Missing required arguments; Expected either \('a'\) or \('b'\) arguments to be given", ): foo() def test_multiple_params_multiple_variants() -> None: @required_args(["a", "b"], ["c"]) def foo(*, a: str | None = None, b: str | None = None, c: str | None = None) -> str | None: if a is not None: return a if b is not None: return b return c error_message = r"Missing required arguments; Expected either \('a' and 'b'\) or \('c'\) arguments to be given" with pytest.raises(TypeError, match=error_message): foo(a="foo") with pytest.raises(TypeError, match=error_message): foo(b="bar") with pytest.raises(TypeError, match=error_message): foo() assert foo(a=None, b="bar") == "bar" assert foo(c=None) is None assert foo(c="foo") == "foo" anthropic-sdk-python-0.69.0/tests/test_response.py000066400000000000000000000225701506653454500223270ustar00rootroot00000000000000import json from typing import Any, List, Union, cast from typing_extensions import Annotated import httpx import pytest import pydantic from anthropic import Anthropic, BaseModel, AsyncAnthropic from anthropic._response import ( APIResponse, BaseAPIResponse, AsyncAPIResponse, BinaryAPIResponse, AsyncBinaryAPIResponse, extract_response_type, ) from anthropic._streaming import Stream from anthropic._base_client import FinalRequestOptions class ConcreteBaseAPIResponse(APIResponse[bytes]): ... class ConcreteAPIResponse(APIResponse[List[str]]): ... class ConcreteAsyncAPIResponse(APIResponse[httpx.Response]): ... def test_extract_response_type_direct_classes() -> None: assert extract_response_type(BaseAPIResponse[str]) == str assert extract_response_type(APIResponse[str]) == str assert extract_response_type(AsyncAPIResponse[str]) == str def test_extract_response_type_direct_class_missing_type_arg() -> None: with pytest.raises( RuntimeError, match="Expected type to have a type argument at index 0 but it did not", ): extract_response_type(AsyncAPIResponse) def test_extract_response_type_concrete_subclasses() -> None: assert extract_response_type(ConcreteBaseAPIResponse) == bytes assert extract_response_type(ConcreteAPIResponse) == List[str] assert extract_response_type(ConcreteAsyncAPIResponse) == httpx.Response def test_extract_response_type_binary_response() -> None: assert extract_response_type(BinaryAPIResponse) == bytes assert extract_response_type(AsyncBinaryAPIResponse) == bytes class PydanticModel(pydantic.BaseModel): ... def test_response_parse_mismatched_basemodel(client: Anthropic) -> None: response = APIResponse( raw=httpx.Response(200, content=b"foo"), client=client, stream=False, stream_cls=None, cast_to=str, options=FinalRequestOptions.construct(method="get", url="/foo"), ) with pytest.raises( TypeError, match="Pydantic models must subclass our base model type, e.g. `from anthropic import BaseModel`", ): response.parse(to=PydanticModel) @pytest.mark.asyncio async def test_async_response_parse_mismatched_basemodel(async_client: AsyncAnthropic) -> None: response = AsyncAPIResponse( raw=httpx.Response(200, content=b"foo"), client=async_client, stream=False, stream_cls=None, cast_to=str, options=FinalRequestOptions.construct(method="get", url="/foo"), ) with pytest.raises( TypeError, match="Pydantic models must subclass our base model type, e.g. `from anthropic import BaseModel`", ): await response.parse(to=PydanticModel) def test_response_parse_custom_stream(client: Anthropic) -> None: response = APIResponse( raw=httpx.Response(200, content=b"foo"), client=client, stream=True, stream_cls=None, cast_to=str, options=FinalRequestOptions.construct(method="get", url="/foo"), ) stream = response.parse(to=Stream[int]) assert stream._cast_to == int @pytest.mark.asyncio async def test_async_response_parse_custom_stream(async_client: AsyncAnthropic) -> None: response = AsyncAPIResponse( raw=httpx.Response(200, content=b"foo"), client=async_client, stream=True, stream_cls=None, cast_to=str, options=FinalRequestOptions.construct(method="get", url="/foo"), ) stream = await response.parse(to=Stream[int]) assert stream._cast_to == int class CustomModel(BaseModel): foo: str bar: int def test_response_parse_custom_model(client: Anthropic) -> None: response = APIResponse( raw=httpx.Response(200, content=json.dumps({"foo": "hello!", "bar": 2})), client=client, stream=False, stream_cls=None, cast_to=str, options=FinalRequestOptions.construct(method="get", url="/foo"), ) obj = response.parse(to=CustomModel) assert obj.foo == "hello!" assert obj.bar == 2 @pytest.mark.asyncio async def test_async_response_parse_custom_model(async_client: AsyncAnthropic) -> None: response = AsyncAPIResponse( raw=httpx.Response(200, content=json.dumps({"foo": "hello!", "bar": 2})), client=async_client, stream=False, stream_cls=None, cast_to=str, options=FinalRequestOptions.construct(method="get", url="/foo"), ) obj = await response.parse(to=CustomModel) assert obj.foo == "hello!" assert obj.bar == 2 def test_response_basemodel_request_id(client: Anthropic) -> None: response = APIResponse( raw=httpx.Response( 200, headers={"request-id": "my-req-id"}, content=json.dumps({"foo": "hello!", "bar": 2}), ), client=client, stream=False, stream_cls=None, cast_to=str, options=FinalRequestOptions.construct(method="get", url="/foo"), ) obj = response.parse(to=CustomModel) assert obj._request_id == "my-req-id" assert obj.foo == "hello!" assert obj.bar == 2 assert obj.to_dict() == {"foo": "hello!", "bar": 2} @pytest.mark.asyncio async def test_async_response_basemodel_request_id(client: Anthropic) -> None: response = AsyncAPIResponse( raw=httpx.Response( 200, headers={"request-id": "my-req-id"}, content=json.dumps({"foo": "hello!", "bar": 2}), ), client=client, stream=False, stream_cls=None, cast_to=str, options=FinalRequestOptions.construct(method="get", url="/foo"), ) obj = await response.parse(to=CustomModel) assert obj._request_id == "my-req-id" assert obj.foo == "hello!" assert obj.bar == 2 assert obj.to_dict() == {"foo": "hello!", "bar": 2} def test_response_parse_annotated_type(client: Anthropic) -> None: response = APIResponse( raw=httpx.Response(200, content=json.dumps({"foo": "hello!", "bar": 2})), client=client, stream=False, stream_cls=None, cast_to=str, options=FinalRequestOptions.construct(method="get", url="/foo"), ) obj = response.parse( to=cast("type[CustomModel]", Annotated[CustomModel, "random metadata"]), ) assert obj.foo == "hello!" assert obj.bar == 2 async def test_async_response_parse_annotated_type(async_client: AsyncAnthropic) -> None: response = AsyncAPIResponse( raw=httpx.Response(200, content=json.dumps({"foo": "hello!", "bar": 2})), client=async_client, stream=False, stream_cls=None, cast_to=str, options=FinalRequestOptions.construct(method="get", url="/foo"), ) obj = await response.parse( to=cast("type[CustomModel]", Annotated[CustomModel, "random metadata"]), ) assert obj.foo == "hello!" assert obj.bar == 2 @pytest.mark.parametrize( "content, expected", [ ("false", False), ("true", True), ("False", False), ("True", True), ("TrUe", True), ("FalSe", False), ], ) def test_response_parse_bool(client: Anthropic, content: str, expected: bool) -> None: response = APIResponse( raw=httpx.Response(200, content=content), client=client, stream=False, stream_cls=None, cast_to=str, options=FinalRequestOptions.construct(method="get", url="/foo"), ) result = response.parse(to=bool) assert result is expected @pytest.mark.parametrize( "content, expected", [ ("false", False), ("true", True), ("False", False), ("True", True), ("TrUe", True), ("FalSe", False), ], ) async def test_async_response_parse_bool(client: AsyncAnthropic, content: str, expected: bool) -> None: response = AsyncAPIResponse( raw=httpx.Response(200, content=content), client=client, stream=False, stream_cls=None, cast_to=str, options=FinalRequestOptions.construct(method="get", url="/foo"), ) result = await response.parse(to=bool) assert result is expected class OtherModel(BaseModel): a: str @pytest.mark.parametrize("client", [False], indirect=True) # loose validation def test_response_parse_expect_model_union_non_json_content(client: Anthropic) -> None: response = APIResponse( raw=httpx.Response(200, content=b"foo", headers={"Content-Type": "application/text"}), client=client, stream=False, stream_cls=None, cast_to=str, options=FinalRequestOptions.construct(method="get", url="/foo"), ) obj = response.parse(to=cast(Any, Union[CustomModel, OtherModel])) assert isinstance(obj, str) assert obj == "foo" @pytest.mark.asyncio @pytest.mark.parametrize("async_client", [False], indirect=True) # loose validation async def test_async_response_parse_expect_model_union_non_json_content(async_client: AsyncAnthropic) -> None: response = AsyncAPIResponse( raw=httpx.Response(200, content=b"foo", headers={"Content-Type": "application/text"}), client=async_client, stream=False, stream_cls=None, cast_to=str, options=FinalRequestOptions.construct(method="get", url="/foo"), ) obj = await response.parse(to=cast(Any, Union[CustomModel, OtherModel])) assert isinstance(obj, str) assert obj == "foo" anthropic-sdk-python-0.69.0/tests/test_streaming.py000066400000000000000000000203631506653454500224600ustar00rootroot00000000000000from __future__ import annotations from typing import Iterator, AsyncIterator import httpx import pytest from anthropic import Anthropic, AsyncAnthropic from anthropic._streaming import Stream, AsyncStream, ServerSentEvent @pytest.mark.asyncio @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"]) async def test_basic(sync: bool, client: Anthropic, async_client: AsyncAnthropic) -> None: def body() -> Iterator[bytes]: yield b"event: completion\n" yield b'data: {"foo":true}\n' yield b"\n" iterator = make_event_iterator(content=body(), sync=sync, client=client, async_client=async_client) sse = await iter_next(iterator) assert sse.event == "completion" assert sse.json() == {"foo": True} await assert_empty_iter(iterator) @pytest.mark.asyncio @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"]) async def test_data_missing_event(sync: bool, client: Anthropic, async_client: AsyncAnthropic) -> None: def body() -> Iterator[bytes]: yield b'data: {"foo":true}\n' yield b"\n" iterator = make_event_iterator(content=body(), sync=sync, client=client, async_client=async_client) sse = await iter_next(iterator) assert sse.event is None assert sse.json() == {"foo": True} await assert_empty_iter(iterator) @pytest.mark.asyncio @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"]) async def test_event_missing_data(sync: bool, client: Anthropic, async_client: AsyncAnthropic) -> None: def body() -> Iterator[bytes]: yield b"event: ping\n" yield b"\n" iterator = make_event_iterator(content=body(), sync=sync, client=client, async_client=async_client) sse = await iter_next(iterator) assert sse.event == "ping" assert sse.data == "" await assert_empty_iter(iterator) @pytest.mark.asyncio @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"]) async def test_multiple_events(sync: bool, client: Anthropic, async_client: AsyncAnthropic) -> None: def body() -> Iterator[bytes]: yield b"event: ping\n" yield b"\n" yield b"event: completion\n" yield b"\n" iterator = make_event_iterator(content=body(), sync=sync, client=client, async_client=async_client) sse = await iter_next(iterator) assert sse.event == "ping" assert sse.data == "" sse = await iter_next(iterator) assert sse.event == "completion" assert sse.data == "" await assert_empty_iter(iterator) @pytest.mark.asyncio @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"]) async def test_multiple_events_with_data(sync: bool, client: Anthropic, async_client: AsyncAnthropic) -> None: def body() -> Iterator[bytes]: yield b"event: ping\n" yield b'data: {"foo":true}\n' yield b"\n" yield b"event: completion\n" yield b'data: {"bar":false}\n' yield b"\n" iterator = make_event_iterator(content=body(), sync=sync, client=client, async_client=async_client) sse = await iter_next(iterator) assert sse.event == "ping" assert sse.json() == {"foo": True} sse = await iter_next(iterator) assert sse.event == "completion" assert sse.json() == {"bar": False} await assert_empty_iter(iterator) @pytest.mark.asyncio @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"]) async def test_multiple_data_lines_with_empty_line(sync: bool, client: Anthropic, async_client: AsyncAnthropic) -> None: def body() -> Iterator[bytes]: yield b"event: ping\n" yield b"data: {\n" yield b'data: "foo":\n' yield b"data: \n" yield b"data:\n" yield b"data: true}\n" yield b"\n\n" iterator = make_event_iterator(content=body(), sync=sync, client=client, async_client=async_client) sse = await iter_next(iterator) assert sse.event == "ping" assert sse.json() == {"foo": True} assert sse.data == '{\n"foo":\n\n\ntrue}' await assert_empty_iter(iterator) @pytest.mark.asyncio @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"]) async def test_data_json_escaped_double_new_line(sync: bool, client: Anthropic, async_client: AsyncAnthropic) -> None: def body() -> Iterator[bytes]: yield b"event: ping\n" yield b'data: {"foo": "my long\\n\\ncontent"}' yield b"\n\n" iterator = make_event_iterator(content=body(), sync=sync, client=client, async_client=async_client) sse = await iter_next(iterator) assert sse.event == "ping" assert sse.json() == {"foo": "my long\n\ncontent"} await assert_empty_iter(iterator) @pytest.mark.asyncio @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"]) async def test_multiple_data_lines(sync: bool, client: Anthropic, async_client: AsyncAnthropic) -> None: def body() -> Iterator[bytes]: yield b"event: ping\n" yield b"data: {\n" yield b'data: "foo":\n' yield b"data: true}\n" yield b"\n\n" iterator = make_event_iterator(content=body(), sync=sync, client=client, async_client=async_client) sse = await iter_next(iterator) assert sse.event == "ping" assert sse.json() == {"foo": True} await assert_empty_iter(iterator) @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"]) async def test_special_new_line_character( sync: bool, client: Anthropic, async_client: AsyncAnthropic, ) -> None: def body() -> Iterator[bytes]: yield b'data: {"content":" culpa"}\n' yield b"\n" yield b'data: {"content":" \xe2\x80\xa8"}\n' yield b"\n" yield b'data: {"content":"foo"}\n' yield b"\n" iterator = make_event_iterator(content=body(), sync=sync, client=client, async_client=async_client) sse = await iter_next(iterator) assert sse.event is None assert sse.json() == {"content": " culpa"} sse = await iter_next(iterator) assert sse.event is None assert sse.json() == {"content": " 
"} sse = await iter_next(iterator) assert sse.event is None assert sse.json() == {"content": "foo"} await assert_empty_iter(iterator) @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"]) async def test_multi_byte_character_multiple_chunks( sync: bool, client: Anthropic, async_client: AsyncAnthropic, ) -> None: def body() -> Iterator[bytes]: yield b'data: {"content":"' # bytes taken from the string 'известни' and arbitrarily split # so that some multi-byte characters span multiple chunks yield b"\xd0" yield b"\xb8\xd0\xb7\xd0" yield b"\xb2\xd0\xb5\xd1\x81\xd1\x82\xd0\xbd\xd0\xb8" yield b'"}\n' yield b"\n" iterator = make_event_iterator(content=body(), sync=sync, client=client, async_client=async_client) sse = await iter_next(iterator) assert sse.event is None assert sse.json() == {"content": "известни"} def test_isinstance_check(client: Anthropic, async_client: AsyncAnthropic) -> None: async_stream = AsyncStream(cast_to=object, client=async_client, response=httpx.Response(200, content=b"foo")) assert isinstance(async_stream, AsyncStream) sync_stream = Stream(cast_to=object, client=client, response=httpx.Response(200, content=b"foo")) assert isinstance(sync_stream, Stream) async def to_aiter(iter: Iterator[bytes]) -> AsyncIterator[bytes]: for chunk in iter: yield chunk async def iter_next(iter: Iterator[ServerSentEvent] | AsyncIterator[ServerSentEvent]) -> ServerSentEvent: if isinstance(iter, AsyncIterator): return await iter.__anext__() return next(iter) async def assert_empty_iter(iter: Iterator[ServerSentEvent] | AsyncIterator[ServerSentEvent]) -> None: with pytest.raises((StopAsyncIteration, RuntimeError)): await iter_next(iter) def make_event_iterator( content: Iterator[bytes], *, sync: bool, client: Anthropic, async_client: AsyncAnthropic, ) -> Iterator[ServerSentEvent] | AsyncIterator[ServerSentEvent]: if sync: return Stream(cast_to=object, client=client, response=httpx.Response(200, content=content))._iter_events() return AsyncStream( cast_to=object, client=async_client, response=httpx.Response(200, content=to_aiter(content)) )._iter_events() anthropic-sdk-python-0.69.0/tests/test_transform.py000066400000000000000000000364071506653454500225100ustar00rootroot00000000000000from __future__ import annotations import io import pathlib from typing import Any, Dict, List, Union, TypeVar, Iterable, Optional, cast from datetime import date, datetime from typing_extensions import Required, Annotated, TypedDict import pytest from anthropic._types import Base64FileInput, omit, not_given from anthropic._utils import ( PropertyInfo, transform as _transform, parse_datetime, async_transform as _async_transform, ) from anthropic._compat import PYDANTIC_V1 from anthropic._models import BaseModel _T = TypeVar("_T") SAMPLE_FILE_PATH = pathlib.Path(__file__).parent.joinpath("sample_file.txt") async def transform( data: _T, expected_type: object, use_async: bool, ) -> _T: if use_async: return await _async_transform(data, expected_type=expected_type) return _transform(data, expected_type=expected_type) parametrize = pytest.mark.parametrize("use_async", [False, True], ids=["sync", "async"]) class Foo1(TypedDict): foo_bar: Annotated[str, PropertyInfo(alias="fooBar")] @parametrize @pytest.mark.asyncio async def test_top_level_alias(use_async: bool) -> None: assert await transform({"foo_bar": "hello"}, expected_type=Foo1, use_async=use_async) == {"fooBar": "hello"} class Foo2(TypedDict): bar: Bar2 class Bar2(TypedDict): this_thing: Annotated[int, PropertyInfo(alias="this__thing")] baz: Annotated[Baz2, PropertyInfo(alias="Baz")] class Baz2(TypedDict): my_baz: Annotated[str, PropertyInfo(alias="myBaz")] @parametrize @pytest.mark.asyncio async def test_recursive_typeddict(use_async: bool) -> None: assert await transform({"bar": {"this_thing": 1}}, Foo2, use_async) == {"bar": {"this__thing": 1}} assert await transform({"bar": {"baz": {"my_baz": "foo"}}}, Foo2, use_async) == {"bar": {"Baz": {"myBaz": "foo"}}} class Foo3(TypedDict): things: List[Bar3] class Bar3(TypedDict): my_field: Annotated[str, PropertyInfo(alias="myField")] @parametrize @pytest.mark.asyncio async def test_list_of_typeddict(use_async: bool) -> None: result = await transform({"things": [{"my_field": "foo"}, {"my_field": "foo2"}]}, Foo3, use_async) assert result == {"things": [{"myField": "foo"}, {"myField": "foo2"}]} class Foo4(TypedDict): foo: Union[Bar4, Baz4] class Bar4(TypedDict): foo_bar: Annotated[str, PropertyInfo(alias="fooBar")] class Baz4(TypedDict): foo_baz: Annotated[str, PropertyInfo(alias="fooBaz")] @parametrize @pytest.mark.asyncio async def test_union_of_typeddict(use_async: bool) -> None: assert await transform({"foo": {"foo_bar": "bar"}}, Foo4, use_async) == {"foo": {"fooBar": "bar"}} assert await transform({"foo": {"foo_baz": "baz"}}, Foo4, use_async) == {"foo": {"fooBaz": "baz"}} assert await transform({"foo": {"foo_baz": "baz", "foo_bar": "bar"}}, Foo4, use_async) == { "foo": {"fooBaz": "baz", "fooBar": "bar"} } class Foo5(TypedDict): foo: Annotated[Union[Bar4, List[Baz4]], PropertyInfo(alias="FOO")] class Bar5(TypedDict): foo_bar: Annotated[str, PropertyInfo(alias="fooBar")] class Baz5(TypedDict): foo_baz: Annotated[str, PropertyInfo(alias="fooBaz")] @parametrize @pytest.mark.asyncio async def test_union_of_list(use_async: bool) -> None: assert await transform({"foo": {"foo_bar": "bar"}}, Foo5, use_async) == {"FOO": {"fooBar": "bar"}} assert await transform( { "foo": [ {"foo_baz": "baz"}, {"foo_baz": "baz"}, ] }, Foo5, use_async, ) == {"FOO": [{"fooBaz": "baz"}, {"fooBaz": "baz"}]} class Foo6(TypedDict): bar: Annotated[str, PropertyInfo(alias="Bar")] @parametrize @pytest.mark.asyncio async def test_includes_unknown_keys(use_async: bool) -> None: assert await transform({"bar": "bar", "baz_": {"FOO": 1}}, Foo6, use_async) == { "Bar": "bar", "baz_": {"FOO": 1}, } class Foo7(TypedDict): bar: Annotated[List[Bar7], PropertyInfo(alias="bAr")] foo: Bar7 class Bar7(TypedDict): foo: str @parametrize @pytest.mark.asyncio async def test_ignores_invalid_input(use_async: bool) -> None: assert await transform({"bar": ""}, Foo7, use_async) == {"bAr": ""} assert await transform({"foo": ""}, Foo7, use_async) == {"foo": ""} class DatetimeDict(TypedDict, total=False): foo: Annotated[datetime, PropertyInfo(format="iso8601")] bar: Annotated[Optional[datetime], PropertyInfo(format="iso8601")] required: Required[Annotated[Optional[datetime], PropertyInfo(format="iso8601")]] list_: Required[Annotated[Optional[List[datetime]], PropertyInfo(format="iso8601")]] union: Annotated[Union[int, datetime], PropertyInfo(format="iso8601")] class DateDict(TypedDict, total=False): foo: Annotated[date, PropertyInfo(format="iso8601")] class DatetimeModel(BaseModel): foo: datetime class DateModel(BaseModel): foo: Optional[date] @parametrize @pytest.mark.asyncio async def test_iso8601_format(use_async: bool) -> None: dt = datetime.fromisoformat("2023-02-23T14:16:36.337692+00:00") tz = "+00:00" if PYDANTIC_V1 else "Z" assert await transform({"foo": dt}, DatetimeDict, use_async) == {"foo": "2023-02-23T14:16:36.337692+00:00"} # type: ignore[comparison-overlap] assert await transform(DatetimeModel(foo=dt), Any, use_async) == {"foo": "2023-02-23T14:16:36.337692" + tz} # type: ignore[comparison-overlap] dt = dt.replace(tzinfo=None) assert await transform({"foo": dt}, DatetimeDict, use_async) == {"foo": "2023-02-23T14:16:36.337692"} # type: ignore[comparison-overlap] assert await transform(DatetimeModel(foo=dt), Any, use_async) == {"foo": "2023-02-23T14:16:36.337692"} # type: ignore[comparison-overlap] assert await transform({"foo": None}, DateDict, use_async) == {"foo": None} # type: ignore[comparison-overlap] assert await transform(DateModel(foo=None), Any, use_async) == {"foo": None} # type: ignore assert await transform({"foo": date.fromisoformat("2023-02-23")}, DateDict, use_async) == {"foo": "2023-02-23"} # type: ignore[comparison-overlap] assert await transform(DateModel(foo=date.fromisoformat("2023-02-23")), DateDict, use_async) == { "foo": "2023-02-23" } # type: ignore[comparison-overlap] @parametrize @pytest.mark.asyncio async def test_optional_iso8601_format(use_async: bool) -> None: dt = datetime.fromisoformat("2023-02-23T14:16:36.337692+00:00") assert await transform({"bar": dt}, DatetimeDict, use_async) == {"bar": "2023-02-23T14:16:36.337692+00:00"} # type: ignore[comparison-overlap] assert await transform({"bar": None}, DatetimeDict, use_async) == {"bar": None} @parametrize @pytest.mark.asyncio async def test_required_iso8601_format(use_async: bool) -> None: dt = datetime.fromisoformat("2023-02-23T14:16:36.337692+00:00") assert await transform({"required": dt}, DatetimeDict, use_async) == { "required": "2023-02-23T14:16:36.337692+00:00" } # type: ignore[comparison-overlap] assert await transform({"required": None}, DatetimeDict, use_async) == {"required": None} @parametrize @pytest.mark.asyncio async def test_union_datetime(use_async: bool) -> None: dt = datetime.fromisoformat("2023-02-23T14:16:36.337692+00:00") assert await transform({"union": dt}, DatetimeDict, use_async) == { # type: ignore[comparison-overlap] "union": "2023-02-23T14:16:36.337692+00:00" } assert await transform({"union": "foo"}, DatetimeDict, use_async) == {"union": "foo"} @parametrize @pytest.mark.asyncio async def test_nested_list_iso6801_format(use_async: bool) -> None: dt1 = datetime.fromisoformat("2023-02-23T14:16:36.337692+00:00") dt2 = parse_datetime("2022-01-15T06:34:23Z") assert await transform({"list_": [dt1, dt2]}, DatetimeDict, use_async) == { # type: ignore[comparison-overlap] "list_": ["2023-02-23T14:16:36.337692+00:00", "2022-01-15T06:34:23+00:00"] } @parametrize @pytest.mark.asyncio async def test_datetime_custom_format(use_async: bool) -> None: dt = parse_datetime("2022-01-15T06:34:23Z") result = await transform(dt, Annotated[datetime, PropertyInfo(format="custom", format_template="%H")], use_async) assert result == "06" # type: ignore[comparison-overlap] class DateDictWithRequiredAlias(TypedDict, total=False): required_prop: Required[Annotated[date, PropertyInfo(format="iso8601", alias="prop")]] @parametrize @pytest.mark.asyncio async def test_datetime_with_alias(use_async: bool) -> None: assert await transform({"required_prop": None}, DateDictWithRequiredAlias, use_async) == {"prop": None} # type: ignore[comparison-overlap] assert await transform( {"required_prop": date.fromisoformat("2023-02-23")}, DateDictWithRequiredAlias, use_async ) == {"prop": "2023-02-23"} # type: ignore[comparison-overlap] class MyModel(BaseModel): foo: str @parametrize @pytest.mark.asyncio async def test_pydantic_model_to_dictionary(use_async: bool) -> None: assert cast(Any, await transform(MyModel(foo="hi!"), Any, use_async)) == {"foo": "hi!"} assert cast(Any, await transform(MyModel.construct(foo="hi!"), Any, use_async)) == {"foo": "hi!"} @parametrize @pytest.mark.asyncio async def test_pydantic_empty_model(use_async: bool) -> None: assert cast(Any, await transform(MyModel.construct(), Any, use_async)) == {} @parametrize @pytest.mark.asyncio async def test_pydantic_unknown_field(use_async: bool) -> None: assert cast(Any, await transform(MyModel.construct(my_untyped_field=True), Any, use_async)) == { "my_untyped_field": True } @parametrize @pytest.mark.asyncio async def test_pydantic_mismatched_types(use_async: bool) -> None: model = MyModel.construct(foo=True) if PYDANTIC_V1: params = await transform(model, Any, use_async) else: with pytest.warns(UserWarning): params = await transform(model, Any, use_async) assert cast(Any, params) == {"foo": True} @parametrize @pytest.mark.asyncio async def test_pydantic_mismatched_object_type(use_async: bool) -> None: model = MyModel.construct(foo=MyModel.construct(hello="world")) if PYDANTIC_V1: params = await transform(model, Any, use_async) else: with pytest.warns(UserWarning): params = await transform(model, Any, use_async) assert cast(Any, params) == {"foo": {"hello": "world"}} class ModelNestedObjects(BaseModel): nested: MyModel @parametrize @pytest.mark.asyncio async def test_pydantic_nested_objects(use_async: bool) -> None: model = ModelNestedObjects.construct(nested={"foo": "stainless"}) assert isinstance(model.nested, MyModel) assert cast(Any, await transform(model, Any, use_async)) == {"nested": {"foo": "stainless"}} class ModelWithDefaultField(BaseModel): foo: str with_none_default: Union[str, None] = None with_str_default: str = "foo" @parametrize @pytest.mark.asyncio async def test_pydantic_default_field(use_async: bool) -> None: # should be excluded when defaults are used model = ModelWithDefaultField.construct() assert model.with_none_default is None assert model.with_str_default == "foo" assert cast(Any, await transform(model, Any, use_async)) == {} # should be included when the default value is explicitly given model = ModelWithDefaultField.construct(with_none_default=None, with_str_default="foo") assert model.with_none_default is None assert model.with_str_default == "foo" assert cast(Any, await transform(model, Any, use_async)) == {"with_none_default": None, "with_str_default": "foo"} # should be included when a non-default value is explicitly given model = ModelWithDefaultField.construct(with_none_default="bar", with_str_default="baz") assert model.with_none_default == "bar" assert model.with_str_default == "baz" assert cast(Any, await transform(model, Any, use_async)) == {"with_none_default": "bar", "with_str_default": "baz"} class TypedDictIterableUnion(TypedDict): foo: Annotated[Union[Bar8, Iterable[Baz8]], PropertyInfo(alias="FOO")] class Bar8(TypedDict): foo_bar: Annotated[str, PropertyInfo(alias="fooBar")] class Baz8(TypedDict): foo_baz: Annotated[str, PropertyInfo(alias="fooBaz")] @parametrize @pytest.mark.asyncio async def test_iterable_of_dictionaries(use_async: bool) -> None: assert await transform({"foo": [{"foo_baz": "bar"}]}, TypedDictIterableUnion, use_async) == { "FOO": [{"fooBaz": "bar"}] } assert cast(Any, await transform({"foo": ({"foo_baz": "bar"},)}, TypedDictIterableUnion, use_async)) == { "FOO": [{"fooBaz": "bar"}] } def my_iter() -> Iterable[Baz8]: yield {"foo_baz": "hello"} yield {"foo_baz": "world"} assert await transform({"foo": my_iter()}, TypedDictIterableUnion, use_async) == { "FOO": [{"fooBaz": "hello"}, {"fooBaz": "world"}] } @parametrize @pytest.mark.asyncio async def test_dictionary_items(use_async: bool) -> None: class DictItems(TypedDict): foo_baz: Annotated[str, PropertyInfo(alias="fooBaz")] assert await transform({"foo": {"foo_baz": "bar"}}, Dict[str, DictItems], use_async) == {"foo": {"fooBaz": "bar"}} class TypedDictIterableUnionStr(TypedDict): foo: Annotated[Union[str, Iterable[Baz8]], PropertyInfo(alias="FOO")] @parametrize @pytest.mark.asyncio async def test_iterable_union_str(use_async: bool) -> None: assert await transform({"foo": "bar"}, TypedDictIterableUnionStr, use_async) == {"FOO": "bar"} assert cast(Any, await transform(iter([{"foo_baz": "bar"}]), Union[str, Iterable[Baz8]], use_async)) == [ {"fooBaz": "bar"} ] class TypedDictBase64Input(TypedDict): foo: Annotated[Union[str, Base64FileInput], PropertyInfo(format="base64")] @parametrize @pytest.mark.asyncio async def test_base64_file_input(use_async: bool) -> None: # strings are left as-is assert await transform({"foo": "bar"}, TypedDictBase64Input, use_async) == {"foo": "bar"} # pathlib.Path is automatically converted to base64 assert await transform({"foo": SAMPLE_FILE_PATH}, TypedDictBase64Input, use_async) == { "foo": "SGVsbG8sIHdvcmxkIQo=" } # type: ignore[comparison-overlap] # io instances are automatically converted to base64 assert await transform({"foo": io.StringIO("Hello, world!")}, TypedDictBase64Input, use_async) == { "foo": "SGVsbG8sIHdvcmxkIQ==" } # type: ignore[comparison-overlap] assert await transform({"foo": io.BytesIO(b"Hello, world!")}, TypedDictBase64Input, use_async) == { "foo": "SGVsbG8sIHdvcmxkIQ==" } # type: ignore[comparison-overlap] @parametrize @pytest.mark.asyncio async def test_transform_skipping(use_async: bool) -> None: # lists of ints are left as-is data = [1, 2, 3] assert await transform(data, List[int], use_async) is data # iterables of ints are converted to a list data = iter([1, 2, 3]) assert await transform(data, Iterable[int], use_async) == [1, 2, 3] @parametrize @pytest.mark.asyncio async def test_strips_notgiven(use_async: bool) -> None: assert await transform({"foo_bar": "bar"}, Foo1, use_async) == {"fooBar": "bar"} assert await transform({"foo_bar": not_given}, Foo1, use_async) == {} @parametrize @pytest.mark.asyncio async def test_strips_omit(use_async: bool) -> None: assert await transform({"foo_bar": "bar"}, Foo1, use_async) == {"fooBar": "bar"} assert await transform({"foo_bar": omit}, Foo1, use_async) == {} anthropic-sdk-python-0.69.0/tests/test_utils/000077500000000000000000000000001506653454500212515ustar00rootroot00000000000000anthropic-sdk-python-0.69.0/tests/test_utils/test_datetime_parse.py000066400000000000000000000125211506653454500256510ustar00rootroot00000000000000""" Copied from https://github.com/pydantic/pydantic/blob/v1.10.22/tests/test_datetime_parse.py with modifications so it works without pydantic v1 imports. """ from typing import Type, Union from datetime import date, datetime, timezone, timedelta import pytest from anthropic._utils import parse_date, parse_datetime def create_tz(minutes: int) -> timezone: return timezone(timedelta(minutes=minutes)) @pytest.mark.parametrize( "value,result", [ # Valid inputs ("1494012444.883309", date(2017, 5, 5)), (b"1494012444.883309", date(2017, 5, 5)), (1_494_012_444.883_309, date(2017, 5, 5)), ("1494012444", date(2017, 5, 5)), (1_494_012_444, date(2017, 5, 5)), (0, date(1970, 1, 1)), ("2012-04-23", date(2012, 4, 23)), (b"2012-04-23", date(2012, 4, 23)), ("2012-4-9", date(2012, 4, 9)), (date(2012, 4, 9), date(2012, 4, 9)), (datetime(2012, 4, 9, 12, 15), date(2012, 4, 9)), # Invalid inputs ("x20120423", ValueError), ("2012-04-56", ValueError), (19_999_999_999, date(2603, 10, 11)), # just before watershed (20_000_000_001, date(1970, 8, 20)), # just after watershed (1_549_316_052, date(2019, 2, 4)), # nowish in s (1_549_316_052_104, date(2019, 2, 4)), # nowish in ms (1_549_316_052_104_324, date(2019, 2, 4)), # nowish in μs (1_549_316_052_104_324_096, date(2019, 2, 4)), # nowish in ns ("infinity", date(9999, 12, 31)), ("inf", date(9999, 12, 31)), (float("inf"), date(9999, 12, 31)), ("infinity ", date(9999, 12, 31)), (int("1" + "0" * 100), date(9999, 12, 31)), (1e1000, date(9999, 12, 31)), ("-infinity", date(1, 1, 1)), ("-inf", date(1, 1, 1)), ("nan", ValueError), ], ) def test_date_parsing(value: Union[str, bytes, int, float], result: Union[date, Type[Exception]]) -> None: if type(result) == type and issubclass(result, Exception): # pyright: ignore[reportUnnecessaryIsInstance] with pytest.raises(result): parse_date(value) else: assert parse_date(value) == result @pytest.mark.parametrize( "value,result", [ # Valid inputs # values in seconds ("1494012444.883309", datetime(2017, 5, 5, 19, 27, 24, 883_309, tzinfo=timezone.utc)), (1_494_012_444.883_309, datetime(2017, 5, 5, 19, 27, 24, 883_309, tzinfo=timezone.utc)), ("1494012444", datetime(2017, 5, 5, 19, 27, 24, tzinfo=timezone.utc)), (b"1494012444", datetime(2017, 5, 5, 19, 27, 24, tzinfo=timezone.utc)), (1_494_012_444, datetime(2017, 5, 5, 19, 27, 24, tzinfo=timezone.utc)), # values in ms ("1494012444000.883309", datetime(2017, 5, 5, 19, 27, 24, 883, tzinfo=timezone.utc)), ("-1494012444000.883309", datetime(1922, 8, 29, 4, 32, 35, 999117, tzinfo=timezone.utc)), (1_494_012_444_000, datetime(2017, 5, 5, 19, 27, 24, tzinfo=timezone.utc)), ("2012-04-23T09:15:00", datetime(2012, 4, 23, 9, 15)), ("2012-4-9 4:8:16", datetime(2012, 4, 9, 4, 8, 16)), ("2012-04-23T09:15:00Z", datetime(2012, 4, 23, 9, 15, 0, 0, timezone.utc)), ("2012-4-9 4:8:16-0320", datetime(2012, 4, 9, 4, 8, 16, 0, create_tz(-200))), ("2012-04-23T10:20:30.400+02:30", datetime(2012, 4, 23, 10, 20, 30, 400_000, create_tz(150))), ("2012-04-23T10:20:30.400+02", datetime(2012, 4, 23, 10, 20, 30, 400_000, create_tz(120))), ("2012-04-23T10:20:30.400-02", datetime(2012, 4, 23, 10, 20, 30, 400_000, create_tz(-120))), (b"2012-04-23T10:20:30.400-02", datetime(2012, 4, 23, 10, 20, 30, 400_000, create_tz(-120))), (datetime(2017, 5, 5), datetime(2017, 5, 5)), (0, datetime(1970, 1, 1, 0, 0, 0, tzinfo=timezone.utc)), # Invalid inputs ("x20120423091500", ValueError), ("2012-04-56T09:15:90", ValueError), ("2012-04-23T11:05:00-25:00", ValueError), (19_999_999_999, datetime(2603, 10, 11, 11, 33, 19, tzinfo=timezone.utc)), # just before watershed (20_000_000_001, datetime(1970, 8, 20, 11, 33, 20, 1000, tzinfo=timezone.utc)), # just after watershed (1_549_316_052, datetime(2019, 2, 4, 21, 34, 12, 0, tzinfo=timezone.utc)), # nowish in s (1_549_316_052_104, datetime(2019, 2, 4, 21, 34, 12, 104_000, tzinfo=timezone.utc)), # nowish in ms (1_549_316_052_104_324, datetime(2019, 2, 4, 21, 34, 12, 104_324, tzinfo=timezone.utc)), # nowish in μs (1_549_316_052_104_324_096, datetime(2019, 2, 4, 21, 34, 12, 104_324, tzinfo=timezone.utc)), # nowish in ns ("infinity", datetime(9999, 12, 31, 23, 59, 59, 999999)), ("inf", datetime(9999, 12, 31, 23, 59, 59, 999999)), ("inf ", datetime(9999, 12, 31, 23, 59, 59, 999999)), (1e50, datetime(9999, 12, 31, 23, 59, 59, 999999)), (float("inf"), datetime(9999, 12, 31, 23, 59, 59, 999999)), ("-infinity", datetime(1, 1, 1, 0, 0)), ("-inf", datetime(1, 1, 1, 0, 0)), ("nan", ValueError), ], ) def test_datetime_parsing(value: Union[str, bytes, int, float], result: Union[datetime, Type[Exception]]) -> None: if type(result) == type and issubclass(result, Exception): # pyright: ignore[reportUnnecessaryIsInstance] with pytest.raises(result): parse_datetime(value) else: assert parse_datetime(value) == result anthropic-sdk-python-0.69.0/tests/test_utils/test_proxy.py000066400000000000000000000017571506653454500240550ustar00rootroot00000000000000import operator from typing import Any from typing_extensions import override from anthropic._utils import LazyProxy class RecursiveLazyProxy(LazyProxy[Any]): @override def __load__(self) -> Any: return self def __call__(self, *_args: Any, **_kwds: Any) -> Any: raise RuntimeError("This should never be called!") def test_recursive_proxy() -> None: proxy = RecursiveLazyProxy() assert repr(proxy) == "RecursiveLazyProxy" assert str(proxy) == "RecursiveLazyProxy" assert dir(proxy) == [] assert type(proxy).__name__ == "RecursiveLazyProxy" assert type(operator.attrgetter("name.foo.bar.baz")(proxy)).__name__ == "RecursiveLazyProxy" def test_isinstance_does_not_error() -> None: class AlwaysErrorProxy(LazyProxy[Any]): @override def __load__(self) -> Any: raise RuntimeError("Mocking missing dependency") proxy = AlwaysErrorProxy() assert not isinstance(proxy, dict) assert isinstance(proxy, LazyProxy) anthropic-sdk-python-0.69.0/tests/test_utils/test_typing.py000066400000000000000000000046341506653454500242030ustar00rootroot00000000000000from __future__ import annotations from typing import Generic, TypeVar, cast from anthropic._utils import extract_type_var_from_base _T = TypeVar("_T") _T2 = TypeVar("_T2") _T3 = TypeVar("_T3") class BaseGeneric(Generic[_T]): ... class SubclassGeneric(BaseGeneric[_T]): ... class BaseGenericMultipleTypeArgs(Generic[_T, _T2, _T3]): ... class SubclassGenericMultipleTypeArgs(BaseGenericMultipleTypeArgs[_T, _T2, _T3]): ... class SubclassDifferentOrderGenericMultipleTypeArgs(BaseGenericMultipleTypeArgs[_T2, _T, _T3]): ... def test_extract_type_var() -> None: assert ( extract_type_var_from_base( BaseGeneric[int], index=0, generic_bases=cast("tuple[type, ...]", (BaseGeneric,)), ) == int ) def test_extract_type_var_generic_subclass() -> None: assert ( extract_type_var_from_base( SubclassGeneric[int], index=0, generic_bases=cast("tuple[type, ...]", (BaseGeneric,)), ) == int ) def test_extract_type_var_multiple() -> None: typ = BaseGenericMultipleTypeArgs[int, str, None] generic_bases = cast("tuple[type, ...]", (BaseGenericMultipleTypeArgs,)) assert extract_type_var_from_base(typ, index=0, generic_bases=generic_bases) == int assert extract_type_var_from_base(typ, index=1, generic_bases=generic_bases) == str assert extract_type_var_from_base(typ, index=2, generic_bases=generic_bases) == type(None) def test_extract_type_var_generic_subclass_multiple() -> None: typ = SubclassGenericMultipleTypeArgs[int, str, None] generic_bases = cast("tuple[type, ...]", (BaseGenericMultipleTypeArgs,)) assert extract_type_var_from_base(typ, index=0, generic_bases=generic_bases) == int assert extract_type_var_from_base(typ, index=1, generic_bases=generic_bases) == str assert extract_type_var_from_base(typ, index=2, generic_bases=generic_bases) == type(None) def test_extract_type_var_generic_subclass_different_ordering_multiple() -> None: typ = SubclassDifferentOrderGenericMultipleTypeArgs[int, str, None] generic_bases = cast("tuple[type, ...]", (BaseGenericMultipleTypeArgs,)) assert extract_type_var_from_base(typ, index=0, generic_bases=generic_bases) == int assert extract_type_var_from_base(typ, index=1, generic_bases=generic_bases) == str assert extract_type_var_from_base(typ, index=2, generic_bases=generic_bases) == type(None) anthropic-sdk-python-0.69.0/tests/utils.py000066400000000000000000000115731506653454500205730ustar00rootroot00000000000000from __future__ import annotations import os import inspect import traceback import contextlib from typing import Any, TypeVar, Iterator, Sequence, cast from datetime import date, datetime from typing_extensions import Literal, get_args, get_origin, assert_type from anthropic._types import Omit, NoneType from anthropic._utils import ( is_dict, is_list, is_list_type, is_union_type, extract_type_arg, is_sequence_type, is_annotated_type, is_type_alias_type, ) from anthropic._compat import PYDANTIC_V1, field_outer_type, get_model_fields from anthropic._models import BaseModel BaseModelT = TypeVar("BaseModelT", bound=BaseModel) def assert_matches_model(model: type[BaseModelT], value: BaseModelT, *, path: list[str]) -> bool: for name, field in get_model_fields(model).items(): field_value = getattr(value, name) if PYDANTIC_V1: # in v1 nullability was structured differently # https://docs.pydantic.dev/2.0/migration/#required-optional-and-nullable-fields allow_none = getattr(field, "allow_none", False) else: allow_none = False assert_matches_type( field_outer_type(field), field_value, path=[*path, name], allow_none=allow_none, ) return True # Note: the `path` argument is only used to improve error messages when `--showlocals` is used def assert_matches_type( type_: Any, value: object, *, path: list[str], allow_none: bool = False, ) -> None: if is_type_alias_type(type_): type_ = type_.__value__ # unwrap `Annotated[T, ...]` -> `T` if is_annotated_type(type_): type_ = extract_type_arg(type_, 0) if allow_none and value is None: return if type_ is None or type_ is NoneType: assert value is None return origin = get_origin(type_) or type_ if is_list_type(type_): return _assert_list_type(type_, value) if is_sequence_type(type_): assert isinstance(value, Sequence) inner_type = get_args(type_)[0] for entry in value: # type: ignore assert_type(inner_type, entry) # type: ignore return if origin == str: assert isinstance(value, str) elif origin == int: assert isinstance(value, int) elif origin == bool: assert isinstance(value, bool) elif origin == float: assert isinstance(value, float) elif origin == bytes: assert isinstance(value, bytes) elif origin == datetime: assert isinstance(value, datetime) elif origin == date: assert isinstance(value, date) elif origin == object: # nothing to do here, the expected type is unknown pass elif origin == Literal: assert value in get_args(type_) elif origin == dict: assert is_dict(value) args = get_args(type_) key_type = args[0] items_type = args[1] for key, item in value.items(): assert_matches_type(key_type, key, path=[*path, ""]) assert_matches_type(items_type, item, path=[*path, ""]) elif is_union_type(type_): variants = get_args(type_) try: none_index = variants.index(type(None)) except ValueError: pass else: # special case Optional[T] for better error messages if len(variants) == 2: if value is None: # valid return return assert_matches_type(type_=variants[not none_index], value=value, path=path) for i, variant in enumerate(variants): try: assert_matches_type(variant, value, path=[*path, f"variant {i}"]) return except AssertionError: traceback.print_exc() continue raise AssertionError("Did not match any variants") elif issubclass(origin, BaseModel): assert isinstance(value, type_) assert assert_matches_model(type_, cast(Any, value), path=path) elif inspect.isclass(origin) and origin.__name__ == "HttpxBinaryResponseContent": assert value.__class__.__name__ == "HttpxBinaryResponseContent" else: assert None, f"Unhandled field type: {type_}" def _assert_list_type(type_: type[object], value: object) -> None: assert is_list(value) inner_type = get_args(type_)[0] for entry in value: assert_type(inner_type, entry) # type: ignore @contextlib.contextmanager def update_env(**new_env: str | Omit) -> Iterator[None]: old = os.environ.copy() try: for name, value in new_env.items(): if isinstance(value, Omit): os.environ.pop(name, None) else: os.environ[name] = value yield None finally: os.environ.clear() os.environ.update(old) anthropic-sdk-python-0.69.0/tools.md000066400000000000000000000042131506653454500173720ustar00rootroot00000000000000# Tools helpers To define a tool, you can use the `@beta_tool` decorator on any python function like so: ```python from anthropic import beta_tool @beta_tool def sum(left: int, right: int) -> str: """Adds two integers together. Args: left (int): The first integer to add. right (int): The second integer to add. Returns: int: The sum of left and right integers. """ return str(left + right) ``` > [!TIP] > If you're using the async client, replace `@beta_tool` with `@beta_async_tool` and define the function with `async def`. The `@beta_tool` decorator will inspect the function arguments and the docstring to extract a json schema representation of the given function, in this case it'll be turned into: ```json { "name": "sum", "description": "Adds two integers together.", "input_schema": { "additionalProperties": false, "properties": { "left": { "description": "The first integer to add.", "title": "Left", "type": "integer" }, "right": { "description": "The second integer to add.", "title": "Right", "type": "integer" } }, "required": ["left", "right"], "type": "object" } } ``` If you want to implement calling the tool yourself, you can then pass the to the API like so: ```python message = client.beta.messages.create( tools=[get_weather.to_dict()], # ... max_tokens=1024, model="claude-sonnet-4-5-20250929", messages=[{"role": "user", "content": "What is 2 + 2?"}], ) ``` or you can use our [tool runner](#tool-runner)! ## Tool runner We provide a `client.beta.messages.tool_runner()` method that can automatically call tools defined with `@beta_tool()`. This method returns a `BetaToolRunner` class that is an iterator where each iteration yields a new `BetaMessage` instance from an API call, iteration will stop when there no tool call content blocks. ```py runner = client.beta.messages.tool_runner( max_tokens=1024, model="claude-sonnet-4-5-20250929", tools=[sum], messages=[{"role": "user", "content": "What is 9 + 10?"}], ) for message in runner: rich.print(message) ``` anthropic-sdk-python-0.69.0/uv.lock000066400000000000000000023236601506653454500172300ustar00rootroot00000000000000version = 1 revision = 3 requires-python = ">=3.8" resolution-markers = [ "python_full_version >= '3.10'", "python_full_version == '3.9.*'", "python_full_version < '3.9'", ] conflicts = [[ { package = "anthropic", group = "pydantic-v1" }, { package = "anthropic", group = "pydantic-v2" }, ]] [[package]] name = "aiohappyeyeballs" version = "2.4.4" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] sdist = { url = "https://files.pythonhosted.org/packages/7f/55/e4373e888fdacb15563ef6fa9fa8c8252476ea071e96fb46defac9f18bf2/aiohappyeyeballs-2.4.4.tar.gz", hash = "sha256:5fdd7d87889c63183afc18ce9271f9b0a7d32c2303e394468dd45d514a757745", size = 21977, upload-time = "2024-11-30T18:44:00.701Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b9/74/fbb6559de3607b3300b9be3cc64e97548d55678e44623db17820dbd20002/aiohappyeyeballs-2.4.4-py3-none-any.whl", hash = "sha256:a980909d50efcd44795c4afeca523296716d50cd756ddca6af8c65b996e27de8", size = 14756, upload-time = "2024-11-30T18:43:39.849Z" }, ] [[package]] name = "aiohappyeyeballs" version = "2.6.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.10'", "python_full_version == '3.9.*'", ] 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.10.11" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] dependencies = [ { name = "aiohappyeyeballs", version = "2.4.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "aiosignal", version = "1.3.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "async-timeout", marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "attrs", marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "frozenlist", version = "1.5.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "multidict", version = "6.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "yarl", version = "1.15.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/25/a8/8e2ba36c6e3278d62e0c88aa42bb92ddbef092ac363b390dab4421da5cf5/aiohttp-3.10.11.tar.gz", hash = "sha256:9dc2b8f3dcab2e39e0fa309c8da50c3b55e6f34ab25f1a71d3288f24924d33a7", size = 7551886, upload-time = "2024-11-13T16:40:33.335Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/11/c7/575f9e82d7ef13cb1b45b9db8a5b8fadb35107fb12e33809356ae0155223/aiohttp-3.10.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5077b1a5f40ffa3ba1f40d537d3bec4383988ee51fbba6b74aa8fb1bc466599e", size = 588218, upload-time = "2024-11-13T16:36:38.461Z" }, { url = "https://files.pythonhosted.org/packages/12/7b/a800dadbd9a47b7f921bfddcd531371371f39b9cd05786c3638bfe2e1175/aiohttp-3.10.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8d6a14a4d93b5b3c2891fca94fa9d41b2322a68194422bef0dd5ec1e57d7d298", size = 400815, upload-time = "2024-11-13T16:36:40.547Z" }, { url = "https://files.pythonhosted.org/packages/cb/28/7dbd53ab10b0ded397feed914880f39ce075bd39393b8dfc322909754a0a/aiohttp-3.10.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ffbfde2443696345e23a3c597049b1dd43049bb65337837574205e7368472177", size = 392099, upload-time = "2024-11-13T16:36:43.918Z" }, { url = "https://files.pythonhosted.org/packages/6a/2e/c6390f49e67911711c2229740e261c501685fe7201f7f918d6ff2fd1cfb0/aiohttp-3.10.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20b3d9e416774d41813bc02fdc0663379c01817b0874b932b81c7f777f67b217", size = 1224854, upload-time = "2024-11-13T16:36:46.473Z" }, { url = "https://files.pythonhosted.org/packages/69/68/c96afae129201bff4edbece52b3e1abf3a8af57529a42700669458b00b9f/aiohttp-3.10.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2b943011b45ee6bf74b22245c6faab736363678e910504dd7531a58c76c9015a", size = 1259641, upload-time = "2024-11-13T16:36:48.28Z" }, { url = "https://files.pythonhosted.org/packages/63/89/bedd01456442747946114a8c2f30ff1b23d3b2ea0c03709f854c4f354a5a/aiohttp-3.10.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48bc1d924490f0d0b3658fe5c4b081a4d56ebb58af80a6729d4bd13ea569797a", size = 1295412, upload-time = "2024-11-13T16:36:50.286Z" }, { url = "https://files.pythonhosted.org/packages/9b/4d/942198e2939efe7bfa484781590f082135e9931b8bcafb4bba62cf2d8f2f/aiohttp-3.10.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e12eb3f4b1f72aaaf6acd27d045753b18101524f72ae071ae1c91c1cd44ef115", size = 1218311, upload-time = "2024-11-13T16:36:53.721Z" }, { url = "https://files.pythonhosted.org/packages/a3/5b/8127022912f1fa72dfc39cf37c36f83e0b56afc3b93594b1cf377b6e4ffc/aiohttp-3.10.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f14ebc419a568c2eff3c1ed35f634435c24ead2fe19c07426af41e7adb68713a", size = 1189448, upload-time = "2024-11-13T16:36:55.844Z" }, { url = "https://files.pythonhosted.org/packages/af/12/752878033c8feab3362c0890a4d24e9895921729a53491f6f6fad64d3287/aiohttp-3.10.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:72b191cdf35a518bfc7ca87d770d30941decc5aaf897ec8b484eb5cc8c7706f3", size = 1186484, upload-time = "2024-11-13T16:36:58.472Z" }, { url = "https://files.pythonhosted.org/packages/61/24/1d91c304fca47d5e5002ca23abab9b2196ac79d5c531258e048195b435b2/aiohttp-3.10.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5ab2328a61fdc86424ee540d0aeb8b73bbcad7351fb7cf7a6546fc0bcffa0038", size = 1183864, upload-time = "2024-11-13T16:37:00.737Z" }, { url = "https://files.pythonhosted.org/packages/c1/70/022d28b898314dac4cb5dd52ead2a372563c8590b1eaab9c5ed017eefb1e/aiohttp-3.10.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:aa93063d4af05c49276cf14e419550a3f45258b6b9d1f16403e777f1addf4519", size = 1241460, upload-time = "2024-11-13T16:37:03.175Z" }, { url = "https://files.pythonhosted.org/packages/c3/15/2b43853330f82acf180602de0f68be62a2838d25d03d2ed40fecbe82479e/aiohttp-3.10.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:30283f9d0ce420363c24c5c2421e71a738a2155f10adbb1a11a4d4d6d2715cfc", size = 1258521, upload-time = "2024-11-13T16:37:06.013Z" }, { url = "https://files.pythonhosted.org/packages/28/38/9ef2076cb06dcc155e7f02275f5da403a3e7c9327b6b075e999f0eb73613/aiohttp-3.10.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e5358addc8044ee49143c546d2182c15b4ac3a60be01c3209374ace05af5733d", size = 1207329, upload-time = "2024-11-13T16:37:08.091Z" }, { url = "https://files.pythonhosted.org/packages/c2/5f/c5329d67a2c83d8ae17a84e11dec14da5773520913bfc191caaf4cd57e50/aiohttp-3.10.11-cp310-cp310-win32.whl", hash = "sha256:e1ffa713d3ea7cdcd4aea9cddccab41edf6882fa9552940344c44e59652e1120", size = 363835, upload-time = "2024-11-13T16:37:10.017Z" }, { url = "https://files.pythonhosted.org/packages/0f/c6/ca5d70eea2fdbe283dbc1e7d30649a1a5371b2a2a9150db192446f645789/aiohttp-3.10.11-cp310-cp310-win_amd64.whl", hash = "sha256:778cbd01f18ff78b5dd23c77eb82987ee4ba23408cbed233009fd570dda7e674", size = 382169, upload-time = "2024-11-13T16:37:12.603Z" }, { url = "https://files.pythonhosted.org/packages/73/96/221ec59bc38395a6c205cbe8bf72c114ce92694b58abc8c3c6b7250efa7f/aiohttp-3.10.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:80ff08556c7f59a7972b1e8919f62e9c069c33566a6d28586771711e0eea4f07", size = 587742, upload-time = "2024-11-13T16:37:14.469Z" }, { url = "https://files.pythonhosted.org/packages/24/17/4e606c969b19de5c31a09b946bd4c37e30c5288ca91d4790aa915518846e/aiohttp-3.10.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c8f96e9ee19f04c4914e4e7a42a60861066d3e1abf05c726f38d9d0a466e695", size = 400357, upload-time = "2024-11-13T16:37:16.482Z" }, { url = "https://files.pythonhosted.org/packages/a2/e5/433f59b87ba69736e446824710dd7f26fcd05b24c6647cb1e76554ea5d02/aiohttp-3.10.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fb8601394d537da9221947b5d6e62b064c9a43e88a1ecd7414d21a1a6fba9c24", size = 392099, upload-time = "2024-11-13T16:37:20.013Z" }, { url = "https://files.pythonhosted.org/packages/d2/a3/3be340f5063970bb9e47f065ee8151edab639d9c2dce0d9605a325ab035d/aiohttp-3.10.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ea224cf7bc2d8856d6971cea73b1d50c9c51d36971faf1abc169a0d5f85a382", size = 1300367, upload-time = "2024-11-13T16:37:22.645Z" }, { url = "https://files.pythonhosted.org/packages/ba/7d/a3043918466cbee9429792ebe795f92f70eeb40aee4ccbca14c38ee8fa4d/aiohttp-3.10.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db9503f79e12d5d80b3efd4d01312853565c05367493379df76d2674af881caa", size = 1339448, upload-time = "2024-11-13T16:37:24.834Z" }, { url = "https://files.pythonhosted.org/packages/2c/60/192b378bd9d1ae67716b71ae63c3e97c48b134aad7675915a10853a0b7de/aiohttp-3.10.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0f449a50cc33f0384f633894d8d3cd020e3ccef81879c6e6245c3c375c448625", size = 1374875, upload-time = "2024-11-13T16:37:26.799Z" }, { url = "https://files.pythonhosted.org/packages/e0/d7/cd58bd17f5277d9cc32ecdbb0481ca02c52fc066412de413aa01268dc9b4/aiohttp-3.10.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82052be3e6d9e0c123499127782a01a2b224b8af8c62ab46b3f6197035ad94e9", size = 1285626, upload-time = "2024-11-13T16:37:29.02Z" }, { url = "https://files.pythonhosted.org/packages/bb/b2/da4953643b7dcdcd29cc99f98209f3653bf02023d95ce8a8fd57ffba0f15/aiohttp-3.10.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:20063c7acf1eec550c8eb098deb5ed9e1bb0521613b03bb93644b810986027ac", size = 1246120, upload-time = "2024-11-13T16:37:31.268Z" }, { url = "https://files.pythonhosted.org/packages/6c/22/1217b3c773055f0cb172e3b7108274a74c0fe9900c716362727303931cbb/aiohttp-3.10.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:489cced07a4c11488f47aab1f00d0c572506883f877af100a38f1fedaa884c3a", size = 1265177, upload-time = "2024-11-13T16:37:33.348Z" }, { url = "https://files.pythonhosted.org/packages/63/5e/3827ad7e61544ed1e73e4fdea7bb87ea35ac59a362d7eb301feb5e859780/aiohttp-3.10.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ea9b3bab329aeaa603ed3bf605f1e2a6f36496ad7e0e1aa42025f368ee2dc07b", size = 1257238, upload-time = "2024-11-13T16:37:35.753Z" }, { url = "https://files.pythonhosted.org/packages/53/31/951f78751d403da6086b662760e6e8b08201b0dcf5357969f48261b4d0e1/aiohttp-3.10.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ca117819d8ad113413016cb29774b3f6d99ad23c220069789fc050267b786c16", size = 1315944, upload-time = "2024-11-13T16:37:38.317Z" }, { url = "https://files.pythonhosted.org/packages/0d/79/06ef7a2a69880649261818b135b245de5a4e89fed5a6987c8645428563fc/aiohttp-3.10.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2dfb612dcbe70fb7cdcf3499e8d483079b89749c857a8f6e80263b021745c730", size = 1332065, upload-time = "2024-11-13T16:37:40.725Z" }, { url = "https://files.pythonhosted.org/packages/10/39/a273857c2d0bbf2152a4201fbf776931c2dac74aa399c6683ed4c286d1d1/aiohttp-3.10.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9b615d3da0d60e7d53c62e22b4fd1c70f4ae5993a44687b011ea3a2e49051b8", size = 1291882, upload-time = "2024-11-13T16:37:43.209Z" }, { url = "https://files.pythonhosted.org/packages/49/39/7aa387f88403febc96e0494101763afaa14d342109329a01b413b2bac075/aiohttp-3.10.11-cp311-cp311-win32.whl", hash = "sha256:29103f9099b6068bbdf44d6a3d090e0a0b2be6d3c9f16a070dd9d0d910ec08f9", size = 363409, upload-time = "2024-11-13T16:37:45.143Z" }, { url = "https://files.pythonhosted.org/packages/6f/e9/8eb3dc095ce48499d867ad461d02f1491686b79ad92e4fad4df582f6be7b/aiohttp-3.10.11-cp311-cp311-win_amd64.whl", hash = "sha256:236b28ceb79532da85d59aa9b9bf873b364e27a0acb2ceaba475dc61cffb6f3f", size = 382644, upload-time = "2024-11-13T16:37:47.685Z" }, { url = "https://files.pythonhosted.org/packages/01/16/077057ef3bd684dbf9a8273a5299e182a8d07b4b252503712ff8b5364fd1/aiohttp-3.10.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:7480519f70e32bfb101d71fb9a1f330fbd291655a4c1c922232a48c458c52710", size = 584830, upload-time = "2024-11-13T16:37:49.608Z" }, { url = "https://files.pythonhosted.org/packages/2c/cf/348b93deb9597c61a51b6682e81f7c7d79290249e886022ef0705d858d90/aiohttp-3.10.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f65267266c9aeb2287a6622ee2bb39490292552f9fbf851baabc04c9f84e048d", size = 397090, upload-time = "2024-11-13T16:37:51.539Z" }, { url = "https://files.pythonhosted.org/packages/70/bf/903df5cd739dfaf5b827b3d8c9d68ff4fcea16a0ca1aeb948c9da30f56c8/aiohttp-3.10.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7400a93d629a0608dc1d6c55f1e3d6e07f7375745aaa8bd7f085571e4d1cee97", size = 392361, upload-time = "2024-11-13T16:37:53.586Z" }, { url = "https://files.pythonhosted.org/packages/fb/97/e4792675448a2ac5bd56f377a095233b805dd1315235c940c8ba5624e3cb/aiohttp-3.10.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f34b97e4b11b8d4eb2c3a4f975be626cc8af99ff479da7de49ac2c6d02d35725", size = 1309839, upload-time = "2024-11-13T16:37:55.68Z" }, { url = "https://files.pythonhosted.org/packages/96/d0/ba19b1260da6fbbda4d5b1550d8a53ba3518868f2c143d672aedfdbc6172/aiohttp-3.10.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e7b825da878464a252ccff2958838f9caa82f32a8dbc334eb9b34a026e2c636", size = 1348116, upload-time = "2024-11-13T16:37:58.232Z" }, { url = "https://files.pythonhosted.org/packages/b3/b9/15100ee7113a2638bfdc91aecc54641609a92a7ce4fe533ebeaa8d43ff93/aiohttp-3.10.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f9f92a344c50b9667827da308473005f34767b6a2a60d9acff56ae94f895f385", size = 1391402, upload-time = "2024-11-13T16:38:00.522Z" }, { url = "https://files.pythonhosted.org/packages/c5/36/831522618ac0dcd0b28f327afd18df7fb6bbf3eaf302f912a40e87714846/aiohttp-3.10.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc6f1ab987a27b83c5268a17218463c2ec08dbb754195113867a27b166cd6087", size = 1304239, upload-time = "2024-11-13T16:38:04.195Z" }, { url = "https://files.pythonhosted.org/packages/60/9f/b7230d0c48b076500ae57adb717aa0656432acd3d8febb1183dedfaa4e75/aiohttp-3.10.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1dc0f4ca54842173d03322793ebcf2c8cc2d34ae91cc762478e295d8e361e03f", size = 1256565, upload-time = "2024-11-13T16:38:07.218Z" }, { url = "https://files.pythonhosted.org/packages/63/c2/35c7b4699f4830b3b0a5c3d5619df16dca8052ae8b488e66065902d559f6/aiohttp-3.10.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7ce6a51469bfaacff146e59e7fb61c9c23006495d11cc24c514a455032bcfa03", size = 1269285, upload-time = "2024-11-13T16:38:09.396Z" }, { url = "https://files.pythonhosted.org/packages/51/48/bc20ea753909bdeb09f9065260aefa7453e3a57f6a51f56f5216adc1a5e7/aiohttp-3.10.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:aad3cd91d484d065ede16f3cf15408254e2469e3f613b241a1db552c5eb7ab7d", size = 1276716, upload-time = "2024-11-13T16:38:12.039Z" }, { url = "https://files.pythonhosted.org/packages/0c/7b/a8708616b3810f55ead66f8e189afa9474795760473aea734bbea536cd64/aiohttp-3.10.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f4df4b8ca97f658c880fb4b90b1d1ec528315d4030af1ec763247ebfd33d8b9a", size = 1315023, upload-time = "2024-11-13T16:38:15.155Z" }, { url = "https://files.pythonhosted.org/packages/2a/d6/dfe9134a921e05b01661a127a37b7d157db93428905450e32f9898eef27d/aiohttp-3.10.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:2e4e18a0a2d03531edbc06c366954e40a3f8d2a88d2b936bbe78a0c75a3aab3e", size = 1342735, upload-time = "2024-11-13T16:38:17.539Z" }, { url = "https://files.pythonhosted.org/packages/ca/1a/3bd7f18e3909eabd57e5d17ecdbf5ea4c5828d91341e3676a07de7c76312/aiohttp-3.10.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6ce66780fa1a20e45bc753cda2a149daa6dbf1561fc1289fa0c308391c7bc0a4", size = 1302618, upload-time = "2024-11-13T16:38:19.865Z" }, { url = "https://files.pythonhosted.org/packages/cf/51/d063133781cda48cfdd1e11fc8ef45ab3912b446feba41556385b3ae5087/aiohttp-3.10.11-cp312-cp312-win32.whl", hash = "sha256:a919c8957695ea4c0e7a3e8d16494e3477b86f33067478f43106921c2fef15bb", size = 360497, upload-time = "2024-11-13T16:38:21.996Z" }, { url = "https://files.pythonhosted.org/packages/55/4e/f29def9ed39826fe8f85955f2e42fe5cc0cbe3ebb53c97087f225368702e/aiohttp-3.10.11-cp312-cp312-win_amd64.whl", hash = "sha256:b5e29706e6389a2283a91611c91bf24f218962717c8f3b4e528ef529d112ee27", size = 380577, upload-time = "2024-11-13T16:38:24.247Z" }, { url = "https://files.pythonhosted.org/packages/1f/63/654c185dfe3cf5d4a0d35b6ee49ee6ca91922c694eaa90732e1ba4b40ef1/aiohttp-3.10.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:703938e22434d7d14ec22f9f310559331f455018389222eed132808cd8f44127", size = 577381, upload-time = "2024-11-13T16:38:26.708Z" }, { url = "https://files.pythonhosted.org/packages/4e/c4/ee9c350acb202ba2eb0c44b0f84376b05477e870444192a9f70e06844c28/aiohttp-3.10.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9bc50b63648840854e00084c2b43035a62e033cb9b06d8c22b409d56eb098413", size = 393289, upload-time = "2024-11-13T16:38:29.207Z" }, { url = "https://files.pythonhosted.org/packages/3d/7c/30d161a7e3b208cef1b922eacf2bbb8578b7e5a62266a6a2245a1dd044dc/aiohttp-3.10.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5f0463bf8b0754bc744e1feb61590706823795041e63edf30118a6f0bf577461", size = 388859, upload-time = "2024-11-13T16:38:31.567Z" }, { url = "https://files.pythonhosted.org/packages/79/10/8d050e04be447d3d39e5a4a910fa289d930120cebe1b893096bd3ee29063/aiohttp-3.10.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6c6dec398ac5a87cb3a407b068e1106b20ef001c344e34154616183fe684288", size = 1280983, upload-time = "2024-11-13T16:38:33.738Z" }, { url = "https://files.pythonhosted.org/packages/31/b3/977eca40afe643dcfa6b8d8bb9a93f4cba1d8ed1ead22c92056b08855c7a/aiohttp-3.10.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bcaf2d79104d53d4dcf934f7ce76d3d155302d07dae24dff6c9fffd217568067", size = 1317132, upload-time = "2024-11-13T16:38:35.999Z" }, { url = "https://files.pythonhosted.org/packages/1a/43/b5ee8e697ed0f96a2b3d80b3058fa7590cda508e9cd256274246ba1cf37a/aiohttp-3.10.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:25fd5470922091b5a9aeeb7e75be609e16b4fba81cdeaf12981393fb240dd10e", size = 1362630, upload-time = "2024-11-13T16:38:39.016Z" }, { url = "https://files.pythonhosted.org/packages/28/20/3ae8e993b2990fa722987222dea74d6bac9331e2f530d086f309b4aa8847/aiohttp-3.10.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbde2ca67230923a42161b1f408c3992ae6e0be782dca0c44cb3206bf330dee1", size = 1276865, upload-time = "2024-11-13T16:38:41.423Z" }, { url = "https://files.pythonhosted.org/packages/02/08/1afb0ab7dcff63333b683e998e751aa2547d1ff897b577d2244b00e6fe38/aiohttp-3.10.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:249c8ff8d26a8b41a0f12f9df804e7c685ca35a207e2410adbd3e924217b9006", size = 1230448, upload-time = "2024-11-13T16:38:43.962Z" }, { url = "https://files.pythonhosted.org/packages/c6/fd/ccd0ff842c62128d164ec09e3dd810208a84d79cd402358a3038ae91f3e9/aiohttp-3.10.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:878ca6a931ee8c486a8f7b432b65431d095c522cbeb34892bee5be97b3481d0f", size = 1244626, upload-time = "2024-11-13T16:38:47.089Z" }, { url = "https://files.pythonhosted.org/packages/9f/75/30e9537ab41ed7cb062338d8df7c4afb0a715b3551cd69fc4ea61cfa5a95/aiohttp-3.10.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8663f7777ce775f0413324be0d96d9730959b2ca73d9b7e2c2c90539139cbdd6", size = 1243608, upload-time = "2024-11-13T16:38:49.47Z" }, { url = "https://files.pythonhosted.org/packages/c2/e0/3e7a62d99b9080793affddc12a82b11c9bc1312916ad849700d2bddf9786/aiohttp-3.10.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:6cd3f10b01f0c31481fba8d302b61603a2acb37b9d30e1d14e0f5a58b7b18a31", size = 1286158, upload-time = "2024-11-13T16:38:51.947Z" }, { url = "https://files.pythonhosted.org/packages/71/b8/df67886802e71e976996ed9324eb7dc379e53a7d972314e9c7fe3f6ac6bc/aiohttp-3.10.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:4e8d8aad9402d3aa02fdc5ca2fe68bcb9fdfe1f77b40b10410a94c7f408b664d", size = 1313636, upload-time = "2024-11-13T16:38:54.424Z" }, { url = "https://files.pythonhosted.org/packages/3c/3b/aea9c3e70ff4e030f46902df28b4cdf486695f4d78fd9c6698827e2bafab/aiohttp-3.10.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:38e3c4f80196b4f6c3a85d134a534a56f52da9cb8d8e7af1b79a32eefee73a00", size = 1273772, upload-time = "2024-11-13T16:38:56.846Z" }, { url = "https://files.pythonhosted.org/packages/e9/9e/4b4c5705270d1c4ee146516ad288af720798d957ba46504aaf99b86e85d9/aiohttp-3.10.11-cp313-cp313-win32.whl", hash = "sha256:fc31820cfc3b2863c6e95e14fcf815dc7afe52480b4dc03393c4873bb5599f71", size = 358679, upload-time = "2024-11-13T16:38:59.787Z" }, { url = "https://files.pythonhosted.org/packages/28/1d/18ef37549901db94717d4389eb7be807acbfbdeab48a73ff2993fc909118/aiohttp-3.10.11-cp313-cp313-win_amd64.whl", hash = "sha256:4996ff1345704ffdd6d75fb06ed175938c133425af616142e7187f28dc75f14e", size = 378073, upload-time = "2024-11-13T16:39:02.065Z" }, { url = "https://files.pythonhosted.org/packages/dd/f2/59165bee7bba0b0634525834c622f152a30715a1d8280f6291a0cb86b1e6/aiohttp-3.10.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:74baf1a7d948b3d640badeac333af581a367ab916b37e44cf90a0334157cdfd2", size = 592135, upload-time = "2024-11-13T16:39:04.774Z" }, { url = "https://files.pythonhosted.org/packages/2e/0e/b3555c504745af66efbf89d16811148ff12932b86fad529d115538fe2739/aiohttp-3.10.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:473aebc3b871646e1940c05268d451f2543a1d209f47035b594b9d4e91ce8339", size = 402913, upload-time = "2024-11-13T16:39:08.065Z" }, { url = "https://files.pythonhosted.org/packages/31/bb/2890a3c77126758ef58536ca9f7476a12ba2021e0cd074108fb99b8c8747/aiohttp-3.10.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c2f746a6968c54ab2186574e15c3f14f3e7f67aef12b761e043b33b89c5b5f95", size = 394013, upload-time = "2024-11-13T16:39:10.638Z" }, { url = "https://files.pythonhosted.org/packages/74/82/0ab5199b473558846d72901a714b6afeb6f6a6a6a4c3c629e2c107418afd/aiohttp-3.10.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d110cabad8360ffa0dec8f6ec60e43286e9d251e77db4763a87dcfe55b4adb92", size = 1255578, upload-time = "2024-11-13T16:39:13.14Z" }, { url = "https://files.pythonhosted.org/packages/f8/b2/f232477dd3c0e95693a903c4815bfb8d831f6a1a67e27ad14d30a774eeda/aiohttp-3.10.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0099c7d5d7afff4202a0c670e5b723f7718810000b4abcbc96b064129e64bc7", size = 1298780, upload-time = "2024-11-13T16:39:15.721Z" }, { url = "https://files.pythonhosted.org/packages/34/8c/11972235a6b53d5b69098f2ee6629ff8f99cd9592dcaa620c7868deb5673/aiohttp-3.10.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0316e624b754dbbf8c872b62fe6dcb395ef20c70e59890dfa0de9eafccd2849d", size = 1336093, upload-time = "2024-11-13T16:39:19.11Z" }, { url = "https://files.pythonhosted.org/packages/03/be/7ad9a6cd2312221cf7b6837d8e2d8e4660fbd4f9f15bccf79ef857f41f4d/aiohttp-3.10.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a5f7ab8baf13314e6b2485965cbacb94afff1e93466ac4d06a47a81c50f9cca", size = 1250296, upload-time = "2024-11-13T16:39:22.363Z" }, { url = "https://files.pythonhosted.org/packages/bb/8d/a3885a582d9fc481bccb155d082f83a7a846942e36e4a4bba061e3d6b95e/aiohttp-3.10.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c891011e76041e6508cbfc469dd1a8ea09bc24e87e4c204e05f150c4c455a5fa", size = 1215020, upload-time = "2024-11-13T16:39:25.205Z" }, { url = "https://files.pythonhosted.org/packages/bb/e7/09a1736b7264316dc3738492d9b559f2a54b985660f21d76095c9890a62e/aiohttp-3.10.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:9208299251370ee815473270c52cd3f7069ee9ed348d941d574d1457d2c73e8b", size = 1210591, upload-time = "2024-11-13T16:39:28.311Z" }, { url = "https://files.pythonhosted.org/packages/58/b1/ee684631f6af98065d49ac8416db7a8e74ea33e1378bc75952ab0522342f/aiohttp-3.10.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:459f0f32c8356e8125f45eeff0ecf2b1cb6db1551304972702f34cd9e6c44658", size = 1211255, upload-time = "2024-11-13T16:39:30.799Z" }, { url = "https://files.pythonhosted.org/packages/8f/55/e21e312fd6c581f244dd2ed077ccb784aade07c19416a6316b1453f02c4e/aiohttp-3.10.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:14cdc8c1810bbd4b4b9f142eeee23cda528ae4e57ea0923551a9af4820980e39", size = 1278114, upload-time = "2024-11-13T16:39:34.141Z" }, { url = "https://files.pythonhosted.org/packages/d8/7f/ff6df0e90df6759693f52720ebedbfa10982d97aa1fd02c6ca917a6399ea/aiohttp-3.10.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:971aa438a29701d4b34e4943e91b5e984c3ae6ccbf80dd9efaffb01bd0b243a9", size = 1292714, upload-time = "2024-11-13T16:39:37.216Z" }, { url = "https://files.pythonhosted.org/packages/3a/45/63f35367dfffae41e7abd0603f92708b5b3655fda55c08388ac2c7fb127b/aiohttp-3.10.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:9a309c5de392dfe0f32ee57fa43ed8fc6ddf9985425e84bd51ed66bb16bce3a7", size = 1233734, upload-time = "2024-11-13T16:39:40.599Z" }, { url = "https://files.pythonhosted.org/packages/ec/ee/74b0696c0e84e06c43beab9302f353d97dc9f0cccd7ccf3ee648411b849b/aiohttp-3.10.11-cp38-cp38-win32.whl", hash = "sha256:9ec1628180241d906a0840b38f162a3215114b14541f1a8711c368a8739a9be4", size = 365350, upload-time = "2024-11-13T16:39:43.852Z" }, { url = "https://files.pythonhosted.org/packages/21/0c/74c895688db09a2852056abf32d128991ec2fb41e5f57a1fe0928e15151c/aiohttp-3.10.11-cp38-cp38-win_amd64.whl", hash = "sha256:9c6e0ffd52c929f985c7258f83185d17c76d4275ad22e90aa29f38e211aacbec", size = 384542, upload-time = "2024-11-13T16:39:47.093Z" }, { url = "https://files.pythonhosted.org/packages/cc/df/aa0d1548db818395a372b5f90e62072677ce786d6b19680c49dd4da3825f/aiohttp-3.10.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cdc493a2e5d8dc79b2df5bec9558425bcd39aff59fc949810cbd0832e294b106", size = 589833, upload-time = "2024-11-13T16:39:49.72Z" }, { url = "https://files.pythonhosted.org/packages/75/7c/d11145784b3fa29c0421a3883a4b91ee8c19acb40332b1d2e39f47be4e5b/aiohttp-3.10.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b3e70f24e7d0405be2348da9d5a7836936bf3a9b4fd210f8c37e8d48bc32eca6", size = 401685, upload-time = "2024-11-13T16:39:52.263Z" }, { url = "https://files.pythonhosted.org/packages/e2/67/1b5f93babeb060cb683d23104b243be1d6299fe6cd807dcb56cf67d2e62c/aiohttp-3.10.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:968b8fb2a5eee2770eda9c7b5581587ef9b96fbdf8dcabc6b446d35ccc69df01", size = 392957, upload-time = "2024-11-13T16:39:54.668Z" }, { url = "https://files.pythonhosted.org/packages/e1/4d/441df53aafd8dd97b8cfe9e467c641fa19cb5113e7601a7f77f2124518e0/aiohttp-3.10.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deef4362af9493d1382ef86732ee2e4cbc0d7c005947bd54ad1a9a16dd59298e", size = 1229754, upload-time = "2024-11-13T16:39:57.166Z" }, { url = "https://files.pythonhosted.org/packages/4d/cc/f1397a2501b95cb94580de7051395e85af95a1e27aed1f8af73459ddfa22/aiohttp-3.10.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:686b03196976e327412a1b094f4120778c7c4b9cff9bce8d2fdfeca386b89829", size = 1266246, upload-time = "2024-11-13T16:40:00.723Z" }, { url = "https://files.pythonhosted.org/packages/c2/b5/7d33dae7630b4e9f90d634c6a90cb0923797e011b71cd9b10fe685aec3f6/aiohttp-3.10.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3bf6d027d9d1d34e1c2e1645f18a6498c98d634f8e373395221121f1c258ace8", size = 1301720, upload-time = "2024-11-13T16:40:04.111Z" }, { url = "https://files.pythonhosted.org/packages/51/36/f917bcc63bc489aa3f534fa81efbf895fa5286745dcd8bbd0eb9dbc923a1/aiohttp-3.10.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:099fd126bf960f96d34a760e747a629c27fb3634da5d05c7ef4d35ef4ea519fc", size = 1221527, upload-time = "2024-11-13T16:40:06.851Z" }, { url = "https://files.pythonhosted.org/packages/32/c2/1a303a072b4763d99d4b0664a3a8b952869e3fbb660d4239826bd0c56cc1/aiohttp-3.10.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c73c4d3dae0b4644bc21e3de546530531d6cdc88659cdeb6579cd627d3c206aa", size = 1192309, upload-time = "2024-11-13T16:40:09.65Z" }, { url = "https://files.pythonhosted.org/packages/62/ef/d62f705dc665382b78ef171e5ba2616c395220ac7c1f452f0d2dcad3f9f5/aiohttp-3.10.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0c5580f3c51eea91559db3facd45d72e7ec970b04528b4709b1f9c2555bd6d0b", size = 1189481, upload-time = "2024-11-13T16:40:12.77Z" }, { url = "https://files.pythonhosted.org/packages/40/22/3e3eb4f97e5c4f52ccd198512b583c0c9135aa4e989c7ade97023c4cd282/aiohttp-3.10.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:fdf6429f0caabfd8a30c4e2eaecb547b3c340e4730ebfe25139779b9815ba138", size = 1187877, upload-time = "2024-11-13T16:40:15.985Z" }, { url = "https://files.pythonhosted.org/packages/b5/73/77475777fbe2b3efaceb49db2859f1a22c96fd5869d736e80375db05bbf4/aiohttp-3.10.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:d97187de3c276263db3564bb9d9fad9e15b51ea10a371ffa5947a5ba93ad6777", size = 1246006, upload-time = "2024-11-13T16:40:19.17Z" }, { url = "https://files.pythonhosted.org/packages/ef/f7/5b060d19065473da91838b63d8fd4d20ef8426a7d905cc8f9cd11eabd780/aiohttp-3.10.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:0acafb350cfb2eba70eb5d271f55e08bd4502ec35e964e18ad3e7d34d71f7261", size = 1260403, upload-time = "2024-11-13T16:40:21.761Z" }, { url = "https://files.pythonhosted.org/packages/6c/ea/e9ad224815cd83c8dfda686d2bafa2cab5b93d7232e09470a8d2a158acde/aiohttp-3.10.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c13ed0c779911c7998a58e7848954bd4d63df3e3575f591e321b19a2aec8df9f", size = 1208643, upload-time = "2024-11-13T16:40:24.803Z" }, { url = "https://files.pythonhosted.org/packages/ba/c1/e1c6bba72f379adbd52958601a8642546ed0807964afba3b1b5b8cfb1bc0/aiohttp-3.10.11-cp39-cp39-win32.whl", hash = "sha256:22b7c540c55909140f63ab4f54ec2c20d2635c0289cdd8006da46f3327f971b9", size = 364419, upload-time = "2024-11-13T16:40:27.817Z" }, { url = "https://files.pythonhosted.org/packages/30/24/50862e06e86cd263c60661e00b9d2c8d7fdece4fe95454ed5aa21ecf8036/aiohttp-3.10.11-cp39-cp39-win_amd64.whl", hash = "sha256:7b26b1551e481012575dab8e3727b16fe7dd27eb2711d2e63ced7368756268fb", size = 382857, upload-time = "2024-11-13T16:40:30.427Z" }, ] [[package]] name = "aiohttp" version = "3.12.13" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.10'", "python_full_version == '3.9.*'", ] dependencies = [ { name = "aiohappyeyeballs", version = "2.6.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "aiosignal", version = "1.4.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "async-timeout", marker = "(python_full_version >= '3.9' and python_full_version < '3.11') or (python_full_version < '3.9' and extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2') or (python_full_version >= '3.11' and extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "attrs", marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "frozenlist", version = "1.7.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "multidict", version = "6.6.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "propcache", version = "0.3.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "yarl", version = "1.20.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/42/6e/ab88e7cb2a4058bed2f7870276454f85a7c56cd6da79349eb314fc7bbcaa/aiohttp-3.12.13.tar.gz", hash = "sha256:47e2da578528264a12e4e3dd8dd72a7289e5f812758fe086473fab037a10fcce", size = 7819160, upload-time = "2025-06-14T15:15:41.354Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/8b/2d/27e4347660723738b01daa3f5769d56170f232bf4695dd4613340da135bb/aiohttp-3.12.13-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5421af8f22a98f640261ee48aae3a37f0c41371e99412d55eaf2f8a46d5dad29", size = 702090, upload-time = "2025-06-14T15:12:58.938Z" }, { url = "https://files.pythonhosted.org/packages/10/0b/4a8e0468ee8f2b9aff3c05f2c3a6be1dfc40b03f68a91b31041d798a9510/aiohttp-3.12.13-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0fcda86f6cb318ba36ed8f1396a6a4a3fd8f856f84d426584392083d10da4de0", size = 478440, upload-time = "2025-06-14T15:13:02.981Z" }, { url = "https://files.pythonhosted.org/packages/b9/c8/2086df2f9a842b13feb92d071edf756be89250f404f10966b7bc28317f17/aiohttp-3.12.13-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4cd71c9fb92aceb5a23c4c39d8ecc80389c178eba9feab77f19274843eb9412d", size = 466215, upload-time = "2025-06-14T15:13:04.817Z" }, { url = "https://files.pythonhosted.org/packages/a7/3d/d23e5bd978bc8012a65853959b13bd3b55c6e5afc172d89c26ad6624c52b/aiohttp-3.12.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34ebf1aca12845066c963016655dac897651e1544f22a34c9b461ac3b4b1d3aa", size = 1648271, upload-time = "2025-06-14T15:13:06.532Z" }, { url = "https://files.pythonhosted.org/packages/31/31/e00122447bb137591c202786062f26dd383574c9f5157144127077d5733e/aiohttp-3.12.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:893a4639694c5b7edd4bdd8141be296042b6806e27cc1d794e585c43010cc294", size = 1622329, upload-time = "2025-06-14T15:13:08.394Z" }, { url = "https://files.pythonhosted.org/packages/04/01/caef70be3ac38986969045f21f5fb802ce517b3f371f0615206bf8aa6423/aiohttp-3.12.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:663d8ee3ffb3494502ebcccb49078faddbb84c1d870f9c1dd5a29e85d1f747ce", size = 1694734, upload-time = "2025-06-14T15:13:09.979Z" }, { url = "https://files.pythonhosted.org/packages/3f/15/328b71fedecf69a9fd2306549b11c8966e420648a3938d75d3ed5bcb47f6/aiohttp-3.12.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f0f8f6a85a0006ae2709aa4ce05749ba2cdcb4b43d6c21a16c8517c16593aabe", size = 1737049, upload-time = "2025-06-14T15:13:11.672Z" }, { url = "https://files.pythonhosted.org/packages/e6/7a/d85866a642158e1147c7da5f93ad66b07e5452a84ec4258e5f06b9071e92/aiohttp-3.12.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1582745eb63df267c92d8b61ca655a0ce62105ef62542c00a74590f306be8cb5", size = 1641715, upload-time = "2025-06-14T15:13:13.548Z" }, { url = "https://files.pythonhosted.org/packages/14/57/3588800d5d2f5f3e1cb6e7a72747d1abc1e67ba5048e8b845183259c2e9b/aiohttp-3.12.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d59227776ee2aa64226f7e086638baa645f4b044f2947dbf85c76ab11dcba073", size = 1581836, upload-time = "2025-06-14T15:13:15.086Z" }, { url = "https://files.pythonhosted.org/packages/2f/55/c913332899a916d85781aa74572f60fd98127449b156ad9c19e23135b0e4/aiohttp-3.12.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06b07c418bde1c8e737d8fa67741072bd3f5b0fb66cf8c0655172188c17e5fa6", size = 1625685, upload-time = "2025-06-14T15:13:17.163Z" }, { url = "https://files.pythonhosted.org/packages/4c/34/26cded195f3bff128d6a6d58d7a0be2ae7d001ea029e0fe9008dcdc6a009/aiohttp-3.12.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:9445c1842680efac0f81d272fd8db7163acfcc2b1436e3f420f4c9a9c5a50795", size = 1636471, upload-time = "2025-06-14T15:13:19.086Z" }, { url = "https://files.pythonhosted.org/packages/19/21/70629ca006820fccbcec07f3cd5966cbd966e2d853d6da55339af85555b9/aiohttp-3.12.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:09c4767af0b0b98c724f5d47f2bf33395c8986995b0a9dab0575ca81a554a8c0", size = 1611923, upload-time = "2025-06-14T15:13:20.997Z" }, { url = "https://files.pythonhosted.org/packages/31/80/7fa3f3bebf533aa6ae6508b51ac0de9965e88f9654fa679cc1a29d335a79/aiohttp-3.12.13-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:f3854fbde7a465318ad8d3fc5bef8f059e6d0a87e71a0d3360bb56c0bf87b18a", size = 1691511, upload-time = "2025-06-14T15:13:22.54Z" }, { url = "https://files.pythonhosted.org/packages/0f/7a/359974653a3cdd3e9cee8ca10072a662c3c0eb46a359c6a1f667b0296e2f/aiohttp-3.12.13-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2332b4c361c05ecd381edb99e2a33733f3db906739a83a483974b3df70a51b40", size = 1714751, upload-time = "2025-06-14T15:13:24.366Z" }, { url = "https://files.pythonhosted.org/packages/2d/24/0aa03d522171ce19064347afeefadb008be31ace0bbb7d44ceb055700a14/aiohttp-3.12.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1561db63fa1b658cd94325d303933553ea7d89ae09ff21cc3bcd41b8521fbbb6", size = 1643090, upload-time = "2025-06-14T15:13:26.231Z" }, { url = "https://files.pythonhosted.org/packages/86/2e/7d4b0026a41e4b467e143221c51b279083b7044a4b104054f5c6464082ff/aiohttp-3.12.13-cp310-cp310-win32.whl", hash = "sha256:a0be857f0b35177ba09d7c472825d1b711d11c6d0e8a2052804e3b93166de1ad", size = 427526, upload-time = "2025-06-14T15:13:27.988Z" }, { url = "https://files.pythonhosted.org/packages/17/de/34d998da1e7f0de86382160d039131e9b0af1962eebfe53dda2b61d250e7/aiohttp-3.12.13-cp310-cp310-win_amd64.whl", hash = "sha256:fcc30ad4fb5cb41a33953292d45f54ef4066746d625992aeac33b8c681173178", size = 450734, upload-time = "2025-06-14T15:13:29.394Z" }, { url = "https://files.pythonhosted.org/packages/6a/65/5566b49553bf20ffed6041c665a5504fb047cefdef1b701407b8ce1a47c4/aiohttp-3.12.13-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7c229b1437aa2576b99384e4be668af1db84b31a45305d02f61f5497cfa6f60c", size = 709401, upload-time = "2025-06-14T15:13:30.774Z" }, { url = "https://files.pythonhosted.org/packages/14/b5/48e4cc61b54850bdfafa8fe0b641ab35ad53d8e5a65ab22b310e0902fa42/aiohttp-3.12.13-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:04076d8c63471e51e3689c93940775dc3d12d855c0c80d18ac5a1c68f0904358", size = 481669, upload-time = "2025-06-14T15:13:32.316Z" }, { url = "https://files.pythonhosted.org/packages/04/4f/e3f95c8b2a20a0437d51d41d5ccc4a02970d8ad59352efb43ea2841bd08e/aiohttp-3.12.13-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:55683615813ce3601640cfaa1041174dc956d28ba0511c8cbd75273eb0587014", size = 469933, upload-time = "2025-06-14T15:13:34.104Z" }, { url = "https://files.pythonhosted.org/packages/41/c9/c5269f3b6453b1cfbd2cfbb6a777d718c5f086a3727f576c51a468b03ae2/aiohttp-3.12.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:921bc91e602d7506d37643e77819cb0b840d4ebb5f8d6408423af3d3bf79a7b7", size = 1740128, upload-time = "2025-06-14T15:13:35.604Z" }, { url = "https://files.pythonhosted.org/packages/6f/49/a3f76caa62773d33d0cfaa842bdf5789a78749dbfe697df38ab1badff369/aiohttp-3.12.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e72d17fe0974ddeae8ed86db297e23dba39c7ac36d84acdbb53df2e18505a013", size = 1688796, upload-time = "2025-06-14T15:13:37.125Z" }, { url = "https://files.pythonhosted.org/packages/ad/e4/556fccc4576dc22bf18554b64cc873b1a3e5429a5bdb7bbef7f5d0bc7664/aiohttp-3.12.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0653d15587909a52e024a261943cf1c5bdc69acb71f411b0dd5966d065a51a47", size = 1787589, upload-time = "2025-06-14T15:13:38.745Z" }, { url = "https://files.pythonhosted.org/packages/b9/3d/d81b13ed48e1a46734f848e26d55a7391708421a80336e341d2aef3b6db2/aiohttp-3.12.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a77b48997c66722c65e157c06c74332cdf9c7ad00494b85ec43f324e5c5a9b9a", size = 1826635, upload-time = "2025-06-14T15:13:40.733Z" }, { url = "https://files.pythonhosted.org/packages/75/a5/472e25f347da88459188cdaadd1f108f6292f8a25e62d226e63f860486d1/aiohttp-3.12.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d6946bae55fd36cfb8e4092c921075cde029c71c7cb571d72f1079d1e4e013bc", size = 1729095, upload-time = "2025-06-14T15:13:42.312Z" }, { url = "https://files.pythonhosted.org/packages/b9/fe/322a78b9ac1725bfc59dfc301a5342e73d817592828e4445bd8f4ff83489/aiohttp-3.12.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f95db8c8b219bcf294a53742c7bda49b80ceb9d577c8e7aa075612b7f39ffb7", size = 1666170, upload-time = "2025-06-14T15:13:44.884Z" }, { url = "https://files.pythonhosted.org/packages/7a/77/ec80912270e231d5e3839dbd6c065472b9920a159ec8a1895cf868c2708e/aiohttp-3.12.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:03d5eb3cfb4949ab4c74822fb3326cd9655c2b9fe22e4257e2100d44215b2e2b", size = 1714444, upload-time = "2025-06-14T15:13:46.401Z" }, { url = "https://files.pythonhosted.org/packages/21/b2/fb5aedbcb2b58d4180e58500e7c23ff8593258c27c089abfbcc7db65bd40/aiohttp-3.12.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:6383dd0ffa15515283c26cbf41ac8e6705aab54b4cbb77bdb8935a713a89bee9", size = 1709604, upload-time = "2025-06-14T15:13:48.377Z" }, { url = "https://files.pythonhosted.org/packages/e3/15/a94c05f7c4dc8904f80b6001ad6e07e035c58a8ebfcc15e6b5d58500c858/aiohttp-3.12.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:6548a411bc8219b45ba2577716493aa63b12803d1e5dc70508c539d0db8dbf5a", size = 1689786, upload-time = "2025-06-14T15:13:50.401Z" }, { url = "https://files.pythonhosted.org/packages/1d/fd/0d2e618388f7a7a4441eed578b626bda9ec6b5361cd2954cfc5ab39aa170/aiohttp-3.12.13-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:81b0fcbfe59a4ca41dc8f635c2a4a71e63f75168cc91026c61be665945739e2d", size = 1783389, upload-time = "2025-06-14T15:13:51.945Z" }, { url = "https://files.pythonhosted.org/packages/a6/6b/6986d0c75996ef7e64ff7619b9b7449b1d1cbbe05c6755e65d92f1784fe9/aiohttp-3.12.13-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:6a83797a0174e7995e5edce9dcecc517c642eb43bc3cba296d4512edf346eee2", size = 1803853, upload-time = "2025-06-14T15:13:53.533Z" }, { url = "https://files.pythonhosted.org/packages/21/65/cd37b38f6655d95dd07d496b6d2f3924f579c43fd64b0e32b547b9c24df5/aiohttp-3.12.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a5734d8469a5633a4e9ffdf9983ff7cdb512524645c7a3d4bc8a3de45b935ac3", size = 1716909, upload-time = "2025-06-14T15:13:55.148Z" }, { url = "https://files.pythonhosted.org/packages/fd/20/2de7012427dc116714c38ca564467f6143aec3d5eca3768848d62aa43e62/aiohttp-3.12.13-cp311-cp311-win32.whl", hash = "sha256:fef8d50dfa482925bb6b4c208b40d8e9fa54cecba923dc65b825a72eed9a5dbd", size = 427036, upload-time = "2025-06-14T15:13:57.076Z" }, { url = "https://files.pythonhosted.org/packages/f8/b6/98518bcc615ef998a64bef371178b9afc98ee25895b4f476c428fade2220/aiohttp-3.12.13-cp311-cp311-win_amd64.whl", hash = "sha256:9a27da9c3b5ed9d04c36ad2df65b38a96a37e9cfba6f1381b842d05d98e6afe9", size = 451427, upload-time = "2025-06-14T15:13:58.505Z" }, { url = "https://files.pythonhosted.org/packages/b4/6a/ce40e329788013cd190b1d62bbabb2b6a9673ecb6d836298635b939562ef/aiohttp-3.12.13-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0aa580cf80558557285b49452151b9c69f2fa3ad94c5c9e76e684719a8791b73", size = 700491, upload-time = "2025-06-14T15:14:00.048Z" }, { url = "https://files.pythonhosted.org/packages/28/d9/7150d5cf9163e05081f1c5c64a0cdf3c32d2f56e2ac95db2a28fe90eca69/aiohttp-3.12.13-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b103a7e414b57e6939cc4dece8e282cfb22043efd0c7298044f6594cf83ab347", size = 475104, upload-time = "2025-06-14T15:14:01.691Z" }, { url = "https://files.pythonhosted.org/packages/f8/91/d42ba4aed039ce6e449b3e2db694328756c152a79804e64e3da5bc19dffc/aiohttp-3.12.13-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:78f64e748e9e741d2eccff9597d09fb3cd962210e5b5716047cbb646dc8fe06f", size = 467948, upload-time = "2025-06-14T15:14:03.561Z" }, { url = "https://files.pythonhosted.org/packages/99/3b/06f0a632775946981d7c4e5a865cddb6e8dfdbaed2f56f9ade7bb4a1039b/aiohttp-3.12.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29c955989bf4c696d2ededc6b0ccb85a73623ae6e112439398935362bacfaaf6", size = 1714742, upload-time = "2025-06-14T15:14:05.558Z" }, { url = "https://files.pythonhosted.org/packages/92/a6/2552eebad9ec5e3581a89256276009e6a974dc0793632796af144df8b740/aiohttp-3.12.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d640191016763fab76072c87d8854a19e8e65d7a6fcfcbf017926bdbbb30a7e5", size = 1697393, upload-time = "2025-06-14T15:14:07.194Z" }, { url = "https://files.pythonhosted.org/packages/d8/9f/bd08fdde114b3fec7a021381b537b21920cdd2aa29ad48c5dffd8ee314f1/aiohttp-3.12.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4dc507481266b410dede95dd9f26c8d6f5a14315372cc48a6e43eac652237d9b", size = 1752486, upload-time = "2025-06-14T15:14:08.808Z" }, { url = "https://files.pythonhosted.org/packages/f7/e1/affdea8723aec5bd0959171b5490dccd9a91fcc505c8c26c9f1dca73474d/aiohttp-3.12.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a94daa873465d518db073bd95d75f14302e0208a08e8c942b2f3f1c07288a75", size = 1798643, upload-time = "2025-06-14T15:14:10.767Z" }, { url = "https://files.pythonhosted.org/packages/f3/9d/666d856cc3af3a62ae86393baa3074cc1d591a47d89dc3bf16f6eb2c8d32/aiohttp-3.12.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:177f52420cde4ce0bb9425a375d95577fe082cb5721ecb61da3049b55189e4e6", size = 1718082, upload-time = "2025-06-14T15:14:12.38Z" }, { url = "https://files.pythonhosted.org/packages/f3/ce/3c185293843d17be063dada45efd2712bb6bf6370b37104b4eda908ffdbd/aiohttp-3.12.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f7df1f620ec40f1a7fbcb99ea17d7326ea6996715e78f71a1c9a021e31b96b8", size = 1633884, upload-time = "2025-06-14T15:14:14.415Z" }, { url = "https://files.pythonhosted.org/packages/3a/5b/f3413f4b238113be35dfd6794e65029250d4b93caa0974ca572217745bdb/aiohttp-3.12.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3062d4ad53b36e17796dce1c0d6da0ad27a015c321e663657ba1cc7659cfc710", size = 1694943, upload-time = "2025-06-14T15:14:16.48Z" }, { url = "https://files.pythonhosted.org/packages/82/c8/0e56e8bf12081faca85d14a6929ad5c1263c146149cd66caa7bc12255b6d/aiohttp-3.12.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:8605e22d2a86b8e51ffb5253d9045ea73683d92d47c0b1438e11a359bdb94462", size = 1716398, upload-time = "2025-06-14T15:14:18.589Z" }, { url = "https://files.pythonhosted.org/packages/ea/f3/33192b4761f7f9b2f7f4281365d925d663629cfaea093a64b658b94fc8e1/aiohttp-3.12.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54fbbe6beafc2820de71ece2198458a711e224e116efefa01b7969f3e2b3ddae", size = 1657051, upload-time = "2025-06-14T15:14:20.223Z" }, { url = "https://files.pythonhosted.org/packages/5e/0b/26ddd91ca8f84c48452431cb4c5dd9523b13bc0c9766bda468e072ac9e29/aiohttp-3.12.13-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:050bd277dfc3768b606fd4eae79dd58ceda67d8b0b3c565656a89ae34525d15e", size = 1736611, upload-time = "2025-06-14T15:14:21.988Z" }, { url = "https://files.pythonhosted.org/packages/c3/8d/e04569aae853302648e2c138a680a6a2f02e374c5b6711732b29f1e129cc/aiohttp-3.12.13-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:2637a60910b58f50f22379b6797466c3aa6ae28a6ab6404e09175ce4955b4e6a", size = 1764586, upload-time = "2025-06-14T15:14:23.979Z" }, { url = "https://files.pythonhosted.org/packages/ac/98/c193c1d1198571d988454e4ed75adc21c55af247a9fda08236602921c8c8/aiohttp-3.12.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e986067357550d1aaa21cfe9897fa19e680110551518a5a7cf44e6c5638cb8b5", size = 1724197, upload-time = "2025-06-14T15:14:25.692Z" }, { url = "https://files.pythonhosted.org/packages/e7/9e/07bb8aa11eec762c6b1ff61575eeeb2657df11ab3d3abfa528d95f3e9337/aiohttp-3.12.13-cp312-cp312-win32.whl", hash = "sha256:ac941a80aeea2aaae2875c9500861a3ba356f9ff17b9cb2dbfb5cbf91baaf5bf", size = 421771, upload-time = "2025-06-14T15:14:27.364Z" }, { url = "https://files.pythonhosted.org/packages/52/66/3ce877e56ec0813069cdc9607cd979575859c597b6fb9b4182c6d5f31886/aiohttp-3.12.13-cp312-cp312-win_amd64.whl", hash = "sha256:671f41e6146a749b6c81cb7fd07f5a8356d46febdaaaf07b0e774ff04830461e", size = 447869, upload-time = "2025-06-14T15:14:29.05Z" }, { url = "https://files.pythonhosted.org/packages/11/0f/db19abdf2d86aa1deec3c1e0e5ea46a587b97c07a16516b6438428b3a3f8/aiohttp-3.12.13-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:d4a18e61f271127465bdb0e8ff36e8f02ac4a32a80d8927aa52371e93cd87938", size = 694910, upload-time = "2025-06-14T15:14:30.604Z" }, { url = "https://files.pythonhosted.org/packages/d5/81/0ab551e1b5d7f1339e2d6eb482456ccbe9025605b28eed2b1c0203aaaade/aiohttp-3.12.13-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:532542cb48691179455fab429cdb0d558b5e5290b033b87478f2aa6af5d20ace", size = 472566, upload-time = "2025-06-14T15:14:32.275Z" }, { url = "https://files.pythonhosted.org/packages/34/3f/6b7d336663337672d29b1f82d1f252ec1a040fe2d548f709d3f90fa2218a/aiohttp-3.12.13-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d7eea18b52f23c050ae9db5d01f3d264ab08f09e7356d6f68e3f3ac2de9dfabb", size = 464856, upload-time = "2025-06-14T15:14:34.132Z" }, { url = "https://files.pythonhosted.org/packages/26/7f/32ca0f170496aa2ab9b812630fac0c2372c531b797e1deb3deb4cea904bd/aiohttp-3.12.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad7c8e5c25f2a26842a7c239de3f7b6bfb92304593ef997c04ac49fb703ff4d7", size = 1703683, upload-time = "2025-06-14T15:14:36.034Z" }, { url = "https://files.pythonhosted.org/packages/ec/53/d5513624b33a811c0abea8461e30a732294112318276ce3dbf047dbd9d8b/aiohttp-3.12.13-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6af355b483e3fe9d7336d84539fef460120c2f6e50e06c658fe2907c69262d6b", size = 1684946, upload-time = "2025-06-14T15:14:38Z" }, { url = "https://files.pythonhosted.org/packages/37/72/4c237dd127827b0247dc138d3ebd49c2ded6114c6991bbe969058575f25f/aiohttp-3.12.13-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a95cf9f097498f35c88e3609f55bb47b28a5ef67f6888f4390b3d73e2bac6177", size = 1737017, upload-time = "2025-06-14T15:14:39.951Z" }, { url = "https://files.pythonhosted.org/packages/0d/67/8a7eb3afa01e9d0acc26e1ef847c1a9111f8b42b82955fcd9faeb84edeb4/aiohttp-3.12.13-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b8ed8c38a1c584fe99a475a8f60eefc0b682ea413a84c6ce769bb19a7ff1c5ef", size = 1786390, upload-time = "2025-06-14T15:14:42.151Z" }, { url = "https://files.pythonhosted.org/packages/48/19/0377df97dd0176ad23cd8cad4fd4232cfeadcec6c1b7f036315305c98e3f/aiohttp-3.12.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a0b9170d5d800126b5bc89d3053a2363406d6e327afb6afaeda2d19ee8bb103", size = 1708719, upload-time = "2025-06-14T15:14:44.039Z" }, { url = "https://files.pythonhosted.org/packages/61/97/ade1982a5c642b45f3622255173e40c3eed289c169f89d00eeac29a89906/aiohttp-3.12.13-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:372feeace612ef8eb41f05ae014a92121a512bd5067db8f25101dd88a8db11da", size = 1622424, upload-time = "2025-06-14T15:14:45.945Z" }, { url = "https://files.pythonhosted.org/packages/99/ab/00ad3eea004e1d07ccc406e44cfe2b8da5acb72f8c66aeeb11a096798868/aiohttp-3.12.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a946d3702f7965d81f7af7ea8fb03bb33fe53d311df48a46eeca17e9e0beed2d", size = 1675447, upload-time = "2025-06-14T15:14:47.911Z" }, { url = "https://files.pythonhosted.org/packages/3f/fe/74e5ce8b2ccaba445fe0087abc201bfd7259431d92ae608f684fcac5d143/aiohttp-3.12.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:a0c4725fae86555bbb1d4082129e21de7264f4ab14baf735278c974785cd2041", size = 1707110, upload-time = "2025-06-14T15:14:50.334Z" }, { url = "https://files.pythonhosted.org/packages/ef/c4/39af17807f694f7a267bd8ab1fbacf16ad66740862192a6c8abac2bff813/aiohttp-3.12.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9b28ea2f708234f0a5c44eb6c7d9eb63a148ce3252ba0140d050b091b6e842d1", size = 1649706, upload-time = "2025-06-14T15:14:52.378Z" }, { url = "https://files.pythonhosted.org/packages/38/e8/f5a0a5f44f19f171d8477059aa5f28a158d7d57fe1a46c553e231f698435/aiohttp-3.12.13-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d4f5becd2a5791829f79608c6f3dc745388162376f310eb9c142c985f9441cc1", size = 1725839, upload-time = "2025-06-14T15:14:54.617Z" }, { url = "https://files.pythonhosted.org/packages/fd/ac/81acc594c7f529ef4419d3866913f628cd4fa9cab17f7bf410a5c3c04c53/aiohttp-3.12.13-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:60f2ce6b944e97649051d5f5cc0f439360690b73909230e107fd45a359d3e911", size = 1759311, upload-time = "2025-06-14T15:14:56.597Z" }, { url = "https://files.pythonhosted.org/packages/38/0d/aabe636bd25c6ab7b18825e5a97d40024da75152bec39aa6ac8b7a677630/aiohttp-3.12.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:69fc1909857401b67bf599c793f2183fbc4804717388b0b888f27f9929aa41f3", size = 1708202, upload-time = "2025-06-14T15:14:58.598Z" }, { url = "https://files.pythonhosted.org/packages/1f/ab/561ef2d8a223261683fb95a6283ad0d36cb66c87503f3a7dde7afe208bb2/aiohttp-3.12.13-cp313-cp313-win32.whl", hash = "sha256:7d7e68787a2046b0e44ba5587aa723ce05d711e3a3665b6b7545328ac8e3c0dd", size = 420794, upload-time = "2025-06-14T15:15:00.939Z" }, { url = "https://files.pythonhosted.org/packages/9d/47/b11d0089875a23bff0abd3edb5516bcd454db3fefab8604f5e4b07bd6210/aiohttp-3.12.13-cp313-cp313-win_amd64.whl", hash = "sha256:5a178390ca90419bfd41419a809688c368e63c86bd725e1186dd97f6b89c2706", size = 446735, upload-time = "2025-06-14T15:15:02.858Z" }, { url = "https://files.pythonhosted.org/packages/05/7e/0f6b2b4797ac364b6ecc9176bb2dd24d4a9aeaa77ecb093c7f87e44dfbd6/aiohttp-3.12.13-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:36f6c973e003dc9b0bb4e8492a643641ea8ef0e97ff7aaa5c0f53d68839357b4", size = 704988, upload-time = "2025-06-14T15:15:04.705Z" }, { url = "https://files.pythonhosted.org/packages/52/38/d51ea984c777b203959030895c1c8b1f9aac754f8e919e4942edce05958e/aiohttp-3.12.13-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6cbfc73179bd67c229eb171e2e3745d2afd5c711ccd1e40a68b90427f282eab1", size = 479967, upload-time = "2025-06-14T15:15:06.575Z" }, { url = "https://files.pythonhosted.org/packages/9d/0a/62f1c2914840eb2184939e773b65e1e5d6b651b78134798263467f0d2467/aiohttp-3.12.13-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1e8b27b2d414f7e3205aa23bb4a692e935ef877e3a71f40d1884f6e04fd7fa74", size = 467373, upload-time = "2025-06-14T15:15:08.788Z" }, { url = "https://files.pythonhosted.org/packages/7b/4e/327a4b56bb940afb03ee45d5fd1ef7dae5ed6617889d61ed8abf0548310b/aiohttp-3.12.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eabded0c2b2ef56243289112c48556c395d70150ce4220d9008e6b4b3dd15690", size = 1642326, upload-time = "2025-06-14T15:15:10.74Z" }, { url = "https://files.pythonhosted.org/packages/55/5d/f0277aad4d85a56cd6102335d5111c7c6d1f98cb760aa485e4fe11a24f52/aiohttp-3.12.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:003038e83f1a3ff97409999995ec02fe3008a1d675478949643281141f54751d", size = 1616820, upload-time = "2025-06-14T15:15:12.77Z" }, { url = "https://files.pythonhosted.org/packages/f2/ff/909193459a6d32ee806d9f7ae2342c940ee97d2c1416140c5aec3bd6bfc0/aiohttp-3.12.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1b6f46613031dbc92bdcaad9c4c22c7209236ec501f9c0c5f5f0b6a689bf50f3", size = 1690448, upload-time = "2025-06-14T15:15:14.754Z" }, { url = "https://files.pythonhosted.org/packages/45/e7/14d09183849e9bd69d8d5bf7df0ab7603996b83b00540e0890eeefa20e1e/aiohttp-3.12.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c332c6bb04650d59fb94ed96491f43812549a3ba6e7a16a218e612f99f04145e", size = 1729763, upload-time = "2025-06-14T15:15:16.783Z" }, { url = "https://files.pythonhosted.org/packages/55/01/07b980d6226574cc2d157fa4978a3d77270a4e860193a579630a81b30e30/aiohttp-3.12.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3fea41a2c931fb582cb15dc86a3037329e7b941df52b487a9f8b5aa960153cbd", size = 1636002, upload-time = "2025-06-14T15:15:18.871Z" }, { url = "https://files.pythonhosted.org/packages/73/cf/20a1f75ca3d8e48065412e80b79bb1c349e26a4fa51d660be186a9c0c1e3/aiohttp-3.12.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:846104f45d18fb390efd9b422b27d8f3cf8853f1218c537f36e71a385758c896", size = 1571003, upload-time = "2025-06-14T15:15:20.95Z" }, { url = "https://files.pythonhosted.org/packages/e1/99/09520d83e5964d6267074be9c66698e2003dfe8c66465813f57b029dec8c/aiohttp-3.12.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d6c85ac7dd350f8da2520bac8205ce99df4435b399fa7f4dc4a70407073e390", size = 1618964, upload-time = "2025-06-14T15:15:23.155Z" }, { url = "https://files.pythonhosted.org/packages/3a/01/c68f2c7632441fbbfc4a835e003e61eb1d63531857b0a2b73c9698846fa8/aiohttp-3.12.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:5a1ecce0ed281bec7da8550da052a6b89552db14d0a0a45554156f085a912f48", size = 1629103, upload-time = "2025-06-14T15:15:25.209Z" }, { url = "https://files.pythonhosted.org/packages/fb/fe/f9540bf12fa443d8870ecab70260c02140ed8b4c37884a2e1050bdd689a2/aiohttp-3.12.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:5304d74867028cca8f64f1cc1215eb365388033c5a691ea7aa6b0dc47412f495", size = 1605745, upload-time = "2025-06-14T15:15:27.604Z" }, { url = "https://files.pythonhosted.org/packages/91/d7/526f1d16ca01e0c995887097b31e39c2e350dc20c1071e9b2dcf63a86fcd/aiohttp-3.12.13-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:64d1f24ee95a2d1e094a4cd7a9b7d34d08db1bbcb8aa9fb717046b0a884ac294", size = 1693348, upload-time = "2025-06-14T15:15:30.151Z" }, { url = "https://files.pythonhosted.org/packages/cd/0a/c103fdaab6fbde7c5f10450b5671dca32cea99800b1303ee8194a799bbb9/aiohttp-3.12.13-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:119c79922a7001ca6a9e253228eb39b793ea994fd2eccb79481c64b5f9d2a055", size = 1709023, upload-time = "2025-06-14T15:15:32.881Z" }, { url = "https://files.pythonhosted.org/packages/2f/bc/b8d14e754b5e0bf9ecf6df4b930f2cbd6eaaafcdc1b2f9271968747fb6e3/aiohttp-3.12.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:bb18f00396d22e2f10cd8825d671d9f9a3ba968d708a559c02a627536b36d91c", size = 1638691, upload-time = "2025-06-14T15:15:35.033Z" }, { url = "https://files.pythonhosted.org/packages/a4/7b/44b77bf4c48d95d81af5c57e79337d0d51350a85a84e9997a99a6205c441/aiohttp-3.12.13-cp39-cp39-win32.whl", hash = "sha256:0022de47ef63fd06b065d430ac79c6b0bd24cdae7feaf0e8c6bac23b805a23a8", size = 428365, upload-time = "2025-06-14T15:15:37.369Z" }, { url = "https://files.pythonhosted.org/packages/e5/cb/aaa022eb993e7d51928dc22d743ed17addb40142250e829701c5e6679615/aiohttp-3.12.13-cp39-cp39-win_amd64.whl", hash = "sha256:29e08111ccf81b2734ae03f1ad1cb03b9615e7d8f616764f22f71209c094f122", size = 451652, upload-time = "2025-06-14T15:15:39.079Z" }, ] [[package]] name = "aiosignal" version = "1.3.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] dependencies = [ { name = "frozenlist", version = "1.5.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ae/67/0952ed97a9793b4958e5736f6d2b346b414a2cd63e82d05940032f45b32f/aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc", size = 19422, upload-time = "2022-11-08T16:03:58.806Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/76/ac/a7305707cb852b7e16ff80eaf5692309bde30e2b1100a1fcacdc8f731d97/aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17", size = 7617, upload-time = "2022-11-08T16:03:57.483Z" }, ] [[package]] name = "aiosignal" version = "1.4.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.10'", "python_full_version == '3.9.*'", ] dependencies = [ { name = "frozenlist", version = "1.7.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "typing-extensions", marker = "(python_full_version >= '3.9' and python_full_version < '3.13') or (python_full_version < '3.9' and extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2') or (python_full_version >= '3.13' and extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-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" } dependencies = [ { name = "typing-extensions", marker = "(python_full_version < '3.9' and extra != 'group-9-anthropic-pydantic-v1') or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] 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 = "anthropic" version = "0.68.0" source = { editable = "." } dependencies = [ { name = "anyio", version = "4.5.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "anyio", version = "4.8.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "distro" }, { name = "docstring-parser" }, { name = "httpx" }, { name = "jiter", version = "0.9.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "jiter", version = "0.11.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "pydantic", version = "1.10.23", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'group-9-anthropic-pydantic-v1'" }, { name = "pydantic", version = "2.10.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.9' and extra != 'group-9-anthropic-pydantic-v1') or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "pydantic", version = "2.11.9", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.9' and extra != 'group-9-anthropic-pydantic-v1') or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "sniffio" }, { name = "typing-extensions" }, ] [package.optional-dependencies] aiohttp = [ { name = "aiohttp", version = "3.10.11", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "aiohttp", version = "3.12.13", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "httpx-aiohttp" }, ] bedrock = [ { name = "boto3", version = "1.37.38", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "boto3", version = "1.40.31", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "botocore", version = "1.37.38", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "botocore", version = "1.40.31", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] vertex = [ { name = "google-auth", extra = ["requests"] }, ] [package.dev-dependencies] dev = [ { name = "boto3-stubs" }, { name = "dirty-equals" }, { name = "griffe", version = "1.4.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "griffe", version = "1.13.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "importlib-metadata", version = "8.5.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "importlib-metadata", version = "8.6.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "inline-snapshot" }, { name = "mypy" }, { name = "pyright" }, { name = "pytest", version = "8.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "pytest", version = "8.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "pytest-asyncio" }, { name = "pytest-xdist", version = "3.6.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "pytest-xdist", version = "3.7.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "respx" }, { name = "rich" }, { name = "ruff" }, { name = "time-machine", version = "2.15.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "time-machine", version = "2.16.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] pydantic-v1 = [ { name = "pydantic", version = "1.10.23", source = { registry = "https://pypi.org/simple" } }, ] pydantic-v2 = [ { name = "pydantic", version = "2.10.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.9' and extra == 'group-9-anthropic-pydantic-v2') or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "pydantic", version = "2.11.9", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.9' and extra == 'group-9-anthropic-pydantic-v2') or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] [package.metadata] requires-dist = [ { name = "aiohttp", marker = "extra == 'aiohttp'" }, { name = "anyio", specifier = ">=3.5.0,<5" }, { name = "boto3", marker = "extra == 'bedrock'", specifier = ">=1.28.57" }, { name = "botocore", marker = "extra == 'bedrock'", specifier = ">=1.31.57" }, { name = "distro", specifier = ">=1.7.0,<2" }, { name = "docstring-parser", specifier = ">=0.15,<1" }, { name = "google-auth", extras = ["requests"], marker = "extra == 'vertex'", specifier = ">=2,<3" }, { name = "httpx", specifier = ">=0.25.0,<1" }, { name = "httpx-aiohttp", marker = "extra == 'aiohttp'", specifier = ">=0.1.8" }, { name = "jiter", specifier = ">=0.4.0,<1" }, { name = "pydantic", specifier = ">=1.9.0,<3" }, { name = "sniffio" }, { name = "typing-extensions", specifier = ">=4.10,<5" }, ] provides-extras = ["aiohttp", "vertex", "bedrock"] [package.metadata.requires-dev] dev = [ { name = "boto3-stubs", specifier = ">=1" }, { name = "dirty-equals", specifier = ">=0.6.0" }, { name = "griffe", specifier = ">=1" }, { name = "importlib-metadata", specifier = ">=6.7.0" }, { name = "inline-snapshot", specifier = ">=0.28.0" }, { name = "mypy" }, { 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", specifier = ">=2,<3" }] [[package]] name = "anyio" version = "4.5.2" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] dependencies = [ { name = "exceptiongroup", marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "idna", marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "sniffio", marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "typing-extensions", marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/4d/f9/9a7ce600ebe7804daf90d4d48b1c0510a4561ddce43a596be46676f82343/anyio-4.5.2.tar.gz", hash = "sha256:23009af4ed04ce05991845451e11ef02fc7c5ed29179ac9a420e5ad0ac7ddc5b", size = 171293, upload-time = "2024-10-13T22:18:03.307Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/1b/b4/f7e396030e3b11394436358ca258a81d6010106582422f23443c16ca1873/anyio-4.5.2-py3-none-any.whl", hash = "sha256:c011ee36bc1e8ba40e5a81cb9df91925c218fe9b778554e0b56a21e1b5d4716f", size = 89766, upload-time = "2024-10-13T22:18:01.524Z" }, ] [[package]] name = "anyio" version = "4.8.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.10'", "python_full_version == '3.9.*'", ] dependencies = [ { name = "exceptiongroup", marker = "(python_full_version >= '3.9' and python_full_version < '3.11') or (python_full_version < '3.9' and extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2') or (python_full_version >= '3.11' and extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "idna", marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "sniffio", marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "typing-extensions", marker = "(python_full_version >= '3.9' and python_full_version < '3.13') or (python_full_version < '3.9' and extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2') or (python_full_version >= '3.13' and extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a3/73/199a98fc2dae33535d6b8e8e6ec01f8c1d76c9adb096c6b7d64823038cde/anyio-4.8.0.tar.gz", hash = "sha256:1d9fe889df5212298c0c0723fa20479d1b94883a2df44bd3897aa91083316f7a", size = 181126, upload-time = "2025-01-05T13:13:11.095Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/46/eb/e7f063ad1fec6b3178a3cd82d1a3c4de82cccf283fc42746168188e1cdd5/anyio-4.8.0-py3-none-any.whl", hash = "sha256:b5011f270ab5eb0abf13385f851315585cc37ef330dd88e27ec3d34d651fd47a", size = 96041, upload-time = "2025-01-05T13:13:07.985Z" }, ] [[package]] name = "asttokens" version = "3.0.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/4a/e7/82da0a03e7ba5141f05cce0d302e6eed121ae055e0456ca228bf693984bc/asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7", size = 61978, upload-time = "2024-11-30T04:30:14.439Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/25/8a/c46dcc25341b5bce5472c718902eb3d38600a903b14fa6aeecef3f21a46f/asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2", size = 26918, upload-time = "2024-11-30T04:30:10.946Z" }, ] [[package]] name = "astunparse" version = "1.6.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "six", marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "wheel", marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/f3/af/4182184d3c338792894f34a62672919db7ca008c89abee9b564dd34d8029/astunparse-1.6.3.tar.gz", hash = "sha256:5ad93a8456f0d084c3456d059fd9a92cce667963232cbf763eac3bc5b7940872", size = 18290, upload-time = "2019-12-22T18:12:13.129Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/2b/03/13dde6512ad7b4557eb792fbcf0c653af6076b81e5941d36ec61f7ce6028/astunparse-1.6.3-py2.py3-none-any.whl", hash = "sha256:c2652417f2c8b5bb325c885ae329bdf3f86424075c4fd1a128674bc6fba4b8e8", size = 12732, upload-time = "2019-12-22T18:12:11.297Z" }, ] [[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.3.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/1367933a8532ee6ff8d63537de4f1177af4bff9f3e829baf7331f595bb24/attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b", size = 812032, upload-time = "2025-03-13T11:10:22.779Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815, upload-time = "2025-03-13T11:10:21.14Z" }, ] [[package]] name = "boto3" version = "1.37.38" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] dependencies = [ { name = "botocore", version = "1.37.38", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "jmespath", marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "s3transfer", version = "0.11.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0d/b5/d1c2e8c484cea43891629bbab6ca90ce9ca932586750bc0e786c8f096ccf/boto3-1.37.38.tar.gz", hash = "sha256:88c02910933ab7777597d1ca7c62375f52822e0aa1a8e0c51b2598a547af42b2", size = 111623, upload-time = "2025-04-21T19:27:18.06Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/d3/87/8189f22ee798177bc7b40afd13f046442c5f91b699e70a950b42ff447e80/boto3-1.37.38-py3-none-any.whl", hash = "sha256:b6d42803607148804dff82389757827a24ce9271f0583748853934c86310999f", size = 139922, upload-time = "2025-04-21T19:27:16.107Z" }, ] [[package]] name = "boto3" version = "1.40.31" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.10'", "python_full_version == '3.9.*'", ] dependencies = [ { name = "botocore", version = "1.40.31", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "jmespath", marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "s3transfer", version = "0.14.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/9c/e6/1a8b1710245aac792ea283051727f4e7f29b4bfb85fd887f4c25aa85b4eb/boto3-1.40.31.tar.gz", hash = "sha256:8c5f1270f09431694412f326cfb5ac9786d41ea3bc6ac54cbb7161d40afc660d", size = 111606, upload-time = "2025-09-15T19:38:46.136Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ee/79/22fd4a4a61cb87f893804d8a36a834c69849a8fe2b0d9e28c2676824bff1/boto3-1.40.31-py3-none-any.whl", hash = "sha256:61d5f9975c54ff919a24ff9d472c6c09c8a443a083fe56d30c04fc22d22ac42b", size = 139343, upload-time = "2025-09-15T19:38:44.707Z" }, ] [[package]] name = "boto3-stubs" version = "1.40.31" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore-stubs", version = "1.38.30", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "botocore-stubs", version = "1.40.31", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "types-s3transfer" }, { name = "typing-extensions", marker = "python_full_version < '3.12' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a7/94/daf916ec506f2b072fc6e11a321aa3f273de2c9fc56bc5b402e5f6c8cf32/boto3_stubs-1.40.31.tar.gz", hash = "sha256:99d26772365a807024a71c31ddf557a8bd042622e29a3a1f748d689f8cfb4f78", size = 100829, upload-time = "2025-09-15T19:42:37.405Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/5f/35/465583ffd358c541d5db4788df2d42081a6350e284498f1734ca9f2f4b7f/boto3_stubs-1.40.31-py3-none-any.whl", hash = "sha256:60f9ebf463880bd037b2c4bd44ec8281de90d7eabd9cd223c0f379823586a7f8", size = 69689, upload-time = "2025-09-15T19:42:29.171Z" }, ] [[package]] name = "botocore" version = "1.37.38" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] dependencies = [ { name = "jmespath", marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "python-dateutil", marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "urllib3", version = "1.26.20", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/34/79/4e072e614339727f79afef704e5993b5b4d2667c1671c757cc4deb954744/botocore-1.37.38.tar.gz", hash = "sha256:c3ea386177171f2259b284db6afc971c959ec103fa2115911c4368bea7cbbc5d", size = 13832365, upload-time = "2025-04-21T19:27:05.245Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/55/1b/93f3504afc7c523dcaa8a8147cfc75421983e30b08d9f93a533929589630/botocore-1.37.38-py3-none-any.whl", hash = "sha256:23b4097780e156a4dcaadfc1ed156ce25cb95b6087d010c4bb7f7f5d9bc9d219", size = 13499391, upload-time = "2025-04-21T19:27:00.869Z" }, ] [[package]] name = "botocore" version = "1.40.31" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.10'", "python_full_version == '3.9.*'", ] dependencies = [ { name = "jmespath", marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "python-dateutil", marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "urllib3", version = "1.26.20", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.9.*' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "urllib3", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/42/8a/6ed2ccd9f6b8930ed15e755667f8f5f32a568cf4e3bf31a8526dcf4ce562/botocore-1.40.31.tar.gz", hash = "sha256:9496b91bbe40ed01d341dc8f6ff0492d7f546e80f1a862b00ec5bc9045fa3324", size = 14340752, upload-time = "2025-09-15T19:38:35.659Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/42/98/0f6cfbc627a87d84cfc66ceb7d9b71d694313a32cddbe415b9f298c9e50b/botocore-1.40.31-py3-none-any.whl", hash = "sha256:4033a00f8c6a4b5c3acb30af9283963123917227a437e5fc165189d07bd3cf8a", size = 14013342, upload-time = "2025-09-15T19:38:32.098Z" }, ] [[package]] name = "botocore-stubs" version = "1.38.30" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] dependencies = [ { name = "types-awscrt", marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b2/df/9bf9f6346daf1cbcb736a12417efe025ed63d72a015799f4e8f26a823b93/botocore_stubs-1.38.30.tar.gz", hash = "sha256:291d7bf39a316c00a8a55b7255489b02c0cea1a343482e7784e8d1e235bae995", size = 42299, upload-time = "2025-06-04T20:14:50.799Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/98/71/cc9bc544489160cbacc8472b70ba0f9b93385628ed8bd0f673855b7ceeb7/botocore_stubs-1.38.30-py3-none-any.whl", hash = "sha256:2efb8bdf36504aff596c670d875d8f7dd15205277c15c4cea54afdba8200c266", size = 65628, upload-time = "2025-06-04T20:14:48.089Z" }, ] [[package]] name = "botocore-stubs" version = "1.40.31" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.10'", "python_full_version == '3.9.*'", ] dependencies = [ { name = "types-awscrt", marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a9/a2/31e023b1355cd6022784e27321fd898f0fd39a5f31647c3d5901f679d6db/botocore_stubs-1.40.31.tar.gz", hash = "sha256:017bcea5919242b67e80e6a271149d67cad1d06bd7adac5ab58e32299dba83dc", size = 42713, upload-time = "2025-09-15T20:25:36.273Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/a1/25/3b8ea2996a4fd6ee08d70a2627645f85ed53b668a7d8edc21821a172f7ad/botocore_stubs-1.40.31-py3-none-any.whl", hash = "sha256:a3fc8d12624bd867171745d21d2e11bd9d9a5cd142004ddc37d4594fc5d5c732", size = 66844, upload-time = "2025-09-15T20:25:34.469Z" }, ] [[package]] name = "cachetools" version = "5.5.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/6c/81/3747dad6b14fa2cf53fcf10548cf5aea6913e96fab41a3c198676f8948a5/cachetools-5.5.2.tar.gz", hash = "sha256:1a661caa9175d26759571b2e19580f9d6393969e5dfca11fdb1f947a23e640d4", size = 28380, upload-time = "2025-02-20T21:01:19.524Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/72/76/20fa66124dbe6be5cafeb312ece67de6b61dd91a0247d1ea13db4ebb33c2/cachetools-5.5.2-py3-none-any.whl", hash = "sha256:d26a22bcc62eb95c3beabd9f1ee5e820d3d2704fe2967cbe350e20c8ffcd3f0a", size = 10080, upload-time = "2025-02-20T21:01:16.647Z" }, ] [[package]] name = "certifi" version = "2024.12.14" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/0f/bd/1d41ee578ce09523c81a15426705dd20969f5abf006d1afe8aeff0dd776a/certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db", size = 166010, upload-time = "2024-12-14T13:52:38.02Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/a5/32/8f6669fc4798494966bf446c8c4a162e0b5d893dff088afddf76414f70e1/certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56", size = 164927, upload-time = "2024-12-14T13:52:36.114Z" }, ] [[package]] name = "charset-normalizer" version = "3.4.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/83/2d/5fd176ceb9b2fc619e63405525573493ca23441330fcdaee6bef9460e924/charset_normalizer-3.4.3.tar.gz", hash = "sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14", size = 122371, upload-time = "2025-08-09T07:57:28.46Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/d6/98/f3b8013223728a99b908c9344da3aa04ee6e3fa235f19409033eda92fb78/charset_normalizer-3.4.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fb7f67a1bfa6e40b438170ebdc8158b78dc465a5a67b6dde178a46987b244a72", size = 207695, upload-time = "2025-08-09T07:55:36.452Z" }, { url = "https://files.pythonhosted.org/packages/21/40/5188be1e3118c82dcb7c2a5ba101b783822cfb413a0268ed3be0468532de/charset_normalizer-3.4.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cc9370a2da1ac13f0153780040f465839e6cccb4a1e44810124b4e22483c93fe", size = 147153, upload-time = "2025-08-09T07:55:38.467Z" }, { url = "https://files.pythonhosted.org/packages/37/60/5d0d74bc1e1380f0b72c327948d9c2aca14b46a9efd87604e724260f384c/charset_normalizer-3.4.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:07a0eae9e2787b586e129fdcbe1af6997f8d0e5abaa0bc98c0e20e124d67e601", size = 160428, upload-time = "2025-08-09T07:55:40.072Z" }, { url = "https://files.pythonhosted.org/packages/85/9a/d891f63722d9158688de58d050c59dc3da560ea7f04f4c53e769de5140f5/charset_normalizer-3.4.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:74d77e25adda8581ffc1c720f1c81ca082921329452eba58b16233ab1842141c", size = 157627, upload-time = "2025-08-09T07:55:41.706Z" }, { url = "https://files.pythonhosted.org/packages/65/1a/7425c952944a6521a9cfa7e675343f83fd82085b8af2b1373a2409c683dc/charset_normalizer-3.4.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d0e909868420b7049dafd3a31d45125b31143eec59235311fc4c57ea26a4acd2", size = 152388, upload-time = "2025-08-09T07:55:43.262Z" }, { url = "https://files.pythonhosted.org/packages/f0/c9/a2c9c2a355a8594ce2446085e2ec97fd44d323c684ff32042e2a6b718e1d/charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c6f162aabe9a91a309510d74eeb6507fab5fff92337a15acbe77753d88d9dcf0", size = 150077, upload-time = "2025-08-09T07:55:44.903Z" }, { url = "https://files.pythonhosted.org/packages/3b/38/20a1f44e4851aa1c9105d6e7110c9d020e093dfa5836d712a5f074a12bf7/charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4ca4c094de7771a98d7fbd67d9e5dbf1eb73efa4f744a730437d8a3a5cf994f0", size = 161631, upload-time = "2025-08-09T07:55:46.346Z" }, { url = "https://files.pythonhosted.org/packages/a4/fa/384d2c0f57edad03d7bec3ebefb462090d8905b4ff5a2d2525f3bb711fac/charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:02425242e96bcf29a49711b0ca9f37e451da7c70562bc10e8ed992a5a7a25cc0", size = 159210, upload-time = "2025-08-09T07:55:47.539Z" }, { url = "https://files.pythonhosted.org/packages/33/9e/eca49d35867ca2db336b6ca27617deed4653b97ebf45dfc21311ce473c37/charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:78deba4d8f9590fe4dae384aeff04082510a709957e968753ff3c48399f6f92a", size = 153739, upload-time = "2025-08-09T07:55:48.744Z" }, { url = "https://files.pythonhosted.org/packages/2a/91/26c3036e62dfe8de8061182d33be5025e2424002125c9500faff74a6735e/charset_normalizer-3.4.3-cp310-cp310-win32.whl", hash = "sha256:d79c198e27580c8e958906f803e63cddb77653731be08851c7df0b1a14a8fc0f", size = 99825, upload-time = "2025-08-09T07:55:50.305Z" }, { url = "https://files.pythonhosted.org/packages/e2/c6/f05db471f81af1fa01839d44ae2a8bfeec8d2a8b4590f16c4e7393afd323/charset_normalizer-3.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:c6e490913a46fa054e03699c70019ab869e990270597018cef1d8562132c2669", size = 107452, upload-time = "2025-08-09T07:55:51.461Z" }, { url = "https://files.pythonhosted.org/packages/7f/b5/991245018615474a60965a7c9cd2b4efbaabd16d582a5547c47ee1c7730b/charset_normalizer-3.4.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b256ee2e749283ef3ddcff51a675ff43798d92d746d1a6e4631bf8c707d22d0b", size = 204483, upload-time = "2025-08-09T07:55:53.12Z" }, { url = "https://files.pythonhosted.org/packages/c7/2a/ae245c41c06299ec18262825c1569c5d3298fc920e4ddf56ab011b417efd/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:13faeacfe61784e2559e690fc53fa4c5ae97c6fcedb8eb6fb8d0a15b475d2c64", size = 145520, upload-time = "2025-08-09T07:55:54.712Z" }, { url = "https://files.pythonhosted.org/packages/3a/a4/b3b6c76e7a635748c4421d2b92c7b8f90a432f98bda5082049af37ffc8e3/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:00237675befef519d9af72169d8604a067d92755e84fe76492fef5441db05b91", size = 158876, upload-time = "2025-08-09T07:55:56.024Z" }, { url = "https://files.pythonhosted.org/packages/e2/e6/63bb0e10f90a8243c5def74b5b105b3bbbfb3e7bb753915fe333fb0c11ea/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:585f3b2a80fbd26b048a0be90c5aae8f06605d3c92615911c3a2b03a8a3b796f", size = 156083, upload-time = "2025-08-09T07:55:57.582Z" }, { url = "https://files.pythonhosted.org/packages/87/df/b7737ff046c974b183ea9aa111b74185ac8c3a326c6262d413bd5a1b8c69/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e78314bdc32fa80696f72fa16dc61168fda4d6a0c014e0380f9d02f0e5d8a07", size = 150295, upload-time = "2025-08-09T07:55:59.147Z" }, { url = "https://files.pythonhosted.org/packages/61/f1/190d9977e0084d3f1dc169acd060d479bbbc71b90bf3e7bf7b9927dec3eb/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:96b2b3d1a83ad55310de8c7b4a2d04d9277d5591f40761274856635acc5fcb30", size = 148379, upload-time = "2025-08-09T07:56:00.364Z" }, { url = "https://files.pythonhosted.org/packages/4c/92/27dbe365d34c68cfe0ca76f1edd70e8705d82b378cb54ebbaeabc2e3029d/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:939578d9d8fd4299220161fdd76e86c6a251987476f5243e8864a7844476ba14", size = 160018, upload-time = "2025-08-09T07:56:01.678Z" }, { url = "https://files.pythonhosted.org/packages/99/04/baae2a1ea1893a01635d475b9261c889a18fd48393634b6270827869fa34/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:fd10de089bcdcd1be95a2f73dbe6254798ec1bda9f450d5828c96f93e2536b9c", size = 157430, upload-time = "2025-08-09T07:56:02.87Z" }, { url = "https://files.pythonhosted.org/packages/2f/36/77da9c6a328c54d17b960c89eccacfab8271fdaaa228305330915b88afa9/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1e8ac75d72fa3775e0b7cb7e4629cec13b7514d928d15ef8ea06bca03ef01cae", size = 151600, upload-time = "2025-08-09T07:56:04.089Z" }, { url = "https://files.pythonhosted.org/packages/64/d4/9eb4ff2c167edbbf08cdd28e19078bf195762e9bd63371689cab5ecd3d0d/charset_normalizer-3.4.3-cp311-cp311-win32.whl", hash = "sha256:6cf8fd4c04756b6b60146d98cd8a77d0cdae0e1ca20329da2ac85eed779b6849", size = 99616, upload-time = "2025-08-09T07:56:05.658Z" }, { url = "https://files.pythonhosted.org/packages/f4/9c/996a4a028222e7761a96634d1820de8a744ff4327a00ada9c8942033089b/charset_normalizer-3.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:31a9a6f775f9bcd865d88ee350f0ffb0e25936a7f930ca98995c05abf1faf21c", size = 107108, upload-time = "2025-08-09T07:56:07.176Z" }, { url = "https://files.pythonhosted.org/packages/e9/5e/14c94999e418d9b87682734589404a25854d5f5d0408df68bc15b6ff54bb/charset_normalizer-3.4.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1", size = 205655, upload-time = "2025-08-09T07:56:08.475Z" }, { url = "https://files.pythonhosted.org/packages/7d/a8/c6ec5d389672521f644505a257f50544c074cf5fc292d5390331cd6fc9c3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884", size = 146223, upload-time = "2025-08-09T07:56:09.708Z" }, { url = "https://files.pythonhosted.org/packages/fc/eb/a2ffb08547f4e1e5415fb69eb7db25932c52a52bed371429648db4d84fb1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018", size = 159366, upload-time = "2025-08-09T07:56:11.326Z" }, { url = "https://files.pythonhosted.org/packages/82/10/0fd19f20c624b278dddaf83b8464dcddc2456cb4b02bb902a6da126b87a1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392", size = 157104, upload-time = "2025-08-09T07:56:13.014Z" }, { url = "https://files.pythonhosted.org/packages/16/ab/0233c3231af734f5dfcf0844aa9582d5a1466c985bbed6cedab85af9bfe3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f", size = 151830, upload-time = "2025-08-09T07:56:14.428Z" }, { url = "https://files.pythonhosted.org/packages/ae/02/e29e22b4e02839a0e4a06557b1999d0a47db3567e82989b5bb21f3fbbd9f/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154", size = 148854, upload-time = "2025-08-09T07:56:16.051Z" }, { url = "https://files.pythonhosted.org/packages/05/6b/e2539a0a4be302b481e8cafb5af8792da8093b486885a1ae4d15d452bcec/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491", size = 160670, upload-time = "2025-08-09T07:56:17.314Z" }, { url = "https://files.pythonhosted.org/packages/31/e7/883ee5676a2ef217a40ce0bffcc3d0dfbf9e64cbcfbdf822c52981c3304b/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93", size = 158501, upload-time = "2025-08-09T07:56:18.641Z" }, { url = "https://files.pythonhosted.org/packages/c1/35/6525b21aa0db614cf8b5792d232021dca3df7f90a1944db934efa5d20bb1/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f", size = 153173, upload-time = "2025-08-09T07:56:20.289Z" }, { url = "https://files.pythonhosted.org/packages/50/ee/f4704bad8201de513fdc8aac1cabc87e38c5818c93857140e06e772b5892/charset_normalizer-3.4.3-cp312-cp312-win32.whl", hash = "sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37", size = 99822, upload-time = "2025-08-09T07:56:21.551Z" }, { url = "https://files.pythonhosted.org/packages/39/f5/3b3836ca6064d0992c58c7561c6b6eee1b3892e9665d650c803bd5614522/charset_normalizer-3.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc", size = 107543, upload-time = "2025-08-09T07:56:23.115Z" }, { url = "https://files.pythonhosted.org/packages/65/ca/2135ac97709b400c7654b4b764daf5c5567c2da45a30cdd20f9eefe2d658/charset_normalizer-3.4.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe", size = 205326, upload-time = "2025-08-09T07:56:24.721Z" }, { url = "https://files.pythonhosted.org/packages/71/11/98a04c3c97dd34e49c7d247083af03645ca3730809a5509443f3c37f7c99/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8", size = 146008, upload-time = "2025-08-09T07:56:26.004Z" }, { url = "https://files.pythonhosted.org/packages/60/f5/4659a4cb3c4ec146bec80c32d8bb16033752574c20b1252ee842a95d1a1e/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9", size = 159196, upload-time = "2025-08-09T07:56:27.25Z" }, { url = "https://files.pythonhosted.org/packages/86/9e/f552f7a00611f168b9a5865a1414179b2c6de8235a4fa40189f6f79a1753/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:30d006f98569de3459c2fc1f2acde170b7b2bd265dc1943e87e1a4efe1b67c31", size = 156819, upload-time = "2025-08-09T07:56:28.515Z" }, { url = "https://files.pythonhosted.org/packages/7e/95/42aa2156235cbc8fa61208aded06ef46111c4d3f0de233107b3f38631803/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f", size = 151350, upload-time = "2025-08-09T07:56:29.716Z" }, { url = "https://files.pythonhosted.org/packages/c2/a9/3865b02c56f300a6f94fc631ef54f0a8a29da74fb45a773dfd3dcd380af7/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6aab0f181c486f973bc7262a97f5aca3ee7e1437011ef0c2ec04b5a11d16c927", size = 148644, upload-time = "2025-08-09T07:56:30.984Z" }, { url = "https://files.pythonhosted.org/packages/77/d9/cbcf1a2a5c7d7856f11e7ac2d782aec12bdfea60d104e60e0aa1c97849dc/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabf8315679312cfa71302f9bd509ded4f2f263fb5b765cf1433b39106c3cc9", size = 160468, upload-time = "2025-08-09T07:56:32.252Z" }, { url = "https://files.pythonhosted.org/packages/f6/42/6f45efee8697b89fda4d50580f292b8f7f9306cb2971d4b53f8914e4d890/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:bd28b817ea8c70215401f657edef3a8aa83c29d447fb0b622c35403780ba11d5", size = 158187, upload-time = "2025-08-09T07:56:33.481Z" }, { url = "https://files.pythonhosted.org/packages/70/99/f1c3bdcfaa9c45b3ce96f70b14f070411366fa19549c1d4832c935d8e2c3/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:18343b2d246dc6761a249ba1fb13f9ee9a2bcd95decc767319506056ea4ad4dc", size = 152699, upload-time = "2025-08-09T07:56:34.739Z" }, { url = "https://files.pythonhosted.org/packages/a3/ad/b0081f2f99a4b194bcbb1934ef3b12aa4d9702ced80a37026b7607c72e58/charset_normalizer-3.4.3-cp313-cp313-win32.whl", hash = "sha256:6fb70de56f1859a3f71261cbe41005f56a7842cc348d3aeb26237560bfa5e0ce", size = 99580, upload-time = "2025-08-09T07:56:35.981Z" }, { url = "https://files.pythonhosted.org/packages/9a/8f/ae790790c7b64f925e5c953b924aaa42a243fb778fed9e41f147b2a5715a/charset_normalizer-3.4.3-cp313-cp313-win_amd64.whl", hash = "sha256:cf1ebb7d78e1ad8ec2a8c4732c7be2e736f6e5123a4146c5b89c9d1f585f8cef", size = 107366, upload-time = "2025-08-09T07:56:37.339Z" }, { url = "https://files.pythonhosted.org/packages/8e/91/b5a06ad970ddc7a0e513112d40113e834638f4ca1120eb727a249fb2715e/charset_normalizer-3.4.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3cd35b7e8aedeb9e34c41385fda4f73ba609e561faedfae0a9e75e44ac558a15", size = 204342, upload-time = "2025-08-09T07:56:38.687Z" }, { url = "https://files.pythonhosted.org/packages/ce/ec/1edc30a377f0a02689342f214455c3f6c2fbedd896a1d2f856c002fc3062/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b89bc04de1d83006373429975f8ef9e7932534b8cc9ca582e4db7d20d91816db", size = 145995, upload-time = "2025-08-09T07:56:40.048Z" }, { url = "https://files.pythonhosted.org/packages/17/e5/5e67ab85e6d22b04641acb5399c8684f4d37caf7558a53859f0283a650e9/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2001a39612b241dae17b4687898843f254f8748b796a2e16f1051a17078d991d", size = 158640, upload-time = "2025-08-09T07:56:41.311Z" }, { url = "https://files.pythonhosted.org/packages/f1/e5/38421987f6c697ee3722981289d554957c4be652f963d71c5e46a262e135/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8dcfc373f888e4fb39a7bc57e93e3b845e7f462dacc008d9749568b1c4ece096", size = 156636, upload-time = "2025-08-09T07:56:43.195Z" }, { url = "https://files.pythonhosted.org/packages/a0/e4/5a075de8daa3ec0745a9a3b54467e0c2967daaaf2cec04c845f73493e9a1/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18b97b8404387b96cdbd30ad660f6407799126d26a39ca65729162fd810a99aa", size = 150939, upload-time = "2025-08-09T07:56:44.819Z" }, { url = "https://files.pythonhosted.org/packages/02/f7/3611b32318b30974131db62b4043f335861d4d9b49adc6d57c1149cc49d4/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ccf600859c183d70eb47e05a44cd80a4ce77394d1ac0f79dbd2dd90a69a3a049", size = 148580, upload-time = "2025-08-09T07:56:46.684Z" }, { url = "https://files.pythonhosted.org/packages/7e/61/19b36f4bd67f2793ab6a99b979b4e4f3d8fc754cbdffb805335df4337126/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:53cd68b185d98dde4ad8990e56a58dea83a4162161b1ea9272e5c9182ce415e0", size = 159870, upload-time = "2025-08-09T07:56:47.941Z" }, { url = "https://files.pythonhosted.org/packages/06/57/84722eefdd338c04cf3030ada66889298eaedf3e7a30a624201e0cbe424a/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:30a96e1e1f865f78b030d65241c1ee850cdf422d869e9028e2fc1d5e4db73b92", size = 157797, upload-time = "2025-08-09T07:56:49.756Z" }, { url = "https://files.pythonhosted.org/packages/72/2a/aff5dd112b2f14bcc3462c312dce5445806bfc8ab3a7328555da95330e4b/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16", size = 152224, upload-time = "2025-08-09T07:56:51.369Z" }, { url = "https://files.pythonhosted.org/packages/b7/8c/9839225320046ed279c6e839d51f028342eb77c91c89b8ef2549f951f3ec/charset_normalizer-3.4.3-cp314-cp314-win32.whl", hash = "sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce", size = 100086, upload-time = "2025-08-09T07:56:52.722Z" }, { url = "https://files.pythonhosted.org/packages/ee/7a/36fbcf646e41f710ce0a563c1c9a343c6edf9be80786edeb15b6f62e17db/charset_normalizer-3.4.3-cp314-cp314-win_amd64.whl", hash = "sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c", size = 107400, upload-time = "2025-08-09T07:56:55.172Z" }, { url = "https://files.pythonhosted.org/packages/22/82/63a45bfc36f73efe46731a3a71cb84e2112f7e0b049507025ce477f0f052/charset_normalizer-3.4.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0f2be7e0cf7754b9a30eb01f4295cc3d4358a479843b31f328afd210e2c7598c", size = 198805, upload-time = "2025-08-09T07:56:56.496Z" }, { url = "https://files.pythonhosted.org/packages/0c/52/8b0c6c3e53f7e546a5e49b9edb876f379725914e1130297f3b423c7b71c5/charset_normalizer-3.4.3-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c60e092517a73c632ec38e290eba714e9627abe9d301c8c8a12ec32c314a2a4b", size = 142862, upload-time = "2025-08-09T07:56:57.751Z" }, { url = "https://files.pythonhosted.org/packages/59/c0/a74f3bd167d311365e7973990243f32c35e7a94e45103125275b9e6c479f/charset_normalizer-3.4.3-cp38-cp38-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:252098c8c7a873e17dd696ed98bbe91dbacd571da4b87df3736768efa7a792e4", size = 155104, upload-time = "2025-08-09T07:56:58.984Z" }, { url = "https://files.pythonhosted.org/packages/1a/79/ae516e678d6e32df2e7e740a7be51dc80b700e2697cb70054a0f1ac2c955/charset_normalizer-3.4.3-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3653fad4fe3ed447a596ae8638b437f827234f01a8cd801842e43f3d0a6b281b", size = 152598, upload-time = "2025-08-09T07:57:00.201Z" }, { url = "https://files.pythonhosted.org/packages/00/bd/ef9c88464b126fa176f4ef4a317ad9b6f4d30b2cffbc43386062367c3e2c/charset_normalizer-3.4.3-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8999f965f922ae054125286faf9f11bc6932184b93011d138925a1773830bbe9", size = 147391, upload-time = "2025-08-09T07:57:01.441Z" }, { url = "https://files.pythonhosted.org/packages/7a/03/cbb6fac9d3e57f7e07ce062712ee80d80a5ab46614684078461917426279/charset_normalizer-3.4.3-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d95bfb53c211b57198bb91c46dd5a2d8018b3af446583aab40074bf7988401cb", size = 145037, upload-time = "2025-08-09T07:57:02.638Z" }, { url = "https://files.pythonhosted.org/packages/64/d1/f9d141c893ef5d4243bc75c130e95af8fd4bc355beff06e9b1e941daad6e/charset_normalizer-3.4.3-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:5b413b0b1bfd94dbf4023ad6945889f374cd24e3f62de58d6bb102c4d9ae534a", size = 156425, upload-time = "2025-08-09T07:57:03.898Z" }, { url = "https://files.pythonhosted.org/packages/c5/35/9c99739250742375167bc1b1319cd1cec2bf67438a70d84b2e1ec4c9daa3/charset_normalizer-3.4.3-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:b5e3b2d152e74e100a9e9573837aba24aab611d39428ded46f4e4022ea7d1942", size = 153734, upload-time = "2025-08-09T07:57:05.549Z" }, { url = "https://files.pythonhosted.org/packages/50/10/c117806094d2c956ba88958dab680574019abc0c02bcf57b32287afca544/charset_normalizer-3.4.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:a2d08ac246bb48479170408d6c19f6385fa743e7157d716e144cad849b2dd94b", size = 148551, upload-time = "2025-08-09T07:57:06.823Z" }, { url = "https://files.pythonhosted.org/packages/61/c5/dc3ba772489c453621ffc27e8978a98fe7e41a93e787e5e5bde797f1dddb/charset_normalizer-3.4.3-cp38-cp38-win32.whl", hash = "sha256:ec557499516fc90fd374bf2e32349a2887a876fbf162c160e3c01b6849eaf557", size = 98459, upload-time = "2025-08-09T07:57:08.031Z" }, { url = "https://files.pythonhosted.org/packages/05/35/bb59b1cd012d7196fc81c2f5879113971efc226a63812c9cf7f89fe97c40/charset_normalizer-3.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:5d8d01eac18c423815ed4f4a2ec3b439d654e55ee4ad610e153cf02faf67ea40", size = 105887, upload-time = "2025-08-09T07:57:09.401Z" }, { url = "https://files.pythonhosted.org/packages/c2/ca/9a0983dd5c8e9733565cf3db4df2b0a2e9a82659fd8aa2a868ac6e4a991f/charset_normalizer-3.4.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:70bfc5f2c318afece2f5838ea5e4c3febada0be750fcf4775641052bbba14d05", size = 207520, upload-time = "2025-08-09T07:57:11.026Z" }, { url = "https://files.pythonhosted.org/packages/39/c6/99271dc37243a4f925b09090493fb96c9333d7992c6187f5cfe5312008d2/charset_normalizer-3.4.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:23b6b24d74478dc833444cbd927c338349d6ae852ba53a0d02a2de1fce45b96e", size = 147307, upload-time = "2025-08-09T07:57:12.4Z" }, { url = "https://files.pythonhosted.org/packages/e4/69/132eab043356bba06eb333cc2cc60c6340857d0a2e4ca6dc2b51312886b3/charset_normalizer-3.4.3-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:34a7f768e3f985abdb42841e20e17b330ad3aaf4bb7e7aeeb73db2e70f077b99", size = 160448, upload-time = "2025-08-09T07:57:13.712Z" }, { url = "https://files.pythonhosted.org/packages/04/9a/914d294daa4809c57667b77470533e65def9c0be1ef8b4c1183a99170e9d/charset_normalizer-3.4.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fb731e5deb0c7ef82d698b0f4c5bb724633ee2a489401594c5c88b02e6cb15f7", size = 157758, upload-time = "2025-08-09T07:57:14.979Z" }, { url = "https://files.pythonhosted.org/packages/b0/a8/6f5bcf1bcf63cb45625f7c5cadca026121ff8a6c8a3256d8d8cd59302663/charset_normalizer-3.4.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:257f26fed7d7ff59921b78244f3cd93ed2af1800ff048c33f624c87475819dd7", size = 152487, upload-time = "2025-08-09T07:57:16.332Z" }, { url = "https://files.pythonhosted.org/packages/c4/72/d3d0e9592f4e504f9dea08b8db270821c909558c353dc3b457ed2509f2fb/charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1ef99f0456d3d46a50945c98de1774da86f8e992ab5c77865ea8b8195341fc19", size = 150054, upload-time = "2025-08-09T07:57:17.576Z" }, { url = "https://files.pythonhosted.org/packages/20/30/5f64fe3981677fe63fa987b80e6c01042eb5ff653ff7cec1b7bd9268e54e/charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:2c322db9c8c89009a990ef07c3bcc9f011a3269bc06782f916cd3d9eed7c9312", size = 161703, upload-time = "2025-08-09T07:57:20.012Z" }, { url = "https://files.pythonhosted.org/packages/e1/ef/dd08b2cac9284fd59e70f7d97382c33a3d0a926e45b15fc21b3308324ffd/charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:511729f456829ef86ac41ca78c63a5cb55240ed23b4b737faca0eb1abb1c41bc", size = 159096, upload-time = "2025-08-09T07:57:21.329Z" }, { url = "https://files.pythonhosted.org/packages/45/8c/dcef87cfc2b3f002a6478f38906f9040302c68aebe21468090e39cde1445/charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:88ab34806dea0671532d3f82d82b85e8fc23d7b2dd12fa837978dad9bb392a34", size = 153852, upload-time = "2025-08-09T07:57:22.608Z" }, { url = "https://files.pythonhosted.org/packages/63/86/9cbd533bd37883d467fcd1bd491b3547a3532d0fbb46de2b99feeebf185e/charset_normalizer-3.4.3-cp39-cp39-win32.whl", hash = "sha256:16a8770207946ac75703458e2c743631c79c59c5890c80011d536248f8eaa432", size = 99840, upload-time = "2025-08-09T07:57:23.883Z" }, { url = "https://files.pythonhosted.org/packages/ce/d6/7e805c8e5c46ff9729c49950acc4ee0aeb55efb8b3a56687658ad10c3216/charset_normalizer-3.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:d22dbedd33326a4a5190dd4fe9e9e693ef12160c77382d9e87919bce54f3d4ca", size = 107438, upload-time = "2025-08-09T07:57:25.287Z" }, { url = "https://files.pythonhosted.org/packages/8a/1f/f041989e93b001bc4e44bb1669ccdcf54d3f00e628229a85b08d330615c5/charset_normalizer-3.4.3-py3-none-any.whl", hash = "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a", size = 53175, upload-time = "2025-08-09T07:57:26.864Z" }, ] [[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.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytz", marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b0/99/133892f401ced5a27e641a473c547d5fbdb39af8f85dac8a9d633ea3e7a7/dirty_equals-0.9.0.tar.gz", hash = "sha256:17f515970b04ed7900b733c95fd8091f4f85e52f1fb5f268757f25c858eb1f7b", size = 50412, upload-time = "2025-01-11T23:23:40.491Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/77/0c/03cc99bf3b6328604b10829de3460f2b2ad3373200c45665c38508e550c6/dirty_equals-0.9.0-py3-none-any.whl", hash = "sha256:ff4d027f5cfa1b69573af00f7ba9043ea652dbdce3fe5cbe828e478c7346db9c", size = 28226, upload-time = "2025-01-11T23:23:37.489Z" }, ] [[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 = "docstring-parser" version = "0.17.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/b2/9d/c3b43da9515bd270df0f80548d9944e389870713cc1fe2b8fb35fe2bcefd/docstring_parser-0.17.0.tar.gz", hash = "sha256:583de4a309722b3315439bb31d64ba3eebada841f2e2cee23b99df001434c912", size = 27442, upload-time = "2025-07-21T07:35:01.868Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/55/e2/2537ebcff11c1ee1ff17d8d0b6f4db75873e3b0fb32c2d4a2ee31ecb310a/docstring_parser-0.17.0-py3-none-any.whl", hash = "sha256:cf2569abd23dce8099b300f9b4fa8191e9582dda731fd533daf54c4551658708", size = 36896, upload-time = "2025-07-21T07:35:00.684Z" }, ] [[package]] name = "exceptiongroup" version = "1.2.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883, upload-time = "2024-07-12T22:26:00.161Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453, upload-time = "2024-07-12T22:25:58.476Z" }, ] [[package]] name = "execnet" version = "2.1.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/bb/ff/b4c0dc78fbe20c3e59c0c7334de0c27eb4001a2b2017999af398bf730817/execnet-2.1.1.tar.gz", hash = "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3", size = 166524, upload-time = "2024-04-08T09:04:19.245Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/43/09/2aea36ff60d16dd8879bdb2f5b3ee0ba8d08cbbdcdfe870e695ce3784385/execnet-2.1.1-py3-none-any.whl", hash = "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc", size = 40612, upload-time = "2024-04-08T09:04:17.414Z" }, ] [[package]] name = "executing" version = "2.2.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/cc/28/c14e053b6762b1044f34a13aab6859bbf40456d37d23aa286ac24cfd9a5d/executing-2.2.1.tar.gz", hash = "sha256:3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4", size = 1129488, upload-time = "2025-09-01T09:48:10.866Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl", hash = "sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017", size = 28317, upload-time = "2025-09-01T09:48:08.5Z" }, ] [[package]] name = "frozenlist" version = "1.5.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] sdist = { url = "https://files.pythonhosted.org/packages/8f/ed/0f4cec13a93c02c47ec32d81d11c0c1efbadf4a471e3f3ce7cad366cbbd3/frozenlist-1.5.0.tar.gz", hash = "sha256:81d5af29e61b9c8348e876d442253723928dce6433e0e76cd925cd83f1b4b817", size = 39930, upload-time = "2024-10-23T09:48:29.903Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/54/79/29d44c4af36b2b240725dce566b20f63f9b36ef267aaaa64ee7466f4f2f8/frozenlist-1.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5b6a66c18b5b9dd261ca98dffcb826a525334b2f29e7caa54e182255c5f6a65a", size = 94451, upload-time = "2024-10-23T09:46:20.558Z" }, { url = "https://files.pythonhosted.org/packages/47/47/0c999aeace6ead8a44441b4f4173e2261b18219e4ad1fe9a479871ca02fc/frozenlist-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d1b3eb7b05ea246510b43a7e53ed1653e55c2121019a97e60cad7efb881a97bb", size = 54301, upload-time = "2024-10-23T09:46:21.759Z" }, { url = "https://files.pythonhosted.org/packages/8d/60/107a38c1e54176d12e06e9d4b5d755b677d71d1219217cee063911b1384f/frozenlist-1.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:15538c0cbf0e4fa11d1e3a71f823524b0c46299aed6e10ebb4c2089abd8c3bec", size = 52213, upload-time = "2024-10-23T09:46:22.993Z" }, { url = "https://files.pythonhosted.org/packages/17/62/594a6829ac5679c25755362a9dc93486a8a45241394564309641425d3ff6/frozenlist-1.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e79225373c317ff1e35f210dd5f1344ff31066ba8067c307ab60254cd3a78ad5", size = 240946, upload-time = "2024-10-23T09:46:24.661Z" }, { url = "https://files.pythonhosted.org/packages/7e/75/6c8419d8f92c80dd0ee3f63bdde2702ce6398b0ac8410ff459f9b6f2f9cb/frozenlist-1.5.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9272fa73ca71266702c4c3e2d4a28553ea03418e591e377a03b8e3659d94fa76", size = 264608, upload-time = "2024-10-23T09:46:26.017Z" }, { url = "https://files.pythonhosted.org/packages/88/3e/82a6f0b84bc6fb7e0be240e52863c6d4ab6098cd62e4f5b972cd31e002e8/frozenlist-1.5.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:498524025a5b8ba81695761d78c8dd7382ac0b052f34e66939c42df860b8ff17", size = 261361, upload-time = "2024-10-23T09:46:27.787Z" }, { url = "https://files.pythonhosted.org/packages/fd/85/14e5f9ccac1b64ff2f10c927b3ffdf88772aea875882406f9ba0cec8ad84/frozenlist-1.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:92b5278ed9d50fe610185ecd23c55d8b307d75ca18e94c0e7de328089ac5dcba", size = 231649, upload-time = "2024-10-23T09:46:28.992Z" }, { url = "https://files.pythonhosted.org/packages/ee/59/928322800306f6529d1852323014ee9008551e9bb027cc38d276cbc0b0e7/frozenlist-1.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f3c8c1dacd037df16e85227bac13cca58c30da836c6f936ba1df0c05d046d8d", size = 241853, upload-time = "2024-10-23T09:46:30.211Z" }, { url = "https://files.pythonhosted.org/packages/7d/bd/e01fa4f146a6f6c18c5d34cab8abdc4013774a26c4ff851128cd1bd3008e/frozenlist-1.5.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f2ac49a9bedb996086057b75bf93538240538c6d9b38e57c82d51f75a73409d2", size = 243652, upload-time = "2024-10-23T09:46:31.758Z" }, { url = "https://files.pythonhosted.org/packages/a5/bd/e4771fd18a8ec6757033f0fa903e447aecc3fbba54e3630397b61596acf0/frozenlist-1.5.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e66cc454f97053b79c2ab09c17fbe3c825ea6b4de20baf1be28919460dd7877f", size = 241734, upload-time = "2024-10-23T09:46:33.044Z" }, { url = "https://files.pythonhosted.org/packages/21/13/c83821fa5544af4f60c5d3a65d054af3213c26b14d3f5f48e43e5fb48556/frozenlist-1.5.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:5a3ba5f9a0dfed20337d3e966dc359784c9f96503674c2faf015f7fe8e96798c", size = 260959, upload-time = "2024-10-23T09:46:34.916Z" }, { url = "https://files.pythonhosted.org/packages/71/f3/1f91c9a9bf7ed0e8edcf52698d23f3c211d8d00291a53c9f115ceb977ab1/frozenlist-1.5.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6321899477db90bdeb9299ac3627a6a53c7399c8cd58d25da094007402b039ab", size = 262706, upload-time = "2024-10-23T09:46:36.159Z" }, { url = "https://files.pythonhosted.org/packages/4c/22/4a256fdf5d9bcb3ae32622c796ee5ff9451b3a13a68cfe3f68e2c95588ce/frozenlist-1.5.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:76e4753701248476e6286f2ef492af900ea67d9706a0155335a40ea21bf3b2f5", size = 250401, upload-time = "2024-10-23T09:46:37.327Z" }, { url = "https://files.pythonhosted.org/packages/af/89/c48ebe1f7991bd2be6d5f4ed202d94960c01b3017a03d6954dd5fa9ea1e8/frozenlist-1.5.0-cp310-cp310-win32.whl", hash = "sha256:977701c081c0241d0955c9586ffdd9ce44f7a7795df39b9151cd9a6fd0ce4cfb", size = 45498, upload-time = "2024-10-23T09:46:38.552Z" }, { url = "https://files.pythonhosted.org/packages/28/2f/cc27d5f43e023d21fe5c19538e08894db3d7e081cbf582ad5ed366c24446/frozenlist-1.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:189f03b53e64144f90990d29a27ec4f7997d91ed3d01b51fa39d2dbe77540fd4", size = 51622, upload-time = "2024-10-23T09:46:39.513Z" }, { url = "https://files.pythonhosted.org/packages/79/43/0bed28bf5eb1c9e4301003b74453b8e7aa85fb293b31dde352aac528dafc/frozenlist-1.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:fd74520371c3c4175142d02a976aee0b4cb4a7cc912a60586ffd8d5929979b30", size = 94987, upload-time = "2024-10-23T09:46:40.487Z" }, { url = "https://files.pythonhosted.org/packages/bb/bf/b74e38f09a246e8abbe1e90eb65787ed745ccab6eaa58b9c9308e052323d/frozenlist-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2f3f7a0fbc219fb4455264cae4d9f01ad41ae6ee8524500f381de64ffaa077d5", size = 54584, upload-time = "2024-10-23T09:46:41.463Z" }, { url = "https://files.pythonhosted.org/packages/2c/31/ab01375682f14f7613a1ade30149f684c84f9b8823a4391ed950c8285656/frozenlist-1.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f47c9c9028f55a04ac254346e92977bf0f166c483c74b4232bee19a6697e4778", size = 52499, upload-time = "2024-10-23T09:46:42.451Z" }, { url = "https://files.pythonhosted.org/packages/98/a8/d0ac0b9276e1404f58fec3ab6e90a4f76b778a49373ccaf6a563f100dfbc/frozenlist-1.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0996c66760924da6e88922756d99b47512a71cfd45215f3570bf1e0b694c206a", size = 276357, upload-time = "2024-10-23T09:46:44.166Z" }, { url = "https://files.pythonhosted.org/packages/ad/c9/c7761084fa822f07dac38ac29f841d4587570dd211e2262544aa0b791d21/frozenlist-1.5.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a2fe128eb4edeabe11896cb6af88fca5346059f6c8d807e3b910069f39157869", size = 287516, upload-time = "2024-10-23T09:46:45.369Z" }, { url = "https://files.pythonhosted.org/packages/a1/ff/cd7479e703c39df7bdab431798cef89dc75010d8aa0ca2514c5b9321db27/frozenlist-1.5.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a8ea951bbb6cacd492e3948b8da8c502a3f814f5d20935aae74b5df2b19cf3d", size = 283131, upload-time = "2024-10-23T09:46:46.654Z" }, { url = "https://files.pythonhosted.org/packages/59/a0/370941beb47d237eca4fbf27e4e91389fd68699e6f4b0ebcc95da463835b/frozenlist-1.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de537c11e4aa01d37db0d403b57bd6f0546e71a82347a97c6a9f0dcc532b3a45", size = 261320, upload-time = "2024-10-23T09:46:47.825Z" }, { url = "https://files.pythonhosted.org/packages/b8/5f/c10123e8d64867bc9b4f2f510a32042a306ff5fcd7e2e09e5ae5100ee333/frozenlist-1.5.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c2623347b933fcb9095841f1cc5d4ff0b278addd743e0e966cb3d460278840d", size = 274877, upload-time = "2024-10-23T09:46:48.989Z" }, { url = "https://files.pythonhosted.org/packages/fa/79/38c505601ae29d4348f21706c5d89755ceded02a745016ba2f58bd5f1ea6/frozenlist-1.5.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cee6798eaf8b1416ef6909b06f7dc04b60755206bddc599f52232606e18179d3", size = 269592, upload-time = "2024-10-23T09:46:50.235Z" }, { url = "https://files.pythonhosted.org/packages/19/e2/39f3a53191b8204ba9f0bb574b926b73dd2efba2a2b9d2d730517e8f7622/frozenlist-1.5.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f5f9da7f5dbc00a604fe74aa02ae7c98bcede8a3b8b9666f9f86fc13993bc71a", size = 265934, upload-time = "2024-10-23T09:46:51.829Z" }, { url = "https://files.pythonhosted.org/packages/d5/c9/3075eb7f7f3a91f1a6b00284af4de0a65a9ae47084930916f5528144c9dd/frozenlist-1.5.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:90646abbc7a5d5c7c19461d2e3eeb76eb0b204919e6ece342feb6032c9325ae9", size = 283859, upload-time = "2024-10-23T09:46:52.947Z" }, { url = "https://files.pythonhosted.org/packages/05/f5/549f44d314c29408b962fa2b0e69a1a67c59379fb143b92a0a065ffd1f0f/frozenlist-1.5.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:bdac3c7d9b705d253b2ce370fde941836a5f8b3c5c2b8fd70940a3ea3af7f4f2", size = 287560, upload-time = "2024-10-23T09:46:54.162Z" }, { url = "https://files.pythonhosted.org/packages/9d/f8/cb09b3c24a3eac02c4c07a9558e11e9e244fb02bf62c85ac2106d1eb0c0b/frozenlist-1.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:03d33c2ddbc1816237a67f66336616416e2bbb6beb306e5f890f2eb22b959cdf", size = 277150, upload-time = "2024-10-23T09:46:55.361Z" }, { url = "https://files.pythonhosted.org/packages/37/48/38c2db3f54d1501e692d6fe058f45b6ad1b358d82cd19436efab80cfc965/frozenlist-1.5.0-cp311-cp311-win32.whl", hash = "sha256:237f6b23ee0f44066219dae14c70ae38a63f0440ce6750f868ee08775073f942", size = 45244, upload-time = "2024-10-23T09:46:56.578Z" }, { url = "https://files.pythonhosted.org/packages/ca/8c/2ddffeb8b60a4bce3b196c32fcc30d8830d4615e7b492ec2071da801b8ad/frozenlist-1.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:0cc974cc93d32c42e7b0f6cf242a6bd941c57c61b618e78b6c0a96cb72788c1d", size = 51634, upload-time = "2024-10-23T09:46:57.6Z" }, { url = "https://files.pythonhosted.org/packages/79/73/fa6d1a96ab7fd6e6d1c3500700963eab46813847f01ef0ccbaa726181dd5/frozenlist-1.5.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:31115ba75889723431aa9a4e77d5f398f5cf976eea3bdf61749731f62d4a4a21", size = 94026, upload-time = "2024-10-23T09:46:58.601Z" }, { url = "https://files.pythonhosted.org/packages/ab/04/ea8bf62c8868b8eada363f20ff1b647cf2e93377a7b284d36062d21d81d1/frozenlist-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7437601c4d89d070eac8323f121fcf25f88674627505334654fd027b091db09d", size = 54150, upload-time = "2024-10-23T09:46:59.608Z" }, { url = "https://files.pythonhosted.org/packages/d0/9a/8e479b482a6f2070b26bda572c5e6889bb3ba48977e81beea35b5ae13ece/frozenlist-1.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7948140d9f8ece1745be806f2bfdf390127cf1a763b925c4a805c603df5e697e", size = 51927, upload-time = "2024-10-23T09:47:00.625Z" }, { url = "https://files.pythonhosted.org/packages/e3/12/2aad87deb08a4e7ccfb33600871bbe8f0e08cb6d8224371387f3303654d7/frozenlist-1.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:feeb64bc9bcc6b45c6311c9e9b99406660a9c05ca8a5b30d14a78555088b0b3a", size = 282647, upload-time = "2024-10-23T09:47:01.992Z" }, { url = "https://files.pythonhosted.org/packages/77/f2/07f06b05d8a427ea0060a9cef6e63405ea9e0d761846b95ef3fb3be57111/frozenlist-1.5.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:683173d371daad49cffb8309779e886e59c2f369430ad28fe715f66d08d4ab1a", size = 289052, upload-time = "2024-10-23T09:47:04.039Z" }, { url = "https://files.pythonhosted.org/packages/bd/9f/8bf45a2f1cd4aa401acd271b077989c9267ae8463e7c8b1eb0d3f561b65e/frozenlist-1.5.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7d57d8f702221405a9d9b40f9da8ac2e4a1a8b5285aac6100f3393675f0a85ee", size = 291719, upload-time = "2024-10-23T09:47:05.58Z" }, { url = "https://files.pythonhosted.org/packages/41/d1/1f20fd05a6c42d3868709b7604c9f15538a29e4f734c694c6bcfc3d3b935/frozenlist-1.5.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30c72000fbcc35b129cb09956836c7d7abf78ab5416595e4857d1cae8d6251a6", size = 267433, upload-time = "2024-10-23T09:47:07.807Z" }, { url = "https://files.pythonhosted.org/packages/af/f2/64b73a9bb86f5a89fb55450e97cd5c1f84a862d4ff90d9fd1a73ab0f64a5/frozenlist-1.5.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:000a77d6034fbad9b6bb880f7ec073027908f1b40254b5d6f26210d2dab1240e", size = 283591, upload-time = "2024-10-23T09:47:09.645Z" }, { url = "https://files.pythonhosted.org/packages/29/e2/ffbb1fae55a791fd6c2938dd9ea779509c977435ba3940b9f2e8dc9d5316/frozenlist-1.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5d7f5a50342475962eb18b740f3beecc685a15b52c91f7d975257e13e029eca9", size = 273249, upload-time = "2024-10-23T09:47:10.808Z" }, { url = "https://files.pythonhosted.org/packages/2e/6e/008136a30798bb63618a114b9321b5971172a5abddff44a100c7edc5ad4f/frozenlist-1.5.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:87f724d055eb4785d9be84e9ebf0f24e392ddfad00b3fe036e43f489fafc9039", size = 271075, upload-time = "2024-10-23T09:47:11.938Z" }, { url = "https://files.pythonhosted.org/packages/ae/f0/4e71e54a026b06724cec9b6c54f0b13a4e9e298cc8db0f82ec70e151f5ce/frozenlist-1.5.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:6e9080bb2fb195a046e5177f10d9d82b8a204c0736a97a153c2466127de87784", size = 285398, upload-time = "2024-10-23T09:47:14.071Z" }, { url = "https://files.pythonhosted.org/packages/4d/36/70ec246851478b1c0b59f11ef8ade9c482ff447c1363c2bd5fad45098b12/frozenlist-1.5.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9b93d7aaa36c966fa42efcaf716e6b3900438632a626fb09c049f6a2f09fc631", size = 294445, upload-time = "2024-10-23T09:47:15.318Z" }, { url = "https://files.pythonhosted.org/packages/37/e0/47f87544055b3349b633a03c4d94b405956cf2437f4ab46d0928b74b7526/frozenlist-1.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:52ef692a4bc60a6dd57f507429636c2af8b6046db8b31b18dac02cbc8f507f7f", size = 280569, upload-time = "2024-10-23T09:47:17.149Z" }, { url = "https://files.pythonhosted.org/packages/f9/7c/490133c160fb6b84ed374c266f42800e33b50c3bbab1652764e6e1fc498a/frozenlist-1.5.0-cp312-cp312-win32.whl", hash = "sha256:29d94c256679247b33a3dc96cce0f93cbc69c23bf75ff715919332fdbb6a32b8", size = 44721, upload-time = "2024-10-23T09:47:19.012Z" }, { url = "https://files.pythonhosted.org/packages/b1/56/4e45136ffc6bdbfa68c29ca56ef53783ef4c2fd395f7cbf99a2624aa9aaa/frozenlist-1.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:8969190d709e7c48ea386db202d708eb94bdb29207a1f269bab1196ce0dcca1f", size = 51329, upload-time = "2024-10-23T09:47:20.177Z" }, { url = "https://files.pythonhosted.org/packages/da/3b/915f0bca8a7ea04483622e84a9bd90033bab54bdf485479556c74fd5eaf5/frozenlist-1.5.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7a1a048f9215c90973402e26c01d1cff8a209e1f1b53f72b95c13db61b00f953", size = 91538, upload-time = "2024-10-23T09:47:21.176Z" }, { url = "https://files.pythonhosted.org/packages/c7/d1/a7c98aad7e44afe5306a2b068434a5830f1470675f0e715abb86eb15f15b/frozenlist-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dd47a5181ce5fcb463b5d9e17ecfdb02b678cca31280639255ce9d0e5aa67af0", size = 52849, upload-time = "2024-10-23T09:47:22.439Z" }, { url = "https://files.pythonhosted.org/packages/3a/c8/76f23bf9ab15d5f760eb48701909645f686f9c64fbb8982674c241fbef14/frozenlist-1.5.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1431d60b36d15cda188ea222033eec8e0eab488f39a272461f2e6d9e1a8e63c2", size = 50583, upload-time = "2024-10-23T09:47:23.44Z" }, { url = "https://files.pythonhosted.org/packages/1f/22/462a3dd093d11df623179d7754a3b3269de3b42de2808cddef50ee0f4f48/frozenlist-1.5.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6482a5851f5d72767fbd0e507e80737f9c8646ae7fd303def99bfe813f76cf7f", size = 265636, upload-time = "2024-10-23T09:47:24.82Z" }, { url = "https://files.pythonhosted.org/packages/80/cf/e075e407fc2ae7328155a1cd7e22f932773c8073c1fc78016607d19cc3e5/frozenlist-1.5.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:44c49271a937625619e862baacbd037a7ef86dd1ee215afc298a417ff3270608", size = 270214, upload-time = "2024-10-23T09:47:26.156Z" }, { url = "https://files.pythonhosted.org/packages/a1/58/0642d061d5de779f39c50cbb00df49682832923f3d2ebfb0fedf02d05f7f/frozenlist-1.5.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:12f78f98c2f1c2429d42e6a485f433722b0061d5c0b0139efa64f396efb5886b", size = 273905, upload-time = "2024-10-23T09:47:27.741Z" }, { url = "https://files.pythonhosted.org/packages/ab/66/3fe0f5f8f2add5b4ab7aa4e199f767fd3b55da26e3ca4ce2cc36698e50c4/frozenlist-1.5.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce3aa154c452d2467487765e3adc730a8c153af77ad84096bc19ce19a2400840", size = 250542, upload-time = "2024-10-23T09:47:28.938Z" }, { url = "https://files.pythonhosted.org/packages/f6/b8/260791bde9198c87a465224e0e2bb62c4e716f5d198fc3a1dacc4895dbd1/frozenlist-1.5.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b7dc0c4338e6b8b091e8faf0db3168a37101943e687f373dce00959583f7439", size = 267026, upload-time = "2024-10-23T09:47:30.283Z" }, { url = "https://files.pythonhosted.org/packages/2e/a4/3d24f88c527f08f8d44ade24eaee83b2627793fa62fa07cbb7ff7a2f7d42/frozenlist-1.5.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:45e0896250900b5aa25180f9aec243e84e92ac84bd4a74d9ad4138ef3f5c97de", size = 257690, upload-time = "2024-10-23T09:47:32.388Z" }, { url = "https://files.pythonhosted.org/packages/de/9a/d311d660420b2beeff3459b6626f2ab4fb236d07afbdac034a4371fe696e/frozenlist-1.5.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:561eb1c9579d495fddb6da8959fd2a1fca2c6d060d4113f5844b433fc02f2641", size = 253893, upload-time = "2024-10-23T09:47:34.274Z" }, { url = "https://files.pythonhosted.org/packages/c6/23/e491aadc25b56eabd0f18c53bb19f3cdc6de30b2129ee0bc39cd387cd560/frozenlist-1.5.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:df6e2f325bfee1f49f81aaac97d2aa757c7646534a06f8f577ce184afe2f0a9e", size = 267006, upload-time = "2024-10-23T09:47:35.499Z" }, { url = "https://files.pythonhosted.org/packages/08/c4/ab918ce636a35fb974d13d666dcbe03969592aeca6c3ab3835acff01f79c/frozenlist-1.5.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:140228863501b44b809fb39ec56b5d4071f4d0aa6d216c19cbb08b8c5a7eadb9", size = 276157, upload-time = "2024-10-23T09:47:37.522Z" }, { url = "https://files.pythonhosted.org/packages/c0/29/3b7a0bbbbe5a34833ba26f686aabfe982924adbdcafdc294a7a129c31688/frozenlist-1.5.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7707a25d6a77f5d27ea7dc7d1fc608aa0a478193823f88511ef5e6b8a48f9d03", size = 264642, upload-time = "2024-10-23T09:47:38.75Z" }, { url = "https://files.pythonhosted.org/packages/ab/42/0595b3dbffc2e82d7fe658c12d5a5bafcd7516c6bf2d1d1feb5387caa9c1/frozenlist-1.5.0-cp313-cp313-win32.whl", hash = "sha256:31a9ac2b38ab9b5a8933b693db4939764ad3f299fcaa931a3e605bc3460e693c", size = 44914, upload-time = "2024-10-23T09:47:40.145Z" }, { url = "https://files.pythonhosted.org/packages/17/c4/b7db1206a3fea44bf3b838ca61deb6f74424a8a5db1dd53ecb21da669be6/frozenlist-1.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:11aabdd62b8b9c4b84081a3c246506d1cddd2dd93ff0ad53ede5defec7886b28", size = 51167, upload-time = "2024-10-23T09:47:41.812Z" }, { url = "https://files.pythonhosted.org/packages/33/b5/00fcbe8e7e7e172829bf4addc8227d8f599a3d5def3a4e9aa2b54b3145aa/frozenlist-1.5.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:dd94994fc91a6177bfaafd7d9fd951bc8689b0a98168aa26b5f543868548d3ca", size = 95648, upload-time = "2024-10-23T09:47:43.118Z" }, { url = "https://files.pythonhosted.org/packages/1e/69/e4a32fc4b2fa8e9cb6bcb1bad9c7eeb4b254bc34da475b23f93264fdc306/frozenlist-1.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d0da8bbec082bf6bf18345b180958775363588678f64998c2b7609e34719b10", size = 54888, upload-time = "2024-10-23T09:47:44.832Z" }, { url = "https://files.pythonhosted.org/packages/76/a3/c08322a91e73d1199901a77ce73971cffa06d3c74974270ff97aed6e152a/frozenlist-1.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:73f2e31ea8dd7df61a359b731716018c2be196e5bb3b74ddba107f694fbd7604", size = 52975, upload-time = "2024-10-23T09:47:46.579Z" }, { url = "https://files.pythonhosted.org/packages/fc/60/a315321d8ada167b578ff9d2edc147274ead6129523b3a308501b6621b4f/frozenlist-1.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:828afae9f17e6de596825cf4228ff28fbdf6065974e5ac1410cecc22f699d2b3", size = 241912, upload-time = "2024-10-23T09:47:47.687Z" }, { url = "https://files.pythonhosted.org/packages/bd/d0/1f0980987bca4f94f9e8bae01980b23495ffc2e5049a3da4d9b7d2762bee/frozenlist-1.5.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1577515d35ed5649d52ab4319db757bb881ce3b2b796d7283e6634d99ace307", size = 259433, upload-time = "2024-10-23T09:47:49.339Z" }, { url = "https://files.pythonhosted.org/packages/28/e7/d00600c072eec8f18a606e281afdf0e8606e71a4882104d0438429b02468/frozenlist-1.5.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2150cc6305a2c2ab33299453e2968611dacb970d2283a14955923062c8d00b10", size = 255576, upload-time = "2024-10-23T09:47:50.519Z" }, { url = "https://files.pythonhosted.org/packages/82/71/993c5f45dba7be347384ddec1ebc1b4d998291884e7690c06aa6ba755211/frozenlist-1.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a72b7a6e3cd2725eff67cd64c8f13335ee18fc3c7befc05aed043d24c7b9ccb9", size = 233349, upload-time = "2024-10-23T09:47:53.197Z" }, { url = "https://files.pythonhosted.org/packages/66/30/f9c006223feb2ac87f1826b57f2367b60aacc43092f562dab60d2312562e/frozenlist-1.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c16d2fa63e0800723139137d667e1056bee1a1cf7965153d2d104b62855e9b99", size = 243126, upload-time = "2024-10-23T09:47:54.432Z" }, { url = "https://files.pythonhosted.org/packages/b5/34/e4219c9343f94b81068d0018cbe37948e66c68003b52bf8a05e9509d09ec/frozenlist-1.5.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:17dcc32fc7bda7ce5875435003220a457bcfa34ab7924a49a1c19f55b6ee185c", size = 241261, upload-time = "2024-10-23T09:47:56.01Z" }, { url = "https://files.pythonhosted.org/packages/48/96/9141758f6a19f2061a51bb59b9907c92f9bda1ac7b2baaf67a6e352b280f/frozenlist-1.5.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:97160e245ea33d8609cd2b8fd997c850b56db147a304a262abc2b3be021a9171", size = 240203, upload-time = "2024-10-23T09:47:57.337Z" }, { url = "https://files.pythonhosted.org/packages/f9/71/0ef5970e68d181571a050958e84c76a061ca52f9c6f50257d9bfdd84c7f7/frozenlist-1.5.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f1e6540b7fa044eee0bb5111ada694cf3dc15f2b0347ca125ee9ca984d5e9e6e", size = 267539, upload-time = "2024-10-23T09:47:58.874Z" }, { url = "https://files.pythonhosted.org/packages/ab/bd/6e7d450c5d993b413591ad9cdab6dcdfa2c6ab2cd835b2b5c1cfeb0323bf/frozenlist-1.5.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:91d6c171862df0a6c61479d9724f22efb6109111017c87567cfeb7b5d1449fdf", size = 268518, upload-time = "2024-10-23T09:48:00.771Z" }, { url = "https://files.pythonhosted.org/packages/cc/3d/5a7c4dfff1ae57ca2cbbe9041521472ecd9446d49e7044a0e9bfd0200fd0/frozenlist-1.5.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c1fac3e2ace2eb1052e9f7c7db480818371134410e1f5c55d65e8f3ac6d1407e", size = 248114, upload-time = "2024-10-23T09:48:02.625Z" }, { url = "https://files.pythonhosted.org/packages/f7/41/2342ec4c714349793f1a1e7bd5c4aeec261e24e697fa9a5499350c3a2415/frozenlist-1.5.0-cp38-cp38-win32.whl", hash = "sha256:b97f7b575ab4a8af9b7bc1d2ef7f29d3afee2226bd03ca3875c16451ad5a7723", size = 45648, upload-time = "2024-10-23T09:48:03.895Z" }, { url = "https://files.pythonhosted.org/packages/0c/90/85bb3547c327f5975078c1be018478d5e8d250a540c828f8f31a35d2a1bd/frozenlist-1.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:374ca2dabdccad8e2a76d40b1d037f5bd16824933bf7bcea3e59c891fd4a0923", size = 51930, upload-time = "2024-10-23T09:48:05.293Z" }, { url = "https://files.pythonhosted.org/packages/da/4d/d94ff0fb0f5313902c132817c62d19cdc5bdcd0c195d392006ef4b779fc6/frozenlist-1.5.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9bbcdfaf4af7ce002694a4e10a0159d5a8d20056a12b05b45cea944a4953f972", size = 95319, upload-time = "2024-10-23T09:48:06.405Z" }, { url = "https://files.pythonhosted.org/packages/8c/1b/d90e554ca2b483d31cb2296e393f72c25bdc38d64526579e95576bfda587/frozenlist-1.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1893f948bf6681733aaccf36c5232c231e3b5166d607c5fa77773611df6dc336", size = 54749, upload-time = "2024-10-23T09:48:07.48Z" }, { url = "https://files.pythonhosted.org/packages/f8/66/7fdecc9ef49f8db2aa4d9da916e4ecf357d867d87aea292efc11e1b2e932/frozenlist-1.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2b5e23253bb709ef57a8e95e6ae48daa9ac5f265637529e4ce6b003a37b2621f", size = 52718, upload-time = "2024-10-23T09:48:08.725Z" }, { url = "https://files.pythonhosted.org/packages/08/04/e2fddc92135276e07addbc1cf413acffa0c2d848b3e54cacf684e146df49/frozenlist-1.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f253985bb515ecd89629db13cb58d702035ecd8cfbca7d7a7e29a0e6d39af5f", size = 241756, upload-time = "2024-10-23T09:48:09.843Z" }, { url = "https://files.pythonhosted.org/packages/c6/52/be5ff200815d8a341aee5b16b6b707355e0ca3652953852238eb92b120c2/frozenlist-1.5.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:04a5c6babd5e8fb7d3c871dc8b321166b80e41b637c31a995ed844a6139942b6", size = 267718, upload-time = "2024-10-23T09:48:11.828Z" }, { url = "https://files.pythonhosted.org/packages/88/be/4bd93a58be57a3722fc544c36debdf9dcc6758f761092e894d78f18b8f20/frozenlist-1.5.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9fe0f1c29ba24ba6ff6abf688cb0b7cf1efab6b6aa6adc55441773c252f7411", size = 263494, upload-time = "2024-10-23T09:48:13.424Z" }, { url = "https://files.pythonhosted.org/packages/32/ba/58348b90193caa096ce9e9befea6ae67f38dabfd3aacb47e46137a6250a8/frozenlist-1.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:226d72559fa19babe2ccd920273e767c96a49b9d3d38badd7c91a0fdeda8ea08", size = 232838, upload-time = "2024-10-23T09:48:14.792Z" }, { url = "https://files.pythonhosted.org/packages/f6/33/9f152105227630246135188901373c4f322cc026565ca6215b063f4c82f4/frozenlist-1.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15b731db116ab3aedec558573c1a5eec78822b32292fe4f2f0345b7f697745c2", size = 242912, upload-time = "2024-10-23T09:48:16.249Z" }, { url = "https://files.pythonhosted.org/packages/a0/10/3db38fb3ccbafadd80a1b0d6800c987b0e3fe3ef2d117c6ced0246eea17a/frozenlist-1.5.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:366d8f93e3edfe5a918c874702f78faac300209a4d5bf38352b2c1bdc07a766d", size = 244763, upload-time = "2024-10-23T09:48:17.781Z" }, { url = "https://files.pythonhosted.org/packages/e2/cd/1df468fdce2f66a4608dffe44c40cdc35eeaa67ef7fd1d813f99a9a37842/frozenlist-1.5.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1b96af8c582b94d381a1c1f51ffaedeb77c821c690ea5f01da3d70a487dd0a9b", size = 242841, upload-time = "2024-10-23T09:48:19.507Z" }, { url = "https://files.pythonhosted.org/packages/ee/5f/16097a5ca0bb6b6779c02cc9379c72fe98d56115d4c54d059fb233168fb6/frozenlist-1.5.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:c03eff4a41bd4e38415cbed054bbaff4a075b093e2394b6915dca34a40d1e38b", size = 263407, upload-time = "2024-10-23T09:48:21.467Z" }, { url = "https://files.pythonhosted.org/packages/0f/f7/58cd220ee1c2248ee65a32f5b4b93689e3fe1764d85537eee9fc392543bc/frozenlist-1.5.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:50cf5e7ee9b98f22bdecbabf3800ae78ddcc26e4a435515fc72d97903e8488e0", size = 265083, upload-time = "2024-10-23T09:48:22.725Z" }, { url = "https://files.pythonhosted.org/packages/62/b8/49768980caabf81ac4a2d156008f7cbd0107e6b36d08a313bb31035d9201/frozenlist-1.5.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1e76bfbc72353269c44e0bc2cfe171900fbf7f722ad74c9a7b638052afe6a00c", size = 251564, upload-time = "2024-10-23T09:48:24.272Z" }, { url = "https://files.pythonhosted.org/packages/cb/83/619327da3b86ef957ee7a0cbf3c166a09ed1e87a3f7f1ff487d7d0284683/frozenlist-1.5.0-cp39-cp39-win32.whl", hash = "sha256:666534d15ba8f0fda3f53969117383d5dc021266b3c1a42c9ec4855e4b58b9d3", size = 45691, upload-time = "2024-10-23T09:48:26.317Z" }, { url = "https://files.pythonhosted.org/packages/8b/28/407bc34a745151ed2322c690b6e7d83d7101472e81ed76e1ebdac0b70a78/frozenlist-1.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:5c28f4b5dbef8a0d8aad0d4de24d1e9e981728628afaf4ea0792f5d0939372f0", size = 51767, upload-time = "2024-10-23T09:48:27.427Z" }, { url = "https://files.pythonhosted.org/packages/c6/c8/a5be5b7550c10858fcf9b0ea054baccab474da77d37f1e828ce043a3a5d4/frozenlist-1.5.0-py3-none-any.whl", hash = "sha256:d994863bba198a4a518b467bb971c56e1db3f180a25c6cf7bb1949c267f748c3", size = 11901, upload-time = "2024-10-23T09:48:28.851Z" }, ] [[package]] name = "frozenlist" version = "1.7.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.10'", "python_full_version == '3.9.*'", ] sdist = { url = "https://files.pythonhosted.org/packages/79/b1/b64018016eeb087db503b038296fd782586432b9c077fc5c7839e9cb6ef6/frozenlist-1.7.0.tar.gz", hash = "sha256:2e310d81923c2437ea8670467121cc3e9b0f76d3043cc1d2331d56c7fb7a3a8f", size = 45078, upload-time = "2025-06-09T23:02:35.538Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/af/36/0da0a49409f6b47cc2d060dc8c9040b897b5902a8a4e37d9bc1deb11f680/frozenlist-1.7.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cc4df77d638aa2ed703b878dd093725b72a824c3c546c076e8fdf276f78ee84a", size = 81304, upload-time = "2025-06-09T22:59:46.226Z" }, { url = "https://files.pythonhosted.org/packages/77/f0/77c11d13d39513b298e267b22eb6cb559c103d56f155aa9a49097221f0b6/frozenlist-1.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:716a9973a2cc963160394f701964fe25012600f3d311f60c790400b00e568b61", size = 47735, upload-time = "2025-06-09T22:59:48.133Z" }, { url = "https://files.pythonhosted.org/packages/37/12/9d07fa18971a44150593de56b2f2947c46604819976784bcf6ea0d5db43b/frozenlist-1.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0fd1bad056a3600047fb9462cff4c5322cebc59ebf5d0a3725e0ee78955001d", size = 46775, upload-time = "2025-06-09T22:59:49.564Z" }, { url = "https://files.pythonhosted.org/packages/70/34/f73539227e06288fcd1f8a76853e755b2b48bca6747e99e283111c18bcd4/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3789ebc19cb811163e70fe2bd354cea097254ce6e707ae42e56f45e31e96cb8e", size = 224644, upload-time = "2025-06-09T22:59:51.35Z" }, { url = "https://files.pythonhosted.org/packages/fb/68/c1d9c2f4a6e438e14613bad0f2973567586610cc22dcb1e1241da71de9d3/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:af369aa35ee34f132fcfad5be45fbfcde0e3a5f6a1ec0712857f286b7d20cca9", size = 222125, upload-time = "2025-06-09T22:59:52.884Z" }, { url = "https://files.pythonhosted.org/packages/b9/d0/98e8f9a515228d708344d7c6986752be3e3192d1795f748c24bcf154ad99/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac64b6478722eeb7a3313d494f8342ef3478dff539d17002f849101b212ef97c", size = 233455, upload-time = "2025-06-09T22:59:54.74Z" }, { url = "https://files.pythonhosted.org/packages/79/df/8a11bcec5600557f40338407d3e5bea80376ed1c01a6c0910fcfdc4b8993/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f89f65d85774f1797239693cef07ad4c97fdd0639544bad9ac4b869782eb1981", size = 227339, upload-time = "2025-06-09T22:59:56.187Z" }, { url = "https://files.pythonhosted.org/packages/50/82/41cb97d9c9a5ff94438c63cc343eb7980dac4187eb625a51bdfdb7707314/frozenlist-1.7.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1073557c941395fdfcfac13eb2456cb8aad89f9de27bae29fabca8e563b12615", size = 212969, upload-time = "2025-06-09T22:59:57.604Z" }, { url = "https://files.pythonhosted.org/packages/13/47/f9179ee5ee4f55629e4f28c660b3fdf2775c8bfde8f9c53f2de2d93f52a9/frozenlist-1.7.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ed8d2fa095aae4bdc7fdd80351009a48d286635edffee66bf865e37a9125c50", size = 222862, upload-time = "2025-06-09T22:59:59.498Z" }, { url = "https://files.pythonhosted.org/packages/1a/52/df81e41ec6b953902c8b7e3a83bee48b195cb0e5ec2eabae5d8330c78038/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:24c34bea555fe42d9f928ba0a740c553088500377448febecaa82cc3e88aa1fa", size = 222492, upload-time = "2025-06-09T23:00:01.026Z" }, { url = "https://files.pythonhosted.org/packages/84/17/30d6ea87fa95a9408245a948604b82c1a4b8b3e153cea596421a2aef2754/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:69cac419ac6a6baad202c85aaf467b65ac860ac2e7f2ac1686dc40dbb52f6577", size = 238250, upload-time = "2025-06-09T23:00:03.401Z" }, { url = "https://files.pythonhosted.org/packages/8f/00/ecbeb51669e3c3df76cf2ddd66ae3e48345ec213a55e3887d216eb4fbab3/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:960d67d0611f4c87da7e2ae2eacf7ea81a5be967861e0c63cf205215afbfac59", size = 218720, upload-time = "2025-06-09T23:00:05.282Z" }, { url = "https://files.pythonhosted.org/packages/1a/c0/c224ce0e0eb31cc57f67742071bb470ba8246623c1823a7530be0e76164c/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:41be2964bd4b15bf575e5daee5a5ce7ed3115320fb3c2b71fca05582ffa4dc9e", size = 232585, upload-time = "2025-06-09T23:00:07.962Z" }, { url = "https://files.pythonhosted.org/packages/55/3c/34cb694abf532f31f365106deebdeac9e45c19304d83cf7d51ebbb4ca4d1/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:46d84d49e00c9429238a7ce02dc0be8f6d7cd0cd405abd1bebdc991bf27c15bd", size = 234248, upload-time = "2025-06-09T23:00:09.428Z" }, { url = "https://files.pythonhosted.org/packages/98/c0/2052d8b6cecda2e70bd81299e3512fa332abb6dcd2969b9c80dfcdddbf75/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:15900082e886edb37480335d9d518cec978afc69ccbc30bd18610b7c1b22a718", size = 221621, upload-time = "2025-06-09T23:00:11.32Z" }, { url = "https://files.pythonhosted.org/packages/c5/bf/7dcebae315436903b1d98ffb791a09d674c88480c158aa171958a3ac07f0/frozenlist-1.7.0-cp310-cp310-win32.whl", hash = "sha256:400ddd24ab4e55014bba442d917203c73b2846391dd42ca5e38ff52bb18c3c5e", size = 39578, upload-time = "2025-06-09T23:00:13.526Z" }, { url = "https://files.pythonhosted.org/packages/8f/5f/f69818f017fa9a3d24d1ae39763e29b7f60a59e46d5f91b9c6b21622f4cd/frozenlist-1.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:6eb93efb8101ef39d32d50bce242c84bcbddb4f7e9febfa7b524532a239b4464", size = 43830, upload-time = "2025-06-09T23:00:14.98Z" }, { url = "https://files.pythonhosted.org/packages/34/7e/803dde33760128acd393a27eb002f2020ddb8d99d30a44bfbaab31c5f08a/frozenlist-1.7.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:aa51e147a66b2d74de1e6e2cf5921890de6b0f4820b257465101d7f37b49fb5a", size = 82251, upload-time = "2025-06-09T23:00:16.279Z" }, { url = "https://files.pythonhosted.org/packages/75/a9/9c2c5760b6ba45eae11334db454c189d43d34a4c0b489feb2175e5e64277/frozenlist-1.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9b35db7ce1cd71d36ba24f80f0c9e7cff73a28d7a74e91fe83e23d27c7828750", size = 48183, upload-time = "2025-06-09T23:00:17.698Z" }, { url = "https://files.pythonhosted.org/packages/47/be/4038e2d869f8a2da165f35a6befb9158c259819be22eeaf9c9a8f6a87771/frozenlist-1.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:34a69a85e34ff37791e94542065c8416c1afbf820b68f720452f636d5fb990cd", size = 47107, upload-time = "2025-06-09T23:00:18.952Z" }, { url = "https://files.pythonhosted.org/packages/79/26/85314b8a83187c76a37183ceed886381a5f992975786f883472fcb6dc5f2/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a646531fa8d82c87fe4bb2e596f23173caec9185bfbca5d583b4ccfb95183e2", size = 237333, upload-time = "2025-06-09T23:00:20.275Z" }, { url = "https://files.pythonhosted.org/packages/1f/fd/e5b64f7d2c92a41639ffb2ad44a6a82f347787abc0c7df5f49057cf11770/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:79b2ffbba483f4ed36a0f236ccb85fbb16e670c9238313709638167670ba235f", size = 231724, upload-time = "2025-06-09T23:00:21.705Z" }, { url = "https://files.pythonhosted.org/packages/20/fb/03395c0a43a5976af4bf7534759d214405fbbb4c114683f434dfdd3128ef/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a26f205c9ca5829cbf82bb2a84b5c36f7184c4316617d7ef1b271a56720d6b30", size = 245842, upload-time = "2025-06-09T23:00:23.148Z" }, { url = "https://files.pythonhosted.org/packages/d0/15/c01c8e1dffdac5d9803507d824f27aed2ba76b6ed0026fab4d9866e82f1f/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bcacfad3185a623fa11ea0e0634aac7b691aa925d50a440f39b458e41c561d98", size = 239767, upload-time = "2025-06-09T23:00:25.103Z" }, { url = "https://files.pythonhosted.org/packages/14/99/3f4c6fe882c1f5514b6848aa0a69b20cb5e5d8e8f51a339d48c0e9305ed0/frozenlist-1.7.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:72c1b0fe8fe451b34f12dce46445ddf14bd2a5bcad7e324987194dc8e3a74c86", size = 224130, upload-time = "2025-06-09T23:00:27.061Z" }, { url = "https://files.pythonhosted.org/packages/4d/83/220a374bd7b2aeba9d0725130665afe11de347d95c3620b9b82cc2fcab97/frozenlist-1.7.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61d1a5baeaac6c0798ff6edfaeaa00e0e412d49946c53fae8d4b8e8b3566c4ae", size = 235301, upload-time = "2025-06-09T23:00:29.02Z" }, { url = "https://files.pythonhosted.org/packages/03/3c/3e3390d75334a063181625343e8daab61b77e1b8214802cc4e8a1bb678fc/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7edf5c043c062462f09b6820de9854bf28cc6cc5b6714b383149745e287181a8", size = 234606, upload-time = "2025-06-09T23:00:30.514Z" }, { url = "https://files.pythonhosted.org/packages/23/1e/58232c19608b7a549d72d9903005e2d82488f12554a32de2d5fb59b9b1ba/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:d50ac7627b3a1bd2dcef6f9da89a772694ec04d9a61b66cf87f7d9446b4a0c31", size = 248372, upload-time = "2025-06-09T23:00:31.966Z" }, { url = "https://files.pythonhosted.org/packages/c0/a4/e4a567e01702a88a74ce8a324691e62a629bf47d4f8607f24bf1c7216e7f/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ce48b2fece5aeb45265bb7a58259f45027db0abff478e3077e12b05b17fb9da7", size = 229860, upload-time = "2025-06-09T23:00:33.375Z" }, { url = "https://files.pythonhosted.org/packages/73/a6/63b3374f7d22268b41a9db73d68a8233afa30ed164c46107b33c4d18ecdd/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:fe2365ae915a1fafd982c146754e1de6ab3478def8a59c86e1f7242d794f97d5", size = 245893, upload-time = "2025-06-09T23:00:35.002Z" }, { url = "https://files.pythonhosted.org/packages/6d/eb/d18b3f6e64799a79673c4ba0b45e4cfbe49c240edfd03a68be20002eaeaa/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:45a6f2fdbd10e074e8814eb98b05292f27bad7d1883afbe009d96abdcf3bc898", size = 246323, upload-time = "2025-06-09T23:00:36.468Z" }, { url = "https://files.pythonhosted.org/packages/5a/f5/720f3812e3d06cd89a1d5db9ff6450088b8f5c449dae8ffb2971a44da506/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:21884e23cffabb157a9dd7e353779077bf5b8f9a58e9b262c6caad2ef5f80a56", size = 233149, upload-time = "2025-06-09T23:00:37.963Z" }, { url = "https://files.pythonhosted.org/packages/69/68/03efbf545e217d5db8446acfd4c447c15b7c8cf4dbd4a58403111df9322d/frozenlist-1.7.0-cp311-cp311-win32.whl", hash = "sha256:284d233a8953d7b24f9159b8a3496fc1ddc00f4db99c324bd5fb5f22d8698ea7", size = 39565, upload-time = "2025-06-09T23:00:39.753Z" }, { url = "https://files.pythonhosted.org/packages/58/17/fe61124c5c333ae87f09bb67186d65038834a47d974fc10a5fadb4cc5ae1/frozenlist-1.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:387cbfdcde2f2353f19c2f66bbb52406d06ed77519ac7ee21be0232147c2592d", size = 44019, upload-time = "2025-06-09T23:00:40.988Z" }, { url = "https://files.pythonhosted.org/packages/ef/a2/c8131383f1e66adad5f6ecfcce383d584ca94055a34d683bbb24ac5f2f1c/frozenlist-1.7.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3dbf9952c4bb0e90e98aec1bd992b3318685005702656bc6f67c1a32b76787f2", size = 81424, upload-time = "2025-06-09T23:00:42.24Z" }, { url = "https://files.pythonhosted.org/packages/4c/9d/02754159955088cb52567337d1113f945b9e444c4960771ea90eb73de8db/frozenlist-1.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1f5906d3359300b8a9bb194239491122e6cf1444c2efb88865426f170c262cdb", size = 47952, upload-time = "2025-06-09T23:00:43.481Z" }, { url = "https://files.pythonhosted.org/packages/01/7a/0046ef1bd6699b40acd2067ed6d6670b4db2f425c56980fa21c982c2a9db/frozenlist-1.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3dabd5a8f84573c8d10d8859a50ea2dec01eea372031929871368c09fa103478", size = 46688, upload-time = "2025-06-09T23:00:44.793Z" }, { url = "https://files.pythonhosted.org/packages/d6/a2/a910bafe29c86997363fb4c02069df4ff0b5bc39d33c5198b4e9dd42d8f8/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa57daa5917f1738064f302bf2626281a1cb01920c32f711fbc7bc36111058a8", size = 243084, upload-time = "2025-06-09T23:00:46.125Z" }, { url = "https://files.pythonhosted.org/packages/64/3e/5036af9d5031374c64c387469bfcc3af537fc0f5b1187d83a1cf6fab1639/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c193dda2b6d49f4c4398962810fa7d7c78f032bf45572b3e04dd5249dff27e08", size = 233524, upload-time = "2025-06-09T23:00:47.73Z" }, { url = "https://files.pythonhosted.org/packages/06/39/6a17b7c107a2887e781a48ecf20ad20f1c39d94b2a548c83615b5b879f28/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfe2b675cf0aaa6d61bf8fbffd3c274b3c9b7b1623beb3809df8a81399a4a9c4", size = 248493, upload-time = "2025-06-09T23:00:49.742Z" }, { url = "https://files.pythonhosted.org/packages/be/00/711d1337c7327d88c44d91dd0f556a1c47fb99afc060ae0ef66b4d24793d/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8fc5d5cda37f62b262405cf9652cf0856839c4be8ee41be0afe8858f17f4c94b", size = 244116, upload-time = "2025-06-09T23:00:51.352Z" }, { url = "https://files.pythonhosted.org/packages/24/fe/74e6ec0639c115df13d5850e75722750adabdc7de24e37e05a40527ca539/frozenlist-1.7.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0d5ce521d1dd7d620198829b87ea002956e4319002ef0bc8d3e6d045cb4646e", size = 224557, upload-time = "2025-06-09T23:00:52.855Z" }, { url = "https://files.pythonhosted.org/packages/8d/db/48421f62a6f77c553575201e89048e97198046b793f4a089c79a6e3268bd/frozenlist-1.7.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:488d0a7d6a0008ca0db273c542098a0fa9e7dfaa7e57f70acef43f32b3f69dca", size = 241820, upload-time = "2025-06-09T23:00:54.43Z" }, { url = "https://files.pythonhosted.org/packages/1d/fa/cb4a76bea23047c8462976ea7b7a2bf53997a0ca171302deae9d6dd12096/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:15a7eaba63983d22c54d255b854e8108e7e5f3e89f647fc854bd77a237e767df", size = 236542, upload-time = "2025-06-09T23:00:56.409Z" }, { url = "https://files.pythonhosted.org/packages/5d/32/476a4b5cfaa0ec94d3f808f193301debff2ea42288a099afe60757ef6282/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1eaa7e9c6d15df825bf255649e05bd8a74b04a4d2baa1ae46d9c2d00b2ca2cb5", size = 249350, upload-time = "2025-06-09T23:00:58.468Z" }, { url = "https://files.pythonhosted.org/packages/8d/ba/9a28042f84a6bf8ea5dbc81cfff8eaef18d78b2a1ad9d51c7bc5b029ad16/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e4389e06714cfa9d47ab87f784a7c5be91d3934cd6e9a7b85beef808297cc025", size = 225093, upload-time = "2025-06-09T23:01:00.015Z" }, { url = "https://files.pythonhosted.org/packages/bc/29/3a32959e68f9cf000b04e79ba574527c17e8842e38c91d68214a37455786/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:73bd45e1488c40b63fe5a7df892baf9e2a4d4bb6409a2b3b78ac1c6236178e01", size = 245482, upload-time = "2025-06-09T23:01:01.474Z" }, { url = "https://files.pythonhosted.org/packages/80/e8/edf2f9e00da553f07f5fa165325cfc302dead715cab6ac8336a5f3d0adc2/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:99886d98e1643269760e5fe0df31e5ae7050788dd288947f7f007209b8c33f08", size = 249590, upload-time = "2025-06-09T23:01:02.961Z" }, { url = "https://files.pythonhosted.org/packages/1c/80/9a0eb48b944050f94cc51ee1c413eb14a39543cc4f760ed12657a5a3c45a/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:290a172aae5a4c278c6da8a96222e6337744cd9c77313efe33d5670b9f65fc43", size = 237785, upload-time = "2025-06-09T23:01:05.095Z" }, { url = "https://files.pythonhosted.org/packages/f3/74/87601e0fb0369b7a2baf404ea921769c53b7ae00dee7dcfe5162c8c6dbf0/frozenlist-1.7.0-cp312-cp312-win32.whl", hash = "sha256:426c7bc70e07cfebc178bc4c2bf2d861d720c4fff172181eeb4a4c41d4ca2ad3", size = 39487, upload-time = "2025-06-09T23:01:06.54Z" }, { url = "https://files.pythonhosted.org/packages/0b/15/c026e9a9fc17585a9d461f65d8593d281fedf55fbf7eb53f16c6df2392f9/frozenlist-1.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:563b72efe5da92e02eb68c59cb37205457c977aa7a449ed1b37e6939e5c47c6a", size = 43874, upload-time = "2025-06-09T23:01:07.752Z" }, { url = "https://files.pythonhosted.org/packages/24/90/6b2cebdabdbd50367273c20ff6b57a3dfa89bd0762de02c3a1eb42cb6462/frozenlist-1.7.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee80eeda5e2a4e660651370ebffd1286542b67e268aa1ac8d6dbe973120ef7ee", size = 79791, upload-time = "2025-06-09T23:01:09.368Z" }, { url = "https://files.pythonhosted.org/packages/83/2e/5b70b6a3325363293fe5fc3ae74cdcbc3e996c2a11dde2fd9f1fb0776d19/frozenlist-1.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d1a81c85417b914139e3a9b995d4a1c84559afc839a93cf2cb7f15e6e5f6ed2d", size = 47165, upload-time = "2025-06-09T23:01:10.653Z" }, { url = "https://files.pythonhosted.org/packages/f4/25/a0895c99270ca6966110f4ad98e87e5662eab416a17e7fd53c364bf8b954/frozenlist-1.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cbb65198a9132ebc334f237d7b0df163e4de83fb4f2bdfe46c1e654bdb0c5d43", size = 45881, upload-time = "2025-06-09T23:01:12.296Z" }, { url = "https://files.pythonhosted.org/packages/19/7c/71bb0bbe0832793c601fff68cd0cf6143753d0c667f9aec93d3c323f4b55/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dab46c723eeb2c255a64f9dc05b8dd601fde66d6b19cdb82b2e09cc6ff8d8b5d", size = 232409, upload-time = "2025-06-09T23:01:13.641Z" }, { url = "https://files.pythonhosted.org/packages/c0/45/ed2798718910fe6eb3ba574082aaceff4528e6323f9a8570be0f7028d8e9/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6aeac207a759d0dedd2e40745575ae32ab30926ff4fa49b1635def65806fddee", size = 225132, upload-time = "2025-06-09T23:01:15.264Z" }, { url = "https://files.pythonhosted.org/packages/ba/e2/8417ae0f8eacb1d071d4950f32f229aa6bf68ab69aab797b72a07ea68d4f/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bd8c4e58ad14b4fa7802b8be49d47993182fdd4023393899632c88fd8cd994eb", size = 237638, upload-time = "2025-06-09T23:01:16.752Z" }, { url = "https://files.pythonhosted.org/packages/f8/b7/2ace5450ce85f2af05a871b8c8719b341294775a0a6c5585d5e6170f2ce7/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04fb24d104f425da3540ed83cbfc31388a586a7696142004c577fa61c6298c3f", size = 233539, upload-time = "2025-06-09T23:01:18.202Z" }, { url = "https://files.pythonhosted.org/packages/46/b9/6989292c5539553dba63f3c83dc4598186ab2888f67c0dc1d917e6887db6/frozenlist-1.7.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6a5c505156368e4ea6b53b5ac23c92d7edc864537ff911d2fb24c140bb175e60", size = 215646, upload-time = "2025-06-09T23:01:19.649Z" }, { url = "https://files.pythonhosted.org/packages/72/31/bc8c5c99c7818293458fe745dab4fd5730ff49697ccc82b554eb69f16a24/frozenlist-1.7.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8bd7eb96a675f18aa5c553eb7ddc24a43c8c18f22e1f9925528128c052cdbe00", size = 232233, upload-time = "2025-06-09T23:01:21.175Z" }, { url = "https://files.pythonhosted.org/packages/59/52/460db4d7ba0811b9ccb85af996019f5d70831f2f5f255f7cc61f86199795/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:05579bf020096fe05a764f1f84cd104a12f78eaab68842d036772dc6d4870b4b", size = 227996, upload-time = "2025-06-09T23:01:23.098Z" }, { url = "https://files.pythonhosted.org/packages/ba/c9/f4b39e904c03927b7ecf891804fd3b4df3db29b9e487c6418e37988d6e9d/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:376b6222d114e97eeec13d46c486facd41d4f43bab626b7c3f6a8b4e81a5192c", size = 242280, upload-time = "2025-06-09T23:01:24.808Z" }, { url = "https://files.pythonhosted.org/packages/b8/33/3f8d6ced42f162d743e3517781566b8481322be321b486d9d262adf70bfb/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:0aa7e176ebe115379b5b1c95b4096fb1c17cce0847402e227e712c27bdb5a949", size = 217717, upload-time = "2025-06-09T23:01:26.28Z" }, { url = "https://files.pythonhosted.org/packages/3e/e8/ad683e75da6ccef50d0ab0c2b2324b32f84fc88ceee778ed79b8e2d2fe2e/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3fbba20e662b9c2130dc771e332a99eff5da078b2b2648153a40669a6d0e36ca", size = 236644, upload-time = "2025-06-09T23:01:27.887Z" }, { url = "https://files.pythonhosted.org/packages/b2/14/8d19ccdd3799310722195a72ac94ddc677541fb4bef4091d8e7775752360/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:f3f4410a0a601d349dd406b5713fec59b4cee7e71678d5b17edda7f4655a940b", size = 238879, upload-time = "2025-06-09T23:01:29.524Z" }, { url = "https://files.pythonhosted.org/packages/ce/13/c12bf657494c2fd1079a48b2db49fa4196325909249a52d8f09bc9123fd7/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e2cdfaaec6a2f9327bf43c933c0319a7c429058e8537c508964a133dffee412e", size = 232502, upload-time = "2025-06-09T23:01:31.287Z" }, { url = "https://files.pythonhosted.org/packages/d7/8b/e7f9dfde869825489382bc0d512c15e96d3964180c9499efcec72e85db7e/frozenlist-1.7.0-cp313-cp313-win32.whl", hash = "sha256:5fc4df05a6591c7768459caba1b342d9ec23fa16195e744939ba5914596ae3e1", size = 39169, upload-time = "2025-06-09T23:01:35.503Z" }, { url = "https://files.pythonhosted.org/packages/35/89/a487a98d94205d85745080a37860ff5744b9820a2c9acbcdd9440bfddf98/frozenlist-1.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:52109052b9791a3e6b5d1b65f4b909703984b770694d3eb64fad124c835d7cba", size = 43219, upload-time = "2025-06-09T23:01:36.784Z" }, { url = "https://files.pythonhosted.org/packages/56/d5/5c4cf2319a49eddd9dd7145e66c4866bdc6f3dbc67ca3d59685149c11e0d/frozenlist-1.7.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:a6f86e4193bb0e235ef6ce3dde5cbabed887e0b11f516ce8a0f4d3b33078ec2d", size = 84345, upload-time = "2025-06-09T23:01:38.295Z" }, { url = "https://files.pythonhosted.org/packages/a4/7d/ec2c1e1dc16b85bc9d526009961953df9cec8481b6886debb36ec9107799/frozenlist-1.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:82d664628865abeb32d90ae497fb93df398a69bb3434463d172b80fc25b0dd7d", size = 48880, upload-time = "2025-06-09T23:01:39.887Z" }, { url = "https://files.pythonhosted.org/packages/69/86/f9596807b03de126e11e7d42ac91e3d0b19a6599c714a1989a4e85eeefc4/frozenlist-1.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:912a7e8375a1c9a68325a902f3953191b7b292aa3c3fb0d71a216221deca460b", size = 48498, upload-time = "2025-06-09T23:01:41.318Z" }, { url = "https://files.pythonhosted.org/packages/5e/cb/df6de220f5036001005f2d726b789b2c0b65f2363b104bbc16f5be8084f8/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9537c2777167488d539bc5de2ad262efc44388230e5118868e172dd4a552b146", size = 292296, upload-time = "2025-06-09T23:01:42.685Z" }, { url = "https://files.pythonhosted.org/packages/83/1f/de84c642f17c8f851a2905cee2dae401e5e0daca9b5ef121e120e19aa825/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:f34560fb1b4c3e30ba35fa9a13894ba39e5acfc5f60f57d8accde65f46cc5e74", size = 273103, upload-time = "2025-06-09T23:01:44.166Z" }, { url = "https://files.pythonhosted.org/packages/88/3c/c840bfa474ba3fa13c772b93070893c6e9d5c0350885760376cbe3b6c1b3/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:acd03d224b0175f5a850edc104ac19040d35419eddad04e7cf2d5986d98427f1", size = 292869, upload-time = "2025-06-09T23:01:45.681Z" }, { url = "https://files.pythonhosted.org/packages/a6/1c/3efa6e7d5a39a1d5ef0abeb51c48fb657765794a46cf124e5aca2c7a592c/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2038310bc582f3d6a09b3816ab01737d60bf7b1ec70f5356b09e84fb7408ab1", size = 291467, upload-time = "2025-06-09T23:01:47.234Z" }, { url = "https://files.pythonhosted.org/packages/4f/00/d5c5e09d4922c395e2f2f6b79b9a20dab4b67daaf78ab92e7729341f61f6/frozenlist-1.7.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8c05e4c8e5f36e5e088caa1bf78a687528f83c043706640a92cb76cd6999384", size = 266028, upload-time = "2025-06-09T23:01:48.819Z" }, { url = "https://files.pythonhosted.org/packages/4e/27/72765be905619dfde25a7f33813ac0341eb6b076abede17a2e3fbfade0cb/frozenlist-1.7.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:765bb588c86e47d0b68f23c1bee323d4b703218037765dcf3f25c838c6fecceb", size = 284294, upload-time = "2025-06-09T23:01:50.394Z" }, { url = "https://files.pythonhosted.org/packages/88/67/c94103a23001b17808eb7dd1200c156bb69fb68e63fcf0693dde4cd6228c/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:32dc2e08c67d86d0969714dd484fd60ff08ff81d1a1e40a77dd34a387e6ebc0c", size = 281898, upload-time = "2025-06-09T23:01:52.234Z" }, { url = "https://files.pythonhosted.org/packages/42/34/a3e2c00c00f9e2a9db5653bca3fec306349e71aff14ae45ecc6d0951dd24/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:c0303e597eb5a5321b4de9c68e9845ac8f290d2ab3f3e2c864437d3c5a30cd65", size = 290465, upload-time = "2025-06-09T23:01:53.788Z" }, { url = "https://files.pythonhosted.org/packages/bb/73/f89b7fbce8b0b0c095d82b008afd0590f71ccb3dee6eee41791cf8cd25fd/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:a47f2abb4e29b3a8d0b530f7c3598badc6b134562b1a5caee867f7c62fee51e3", size = 266385, upload-time = "2025-06-09T23:01:55.769Z" }, { url = "https://files.pythonhosted.org/packages/cd/45/e365fdb554159462ca12df54bc59bfa7a9a273ecc21e99e72e597564d1ae/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:3d688126c242a6fabbd92e02633414d40f50bb6002fa4cf995a1d18051525657", size = 288771, upload-time = "2025-06-09T23:01:57.4Z" }, { url = "https://files.pythonhosted.org/packages/00/11/47b6117002a0e904f004d70ec5194fe9144f117c33c851e3d51c765962d0/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:4e7e9652b3d367c7bd449a727dc79d5043f48b88d0cbfd4f9f1060cf2b414104", size = 288206, upload-time = "2025-06-09T23:01:58.936Z" }, { url = "https://files.pythonhosted.org/packages/40/37/5f9f3c3fd7f7746082ec67bcdc204db72dad081f4f83a503d33220a92973/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:1a85e345b4c43db8b842cab1feb41be5cc0b10a1830e6295b69d7310f99becaf", size = 282620, upload-time = "2025-06-09T23:02:00.493Z" }, { url = "https://files.pythonhosted.org/packages/0b/31/8fbc5af2d183bff20f21aa743b4088eac4445d2bb1cdece449ae80e4e2d1/frozenlist-1.7.0-cp313-cp313t-win32.whl", hash = "sha256:3a14027124ddb70dfcee5148979998066897e79f89f64b13328595c4bdf77c81", size = 43059, upload-time = "2025-06-09T23:02:02.072Z" }, { url = "https://files.pythonhosted.org/packages/bb/ed/41956f52105b8dbc26e457c5705340c67c8cc2b79f394b79bffc09d0e938/frozenlist-1.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3bf8010d71d4507775f658e9823210b7427be36625b387221642725b515dcf3e", size = 47516, upload-time = "2025-06-09T23:02:03.779Z" }, { url = "https://files.pythonhosted.org/packages/dd/b1/ee59496f51cd244039330015d60f13ce5a54a0f2bd8d79e4a4a375ab7469/frozenlist-1.7.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cea3dbd15aea1341ea2de490574a4a37ca080b2ae24e4b4f4b51b9057b4c3630", size = 82434, upload-time = "2025-06-09T23:02:05.195Z" }, { url = "https://files.pythonhosted.org/packages/75/e1/d518391ce36a6279b3fa5bc14327dde80bcb646bb50d059c6ca0756b8d05/frozenlist-1.7.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7d536ee086b23fecc36c2073c371572374ff50ef4db515e4e503925361c24f71", size = 48232, upload-time = "2025-06-09T23:02:07.728Z" }, { url = "https://files.pythonhosted.org/packages/b7/8d/a0d04f28b6e821a9685c22e67b5fb798a5a7b68752f104bfbc2dccf080c4/frozenlist-1.7.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dfcebf56f703cb2e346315431699f00db126d158455e513bd14089d992101e44", size = 47186, upload-time = "2025-06-09T23:02:09.243Z" }, { url = "https://files.pythonhosted.org/packages/93/3a/a5334c0535c8b7c78eeabda1579179e44fe3d644e07118e59a2276dedaf1/frozenlist-1.7.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:974c5336e61d6e7eb1ea5b929cb645e882aadab0095c5a6974a111e6479f8878", size = 226617, upload-time = "2025-06-09T23:02:10.949Z" }, { url = "https://files.pythonhosted.org/packages/0a/67/8258d971f519dc3f278c55069a775096cda6610a267b53f6248152b72b2f/frozenlist-1.7.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c70db4a0ab5ab20878432c40563573229a7ed9241506181bba12f6b7d0dc41cb", size = 224179, upload-time = "2025-06-09T23:02:12.603Z" }, { url = "https://files.pythonhosted.org/packages/fc/89/8225905bf889b97c6d935dd3aeb45668461e59d415cb019619383a8a7c3b/frozenlist-1.7.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1137b78384eebaf70560a36b7b229f752fb64d463d38d1304939984d5cb887b6", size = 235783, upload-time = "2025-06-09T23:02:14.678Z" }, { url = "https://files.pythonhosted.org/packages/54/6e/ef52375aa93d4bc510d061df06205fa6dcfd94cd631dd22956b09128f0d4/frozenlist-1.7.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e793a9f01b3e8b5c0bc646fb59140ce0efcc580d22a3468d70766091beb81b35", size = 229210, upload-time = "2025-06-09T23:02:16.313Z" }, { url = "https://files.pythonhosted.org/packages/ee/55/62c87d1a6547bfbcd645df10432c129100c5bd0fd92a384de6e3378b07c1/frozenlist-1.7.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:74739ba8e4e38221d2c5c03d90a7e542cb8ad681915f4ca8f68d04f810ee0a87", size = 215994, upload-time = "2025-06-09T23:02:17.9Z" }, { url = "https://files.pythonhosted.org/packages/45/d2/263fea1f658b8ad648c7d94d18a87bca7e8c67bd6a1bbf5445b1bd5b158c/frozenlist-1.7.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e63344c4e929b1a01e29bc184bbb5fd82954869033765bfe8d65d09e336a677", size = 225122, upload-time = "2025-06-09T23:02:19.479Z" }, { url = "https://files.pythonhosted.org/packages/7b/22/7145e35d12fb368d92124f679bea87309495e2e9ddf14c6533990cb69218/frozenlist-1.7.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2ea2a7369eb76de2217a842f22087913cdf75f63cf1307b9024ab82dfb525938", size = 224019, upload-time = "2025-06-09T23:02:20.969Z" }, { url = "https://files.pythonhosted.org/packages/44/1e/7dae8c54301beb87bcafc6144b9a103bfd2c8f38078c7902984c9a0c4e5b/frozenlist-1.7.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:836b42f472a0e006e02499cef9352ce8097f33df43baaba3e0a28a964c26c7d2", size = 239925, upload-time = "2025-06-09T23:02:22.466Z" }, { url = "https://files.pythonhosted.org/packages/4b/1e/99c93e54aa382e949a98976a73b9b20c3aae6d9d893f31bbe4991f64e3a8/frozenlist-1.7.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e22b9a99741294b2571667c07d9f8cceec07cb92aae5ccda39ea1b6052ed4319", size = 220881, upload-time = "2025-06-09T23:02:24.521Z" }, { url = "https://files.pythonhosted.org/packages/5e/9c/ca5105fa7fb5abdfa8837581be790447ae051da75d32f25c8f81082ffc45/frozenlist-1.7.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:9a19e85cc503d958abe5218953df722748d87172f71b73cf3c9257a91b999890", size = 234046, upload-time = "2025-06-09T23:02:26.206Z" }, { url = "https://files.pythonhosted.org/packages/8d/4d/e99014756093b4ddbb67fb8f0df11fe7a415760d69ace98e2ac6d5d43402/frozenlist-1.7.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:f22dac33bb3ee8fe3e013aa7b91dc12f60d61d05b7fe32191ffa84c3aafe77bd", size = 235756, upload-time = "2025-06-09T23:02:27.79Z" }, { url = "https://files.pythonhosted.org/packages/8b/72/a19a40bcdaa28a51add2aaa3a1a294ec357f36f27bd836a012e070c5e8a5/frozenlist-1.7.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9ccec739a99e4ccf664ea0775149f2749b8a6418eb5b8384b4dc0a7d15d304cb", size = 222894, upload-time = "2025-06-09T23:02:29.848Z" }, { url = "https://files.pythonhosted.org/packages/08/49/0042469993e023a758af81db68c76907cd29e847d772334d4d201cbe9a42/frozenlist-1.7.0-cp39-cp39-win32.whl", hash = "sha256:b3950f11058310008a87757f3eee16a8e1ca97979833239439586857bc25482e", size = 39848, upload-time = "2025-06-09T23:02:31.413Z" }, { url = "https://files.pythonhosted.org/packages/5a/45/827d86ee475c877f5f766fbc23fb6acb6fada9e52f1c9720e2ba3eae32da/frozenlist-1.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:43a82fce6769c70f2f5a06248b614a7d268080a9d20f7457ef10ecee5af82b63", size = 44102, upload-time = "2025-06-09T23:02:32.808Z" }, { url = "https://files.pythonhosted.org/packages/ee/45/b82e3c16be2182bff01179db177fe144d58b5dc787a7d4492c6ed8b9317f/frozenlist-1.7.0-py3-none-any.whl", hash = "sha256:9a5af342e34f7e97caf8c995864c7a396418ae2859cc6fdf1b1073020d516a7e", size = 13106, upload-time = "2025-06-09T23:02:34.204Z" }, ] [[package]] name = "google-auth" version = "2.40.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cachetools" }, { name = "pyasn1-modules" }, { name = "rsa" }, ] sdist = { url = "https://files.pythonhosted.org/packages/9e/9b/e92ef23b84fa10a64ce4831390b7a4c2e53c0132568d99d4ae61d04c8855/google_auth-2.40.3.tar.gz", hash = "sha256:500c3a29adedeb36ea9cf24b8d10858e152f2412e3ca37829b3fa18e33d63b77", size = 281029, upload-time = "2025-06-04T18:04:57.577Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/17/63/b19553b658a1692443c62bd07e5868adaa0ad746a0751ba62c59568cd45b/google_auth-2.40.3-py2.py3-none-any.whl", hash = "sha256:1370d4593e86213563547f97a92752fc658456fe4514c809544f330fed45a7ca", size = 216137, upload-time = "2025-06-04T18:04:55.573Z" }, ] [package.optional-dependencies] requests = [ { name = "requests", version = "2.32.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "requests", version = "2.32.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] [[package]] name = "griffe" version = "1.4.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] dependencies = [ { name = "astunparse", marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "colorama", marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/05/e9/b2c86ad9d69053e497a24ceb25d661094fb321ab4ed39a8b71793dcbae82/griffe-1.4.0.tar.gz", hash = "sha256:8fccc585896d13f1221035d32c50dec65830c87d23f9adb9b1e6f3d63574f7f5", size = 381028, upload-time = "2024-10-11T12:53:54.414Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/22/7c/e9e66869c2e4c9b378474e49c993128ec0131ef4721038b6d06e50538caf/griffe-1.4.0-py3-none-any.whl", hash = "sha256:e589de8b8c137e99a46ec45f9598fc0ac5b6868ce824b24db09c02d117b89bc5", size = 127015, upload-time = "2024-10-11T12:53:52.383Z" }, ] [[package]] name = "griffe" version = "1.13.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.10'", "python_full_version == '3.9.*'", ] dependencies = [ { name = "colorama", marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c6/b5/23b91f22b7b3a7f8f62223f6664946271c0f5cb4179605a3e6bbae863920/griffe-1.13.0.tar.gz", hash = "sha256:246ea436a5e78f7fbf5f24ca8a727bb4d2a4b442a2959052eea3d0bfe9a076e0", size = 412759, upload-time = "2025-08-26T13:27:11.422Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/aa/8c/b7cfdd8dfe48f6b09f7353323732e1a290c388bd14f216947928dc85f904/griffe-1.13.0-py3-none-any.whl", hash = "sha256:470fde5b735625ac0a36296cd194617f039e9e83e301fcbd493e2b58382d0559", size = 139365, upload-time = "2025-08-26T13:27:09.882Z" }, ] [[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", version = "4.5.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "anyio", version = "4.8.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { 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.8" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohttp", version = "3.10.11", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "aiohttp", version = "3.12.13", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "httpx" }, ] sdist = { url = "https://files.pythonhosted.org/packages/37/19/ae2d2bf1f57fdd23c8ad83675599fb5c407fa13bc20e90f00cffa4dea3aa/httpx_aiohttp-0.1.8.tar.gz", hash = "sha256:756c5e74cdb568c3248ba63fe82bfe8bbe64b928728720f7eaac64b3cf46f308", size = 25401, upload-time = "2025-07-04T10:40:32.329Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/54/7a/514c484b88cc4ebbcd2e27e92b86019c0c5bb920582f5fbb10b7e6c78574/httpx_aiohttp-0.1.8-py3-none-any.whl", hash = "sha256:b7bd958d1331f3759a38a0ba22ad29832cb63ca69498c17735228055bf78fa7e", size = 6180, upload-time = "2025-07-04T10:40:31.522Z" }, ] [[package]] name = "idna" version = "3.10" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, ] [[package]] name = "importlib-metadata" version = "8.5.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] dependencies = [ { name = "zipp", version = "3.20.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cd/12/33e59336dca5be0c398a7482335911a33aa0e20776128f038019f1a95f1b/importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7", size = 55304, upload-time = "2024-09-11T14:56:08.937Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/a0/d9/a1e041c5e7caa9a05c925f4bdbdfb7f006d1f74996af53467bc394c97be7/importlib_metadata-8.5.0-py3-none-any.whl", hash = "sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b", size = 26514, upload-time = "2024-09-11T14:56:07.019Z" }, ] [[package]] name = "importlib-metadata" version = "8.6.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.10'", "python_full_version == '3.9.*'", ] dependencies = [ { name = "zipp", version = "3.21.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/33/08/c1395a292bb23fd03bdf572a1357c5a733d3eecbab877641ceacab23db6e/importlib_metadata-8.6.1.tar.gz", hash = "sha256:310b41d755445d74569f993ccfc22838295d9fe005425094fad953d7f15c8580", size = 55767, upload-time = "2025-01-20T22:21:30.429Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/79/9d/0fb148dc4d6fa4a7dd1d8378168d9b4cd8d4560a6fbf6f0121c5fc34eb68/importlib_metadata-8.6.1-py3-none-any.whl", hash = "sha256:02a89390c1e15fdfdc0d7c6b25cb3e62650d0494005c97d6f148bf5b9787525e", size = 26971, upload-time = "2025-01-20T22:21:29.177Z" }, ] [[package]] name = "iniconfig" version = "2.0.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646, upload-time = "2023-01-07T11:08:11.254Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892, upload-time = "2023-01-07T11:08:09.864Z" }, ] [[package]] name = "inline-snapshot" version = "0.29.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "asttokens" }, { name = "executing" }, { name = "pytest", version = "8.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "pytest", version = "8.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "rich" }, { name = "tomli", marker = "python_full_version < '3.11' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/1c/4d/8e3b89f00df7925942acb091809ca32395373dc579517abacec5e242e8bd/inline_snapshot-0.29.0.tar.gz", hash = "sha256:8bac016fc8ff4638a6cdebca96d7042fecde471f0574d360de11f552ba77d6b5", size = 349586, upload-time = "2025-09-15T07:03:05.455Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/2d/eb/5ab8628a3289fab7ab28ccd59ef6d3ef4b28706c3065388df9f975ed29b6/inline_snapshot-0.29.0-py3-none-any.whl", hash = "sha256:aaea04480f1b5ec741b9025da45c00cb166d8791f01bed0f5ea7eabd1f9784cd", size = 70235, upload-time = "2025-09-15T07:03:03.616Z" }, ] [[package]] name = "jiter" version = "0.9.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] sdist = { url = "https://files.pythonhosted.org/packages/84/72/c28662416d9807bb5a38625eadedb82d4bd14fd2700c308ece7acdb8e89f/jiter-0.9.1.tar.gz", hash = "sha256:7852990068b6e06102ecdc44c1619855a2af63347bfb5e7e009928dcacf04fdd", size = 162540, upload-time = "2025-05-18T17:47:14.707Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/2b/5f/7f6aaca7943c644b4fd220650771f39dbfb74f9690efc6fb8c0d4092a399/jiter-0.9.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:c0163baa7ee85860fdc14cc39263014500df901eeffdf94c1eab9a2d713b2a9d", size = 312882, upload-time = "2025-05-18T17:45:14.056Z" }, { url = "https://files.pythonhosted.org/packages/86/0d/aac9eafc5d46bdf5c4f127ac1ce85e434d003bb5e3ae886f5e726a988cf6/jiter-0.9.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:514d4dd845e0af4da15112502e6fcb952f0721f27f17e530454e379472b90c14", size = 311743, upload-time = "2025-05-18T17:45:16.196Z" }, { url = "https://files.pythonhosted.org/packages/b8/54/fab1f4d8634af7bb1ad6dc49bee50ea9f649de0e5309c80192ace739f968/jiter-0.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b879faee1cc1a67fde3f3f370041239fd260ac452bd53e861aa4a94a51e3fd02", size = 1085889, upload-time = "2025-05-18T17:45:17.883Z" }, { url = "https://files.pythonhosted.org/packages/bd/86/bf4ed251d8035d5d72a46c8f9969bd5054fad052371cbea0cb161060e660/jiter-0.9.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:20a5ce641f93bfb8d8e336f8c4a045e491652f41eaacc707b15b245ece611e72", size = 1117896, upload-time = "2025-05-18T17:45:19.82Z" }, { url = "https://files.pythonhosted.org/packages/62/40/b04c40deccd5edd5f2a3853f4a80dc0ddbe157d1d523a573fb3d224315fc/jiter-0.9.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8575b1d2b49df04ca82d658882f4a432b7ed315a69126a379df4d10aeb416021", size = 1211956, upload-time = "2025-05-18T17:45:21.606Z" }, { url = "https://files.pythonhosted.org/packages/85/f0/114e9893e4ef5b423718efe9b3da01117539c333f06ef19543c68c8b7ed1/jiter-0.9.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cc61831699904e0c58e82943f529713833db87acd13f95a3c0feb791f862d47b", size = 1219691, upload-time = "2025-05-18T17:45:23.061Z" }, { url = "https://files.pythonhosted.org/packages/02/9a/1aeac4541ce1c59c65dc76dbab642232da3d8db0581df3e61b8943033bd7/jiter-0.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fb733faf4d0e730d6663873249c1acb572fc8bd9dae3836ceda69751f27c5be", size = 352604, upload-time = "2025-05-18T17:45:24.485Z" }, { url = "https://files.pythonhosted.org/packages/6b/27/446ec6ca0a25d9d2f45ad546633a2b4a1b6a7f28fb6819c7056b163c5aee/jiter-0.9.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d903b3bb917c0df24f2ef62f587c8f32f6003cb2f97264109ca56c023262557f", size = 1147136, upload-time = "2025-05-18T17:45:25.832Z" }, { url = "https://files.pythonhosted.org/packages/09/9d/c8540bc097b07e106d060c21395c6fa6561223e7366c948a04ef0aa39979/jiter-0.9.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:eac3eb5206845b170142c016ae467eca523a25459dc9c53fcd8e154ea263406c", size = 1255843, upload-time = "2025-05-18T17:45:27.513Z" }, { url = "https://files.pythonhosted.org/packages/d3/61/9b377ecf4e09e325e90f77a7a4859ec933162f58ff5c6b7730aff6352033/jiter-0.9.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7ea0c20cfc61acc5335bb8ee36d639e6a4ded03f34f878b2b3038bb9f3bb553c", size = 1257536, upload-time = "2025-05-18T17:45:29.304Z" }, { url = "https://files.pythonhosted.org/packages/ed/f6/b6754e11ac9d02f05a2d713c0846ce813a69c1f6f7de7f1ae216c4e35ace/jiter-0.9.1-cp310-cp310-win32.whl", hash = "sha256:0f8f812dd6d2b4112db9ab4c1079c4fe73e553a500e936657fdda394fa2517e1", size = 214064, upload-time = "2025-05-18T17:45:31.037Z" }, { url = "https://files.pythonhosted.org/packages/1d/cb/7b9c5d6f73499d1fb5e97e36e8078f3bea00d7541a973117eccf9db1e079/jiter-0.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:f7f0198889170e7af6210509803e6527b402efc6c26f42e2896883597a10426f", size = 209952, upload-time = "2025-05-18T17:45:32.772Z" }, { url = "https://files.pythonhosted.org/packages/ee/3b/9f9deaef471e346354c832b6627e0d1b9ba3d9611d0e0fd394c2acf2a615/jiter-0.9.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6b8564e3198c4c8d835fc95cc54d6bcbd2fd8dc33a047fecc12c208491196995", size = 312737, upload-time = "2025-05-18T17:45:34.456Z" }, { url = "https://files.pythonhosted.org/packages/36/00/76fa6d519f8289aad32ec1caf3716eb700ba48e3212d1dda71e74c385a5c/jiter-0.9.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:90b92044588d14efe89b394eca735adc4ac096eba82dc75d93c3083b1eebce8d", size = 313357, upload-time = "2025-05-18T17:45:36.672Z" }, { url = "https://files.pythonhosted.org/packages/b3/e9/f864ebe9ddf07761d5bdd3148b45a5d433c6cbce7c7e8be29baf806fa612/jiter-0.9.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3505f7f419b355c7788fcaae0dfc4c6ccbc50c0dc3633a2da797e841c5a423dc", size = 1085946, upload-time = "2025-05-18T17:45:37.989Z" }, { url = "https://files.pythonhosted.org/packages/82/a1/ed02d4c86d620989dcd392366daa67198961eedaf2e66f7a68f0d3846dba/jiter-0.9.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:93af8c3f4a3bf145c690e857a945eb5c655534bf95c67e1447d85c02e5af64d7", size = 1118090, upload-time = "2025-05-18T17:45:39.322Z" }, { url = "https://files.pythonhosted.org/packages/d3/01/d107531d215a57cda3cbc4adfcf3119166dd32adc1c332c1f3f36efd3484/jiter-0.9.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:43b81dd21e260a249780764921b1f9a6379cb31e24e7b61e6bf0799f38ec4b91", size = 1212231, upload-time = "2025-05-18T17:45:40.738Z" }, { url = "https://files.pythonhosted.org/packages/45/1e/6801a81a2ef1f917fe9a7d2139e576dd4f53497c309dab9461136922709c/jiter-0.9.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:db639fad5631b3d1692609f6dd77b64e8578321b7aeec07a026acd2c867c04a5", size = 1219263, upload-time = "2025-05-18T17:45:42.698Z" }, { url = "https://files.pythonhosted.org/packages/a5/d4/40082e8666cfdb24461855e9bb29fe77f063cc65a6c903291f2e5225f780/jiter-0.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15356b943e70ca7ab3b587ffaffadc0158467f6c4e0b491e52a0743c4bdf5ba1", size = 350364, upload-time = "2025-05-18T17:45:44.257Z" }, { url = "https://files.pythonhosted.org/packages/c4/09/09bc72dd143f76acd55e04c3a45b9f9ee3ed28e00b49924e3702ad041812/jiter-0.9.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:53a7033a46141ff815518a6972d657c75d8f5946b9315e1c25b07e9677c1ff6c", size = 1146802, upload-time = "2025-05-18T17:45:45.945Z" }, { url = "https://files.pythonhosted.org/packages/5b/34/9d15a9c04d5760537b432134447bde94b936ec73dc922b4d14a48def2e1f/jiter-0.9.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:68cf519a6f00b8127f9be64a37e97e978094438abced5adebe088a98c64bdcff", size = 1256019, upload-time = "2025-05-18T17:45:47.544Z" }, { url = "https://files.pythonhosted.org/packages/8f/01/1fcd165fb28968a54bb46a209d5919f7649b96608eef7dc4622ea378b95a/jiter-0.9.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9098abdd34cd9ddeb04768cc4f5fc725ebd9a52978c488da74e58a837ce93506", size = 1257610, upload-time = "2025-05-18T17:45:48.902Z" }, { url = "https://files.pythonhosted.org/packages/9f/87/93ac6a57331dd90e4c896ac852bf8ce6b28b40dace4b9698a207dbb99af2/jiter-0.9.1-cp311-cp311-win32.whl", hash = "sha256:7179ce96aecd096af890dd57b84133e47a59fbde32a77734f09bafa6a4da619e", size = 214515, upload-time = "2025-05-18T17:45:50.248Z" }, { url = "https://files.pythonhosted.org/packages/bb/ee/3678b8a3bd5f6471d0a492540e7ff9c63db278d844214458ec5cfb22adb2/jiter-0.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:e6517f5b7b6f60fd77fc1099572f445be19553c6f61b907ab5b413fb7179663f", size = 212258, upload-time = "2025-05-18T17:45:51.983Z" }, { url = "https://files.pythonhosted.org/packages/ba/a7/5b3ce91b5bb83bf47e85ab2efda26a1706fb52498a2abe79df09af7dfa8f/jiter-0.9.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f330c5023ce4153ceb3e8abe76ecab8c5b525824bcec4e781791d044e5b5fc3a", size = 307494, upload-time = "2025-05-18T17:45:53.639Z" }, { url = "https://files.pythonhosted.org/packages/fd/9a/006ebbb5ab55fd9f47c219f9de7fdedd38694c158ddd6760a15f7a6fcdc8/jiter-0.9.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:77de4d2d529ece2d43fc0dbe90971e9e18f42ed6dd50b40fe232e799efb72c29", size = 312782, upload-time = "2025-05-18T17:45:55.384Z" }, { url = "https://files.pythonhosted.org/packages/17/da/a437705850c8cf6b8c93769ff6fcb3abcbfeb9c12b690c5f1631682d4286/jiter-0.9.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ed3eec217a70762a01ecfbecea27eda91d7d5792bdef41096d2c672a9e3c1fe", size = 1087076, upload-time = "2025-05-18T17:45:56.866Z" }, { url = "https://files.pythonhosted.org/packages/e6/8b/f463a03de974d437abc312a0ca6212e2b014b7023a880fd6956ebfde15c7/jiter-0.9.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d000bb8b9b3a90fb61ff864869461c56ad2dad5f0fa71127464cb65e69ec864b", size = 1118826, upload-time = "2025-05-18T17:45:58.359Z" }, { url = "https://files.pythonhosted.org/packages/6a/04/4d9289d8610f2b10886b4bd32b0c6e036fdeabc86cc9a902e50434a066bd/jiter-0.9.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3610aed85fad26d5e107ce4e246c236b612e539b382d490761aacc4aa5d7cdbf", size = 1213155, upload-time = "2025-05-18T17:45:59.719Z" }, { url = "https://files.pythonhosted.org/packages/f3/4c/851c0a7c95e333d5213558fc76d217a7760de8b704299c007537af49e1de/jiter-0.9.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ae8f1f42f4b0ed244f88bb863d0777292e76e43ee2dc0dac4d63fe29bee183e5", size = 1215024, upload-time = "2025-05-18T17:46:01.083Z" }, { url = "https://files.pythonhosted.org/packages/8f/24/9c62f5775645715ded77a4cf03b9f3c36d4909ee35b07f65bb4ccaad4bfd/jiter-0.9.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2082da43e7b6174c3522a6905a9ee9187c9771e32cad7ab58360f189595a7c3f", size = 350280, upload-time = "2025-05-18T17:46:02.912Z" }, { url = "https://files.pythonhosted.org/packages/d9/79/54a4b1074f1f048ca822a2f4a738fa7b623203540a59ec99d0b0277c38ef/jiter-0.9.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d82b2b8bc089c4ebff99907bdb890730e05c58169d5493473c916518f8d29f5c", size = 1150978, upload-time = "2025-05-18T17:46:04.229Z" }, { url = "https://files.pythonhosted.org/packages/9c/1b/caaa8d274ba82486dfb582e32f431412f2e178344ebf6a231b8606c048fd/jiter-0.9.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:8b7214d4064759ff34846311cabcf49715e8a7286a4431bc7444537ee2f21b1a", size = 1257583, upload-time = "2025-05-18T17:46:06.113Z" }, { url = "https://files.pythonhosted.org/packages/19/f7/a5f991075b16b76b15e4da7939243f373ff4369ce41145be428c7c43d905/jiter-0.9.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:136a635797b27aeb5cacea4d0ffeff5c80081089217c5891bd28968e5df97824", size = 1258268, upload-time = "2025-05-18T17:46:08.564Z" }, { url = "https://files.pythonhosted.org/packages/94/8f/6fabe1aa77637be629e73db2ee3059889b893c4be391f0e038b71948d208/jiter-0.9.1-cp312-cp312-win32.whl", hash = "sha256:5da9a4e2939c4af7617fe01f7e3978fba224d93def72bc748d173f148a8b637f", size = 214250, upload-time = "2025-05-18T17:46:10.108Z" }, { url = "https://files.pythonhosted.org/packages/7d/18/6f118d22acf5930d5a46c4f6853eead883af8c097d83e2a2971308864423/jiter-0.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:d1434a05965d0c1f033061f21553fef5c3a352f3e880a0f503e79e6b639db10c", size = 211070, upload-time = "2025-05-18T17:46:11.39Z" }, { url = "https://files.pythonhosted.org/packages/e2/36/4b5c7c96ce4795376e546bcabd96d8fe8667c9fdeb946523ca382cc30eaa/jiter-0.9.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:cb0629af6a12804ace5f093884c2f14d5075d95951a086054e106cfdb6b8862f", size = 307047, upload-time = "2025-05-18T17:46:13.192Z" }, { url = "https://files.pythonhosted.org/packages/3e/20/7635fb02fe62cd90899dc1c64c972c1470106eede55ce35fc6e3868251af/jiter-0.9.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d15cc2b5602fb5a16689afb507b27c650167152203394efa429a5139553dd993", size = 311796, upload-time = "2025-05-18T17:46:14.455Z" }, { url = "https://files.pythonhosted.org/packages/e4/43/7e4a38c63b9f1a5795d406a7cf1e8a42af0e51d05d5c5b866708a345d49e/jiter-0.9.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffbf9279273b41fb8c4360ad2590a8eea82b36665728f57b0d7b095a904016d9", size = 1086812, upload-time = "2025-05-18T17:46:15.765Z" }, { url = "https://files.pythonhosted.org/packages/30/17/3d5ad7a1e12bb172040c2e206068ee766a320c6b6327a0a52a9c05bf4cd6/jiter-0.9.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3fca2935783d4309eed77ed2acd625f93a07b79693f7d8e58e3c18ac8981e9ea", size = 1118218, upload-time = "2025-05-18T17:46:17.876Z" }, { url = "https://files.pythonhosted.org/packages/a0/f7/9f46d976a91f339898783962043c36b8c9fe103135f264ae25dddad9838e/jiter-0.9.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f3f5f14d63924d3b226236c746ceb37f5ac9d3ce1251762819024f84904b4a0f", size = 1211346, upload-time = "2025-05-18T17:46:19.823Z" }, { url = "https://files.pythonhosted.org/packages/93/71/cf594ec8c76188b5e42fc4f00a9cdfb3f675631234f5a1ac5413fe6684cb/jiter-0.9.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0d43dcddb437096ac48e85f6be8355d806ab9246051f95263933fa5e18d026aa", size = 1214466, upload-time = "2025-05-18T17:46:21.639Z" }, { url = "https://files.pythonhosted.org/packages/e2/e5/efd89f27838ea9d8257c9bc8edd58a953e06ca304c7d2b397fdd2a932e51/jiter-0.9.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19773c6f730523effbca88c4a15658b481cf81e4c981fcd1212dd4beaa0cd37a", size = 350245, upload-time = "2025-05-18T17:46:22.962Z" }, { url = "https://files.pythonhosted.org/packages/b3/78/b7960c8a04d593687659007e6b7f911ef3f877eb11cd2503267ad5b2da0b/jiter-0.9.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:01fcc08b6d3e29562d72edfcd6c5b0aab30b964fb0c99ad8287c2dffeb6fd38c", size = 1149223, upload-time = "2025-05-18T17:46:25.732Z" }, { url = "https://files.pythonhosted.org/packages/65/60/4777b5a70febeece230593a82a69d0d19b5b6e36a8b3afcc4b43528c2657/jiter-0.9.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:448afc1a801a518ed438667229f380bb0b8503f379d170ac947575cb7e1e4edf", size = 1257025, upload-time = "2025-05-18T17:46:27.162Z" }, { url = "https://files.pythonhosted.org/packages/e8/c1/8fe3483537d85bc381bdab2a4952707d92944b1ac32074f7b33de188c2d0/jiter-0.9.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:f321fb984ed7544e77346714a25ffa5bbefddd1adcc32c8fba49030a119a31c6", size = 1257882, upload-time = "2025-05-18T17:46:29.21Z" }, { url = "https://files.pythonhosted.org/packages/7b/1a/4453114fb7b3722f8d232b3c08114535e455d7d2d4d83b44cede53ed42ae/jiter-0.9.1-cp313-cp313-win32.whl", hash = "sha256:7db7c9a95d72668545606aeaf110549f4f42679eaa3ce5c32f8f26c1838550d8", size = 214946, upload-time = "2025-05-18T17:46:30.607Z" }, { url = "https://files.pythonhosted.org/packages/15/d0/237d7dbaaafb08a6f719c8495663b76d70d6c5880a02c7b092f21292458b/jiter-0.9.1-cp313-cp313-win_amd64.whl", hash = "sha256:a6b750ef1201fe4c431f869705607ece4adaf592e497efb6bc4138efaebb4f59", size = 209888, upload-time = "2025-05-18T17:46:31.89Z" }, { url = "https://files.pythonhosted.org/packages/51/32/e90c89adbea8342b6e470f3be9c213b628ae3842810553df15d5afb386ce/jiter-0.9.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4096dba935aa2730c7642146b065855a0f5853fd9bbe22de9e3dd39fcacc37fe", size = 311645, upload-time = "2025-05-18T17:46:33.196Z" }, { url = "https://files.pythonhosted.org/packages/29/40/98fee5bab390c27d20ba82c73d12afd1db89aabeef641ae7629a31a7100f/jiter-0.9.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13ad975e0d9d2f7e54b30d9ae8e2e1c97be422e75606bddc67427721ad13cd1c", size = 352754, upload-time = "2025-05-18T17:46:34.457Z" }, { url = "https://files.pythonhosted.org/packages/9b/17/b0fa4ee5bdcb252b2407fc9528f11d8af717b7218455d23018cf314ccf6a/jiter-0.9.1-cp313-cp313t-win_amd64.whl", hash = "sha256:f11992b20f8a2d336b98b31bff4d8bfcc4bd5aef7840594e32d6cb44fb9b96cf", size = 212573, upload-time = "2025-05-18T17:46:35.855Z" }, { url = "https://files.pythonhosted.org/packages/26/ca/1c7438d66969a13938266492de65daf752754ec59f2a3f3716027c7d708f/jiter-0.9.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:95065923a49ae387bab62b1bf5f798beb12e6fb4469a079fdd0ecad64b40b272", size = 313516, upload-time = "2025-05-18T17:46:37.568Z" }, { url = "https://files.pythonhosted.org/packages/e8/d9/3a6300309e312f8ed529ae57d565f69abdb520e4f12460cefa7996d0716c/jiter-0.9.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a179fbc5c7922844a673be35099a3036a7276dc63753c6c81a77c3cb525f2f8d", size = 308161, upload-time = "2025-05-18T17:46:39.697Z" }, { url = "https://files.pythonhosted.org/packages/b3/91/2aca15be38514daf8f1a1460fd9c4b652ed09148fe109520298858be7928/jiter-0.9.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abd30dc5c0183d31faf30ce8279d723809c54b3fe6d95d922d4a4b31bc462799", size = 1086100, upload-time = "2025-05-18T17:46:41.176Z" }, { url = "https://files.pythonhosted.org/packages/9f/6f/f7ba3dfe7be08bf58939324e0bb4f4aa605eff7f2c2ac140a41221cf50a4/jiter-0.9.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9765512bdeae269843e6615377f48123432da247e18048d05e9c5685377c241c", size = 1118922, upload-time = "2025-05-18T17:46:42.651Z" }, { url = "https://files.pythonhosted.org/packages/b5/4e/b1f4d9bdba81de293e1b8672598300a9195cf3d77b0acc5f331a75695b58/jiter-0.9.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6f15cdbdc1e1e89e0d9ea581de63e03975043a4b40ab87d5554fdc440357b771", size = 1212327, upload-time = "2025-05-18T17:46:44.193Z" }, { url = "https://files.pythonhosted.org/packages/3e/ab/e417aaf5a62067bd91c5f7ed4e5ab83bd46f349449adde1159ad8e2d3a21/jiter-0.9.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b1a639b2cfe56b5b687c678ed45d68f46dfb922c2f338fdfb227eb500053929d", size = 1220860, upload-time = "2025-05-18T17:46:45.728Z" }, { url = "https://files.pythonhosted.org/packages/1e/50/c5ba756c641ca8ebc1e4ff07c03ce5c8ef5052b0238f514436f8de3c9fc4/jiter-0.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41955c9d83c8470de9cc64c97b04a3ffd2f32815bb2c4307f44d8e21542b74df", size = 344077, upload-time = "2025-05-18T17:46:47.49Z" }, { url = "https://files.pythonhosted.org/packages/c6/b3/bd7d8d4bad65aa1f4a20562233080054149785c0d7f7b9027e761335d882/jiter-0.9.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f26f6d42c330e26a6ba3471b390364faad96f3ca965a6c579957810b0c078efa", size = 1148785, upload-time = "2025-05-18T17:46:48.906Z" }, { url = "https://files.pythonhosted.org/packages/c0/12/bfd9a167709f96171312d1e0ae2c1be70a167abcc3bff6f3441967e3626a/jiter-0.9.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a23e01bd7e918f27f02d3df8721b8a395211070a8a65aeb353209b8c72720cf", size = 1255962, upload-time = "2025-05-18T17:46:50.775Z" }, { url = "https://files.pythonhosted.org/packages/5f/3c/3a79020862d2511b854b350bc9229cf228fd38b836e94f274ca940e22e95/jiter-0.9.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8a96ad217989dd9df661711c3fa2e6fb2601c4bbb482e89718110bdafbc16c9e", size = 1257561, upload-time = "2025-05-18T17:46:52.291Z" }, { url = "https://files.pythonhosted.org/packages/93/d3/7f6f8e57613d4947a872980befa6af19de9252e310ea4a512eed0fe1e064/jiter-0.9.1-cp38-cp38-win32.whl", hash = "sha256:4b180e7baa4747b3834c5a9202b1ba30dc64797f45236d9142cdb2a8807763cf", size = 215019, upload-time = "2025-05-18T17:46:54.068Z" }, { url = "https://files.pythonhosted.org/packages/9b/5d/b6f0cd60c8f702936f253644a92dee19e2c82010290e4607af462033351f/jiter-0.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:baf881de1fbc7b3343cce24f75a2ab6350e03fc13d16d00f452929788a6cdc3f", size = 199563, upload-time = "2025-05-18T17:46:55.795Z" }, { url = "https://files.pythonhosted.org/packages/4f/3a/a8a4768af26578c87894bb130bcd6fb6c97f4cb36ed7a20a664412d41935/jiter-0.9.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:ec95aa1b433c50b2b129456b4680b239ec93206ea3f86cfd41b6a70be5beb2f3", size = 313942, upload-time = "2025-05-18T17:46:57.153Z" }, { url = "https://files.pythonhosted.org/packages/63/74/05977891db48000d985a5f573493c43adf0f190eada670e51b92c9ed9139/jiter-0.9.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5d92cb50d135dbdd33b638fa2e0c6af25e1d635d38da13aa9ab05d021fb0c869", size = 308160, upload-time = "2025-05-18T17:46:58.439Z" }, { url = "https://files.pythonhosted.org/packages/21/54/75f529e90442c8ad41acd8cf08323a4f3dcaa105710b2c8a1fda56e3a462/jiter-0.9.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b146dc2464f1d96007271d08bdf79288a5f1aa4aae5329eb79dcffb1181c703e", size = 1086503, upload-time = "2025-05-18T17:47:00.286Z" }, { url = "https://files.pythonhosted.org/packages/bf/fa/02532a7ce7b712c576125d4f2614e77bc897c95b2b15e21ee25f42b3ff34/jiter-0.9.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fcf20ba858658ecd54b4710172d92009afa66d41d967c86d11607592a3c220fa", size = 1120444, upload-time = "2025-05-18T17:47:01.713Z" }, { url = "https://files.pythonhosted.org/packages/91/c2/ab8cebaea6f2691eddcc5b6c67deb1399adbd85f12ad836f7cd77be78bf8/jiter-0.9.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:147fccc44bebdb672d4c601e9312730488b840d415e201e89c8ea0929a63dacf", size = 1212370, upload-time = "2025-05-18T17:47:03.145Z" }, { url = "https://files.pythonhosted.org/packages/13/e3/90dddb7877b67cc0e1ddb864c2ca74314def26ff6542431a6e3061e0f805/jiter-0.9.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a428061aae26efaa6fb690ef9e7d6224aefe4eef7524165d073beb3cdad75f6f", size = 1221210, upload-time = "2025-05-18T17:47:05.042Z" }, { url = "https://files.pythonhosted.org/packages/81/76/90ee847519a94a4a1a8bad7addce7019f424aea03c55eacf068469226760/jiter-0.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7164d92bb901784bd3c098ac0b0beae4306ea6c741dbd3a375449a8affc5366", size = 353774, upload-time = "2025-05-18T17:47:06.445Z" }, { url = "https://files.pythonhosted.org/packages/59/a6/614a5d672d4b9c6bc9ad34579f0522577a0a78cc265069fca96543a832ca/jiter-0.9.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:93049a562233808914a2b938b0c745d7049db1667b3f42f0f5cf48e617393ba5", size = 1148581, upload-time = "2025-05-18T17:47:07.821Z" }, { url = "https://files.pythonhosted.org/packages/2d/94/c100147c310361fa83e25c4c6ce17723532147580252962b89e6085795c2/jiter-0.9.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f6dcf2cb16cc15d82a018e20eeaf169e6f6cd8c426f4c312ebe11710c623bed2", size = 1256636, upload-time = "2025-05-18T17:47:09.189Z" }, { url = "https://files.pythonhosted.org/packages/51/9a/dc82e218ba839052899df555e34f16b8ad1d7da9c01be208f65a5bf0083c/jiter-0.9.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2da9d485a7c526817cde9ff8b3394fa50ff5b782b86b6896378a3ba8844550f2", size = 1258099, upload-time = "2025-05-18T17:47:10.568Z" }, { url = "https://files.pythonhosted.org/packages/58/d5/d853e069624038950265ac0e877985b249049b624e925dab6cd11035140c/jiter-0.9.1-cp39-cp39-win32.whl", hash = "sha256:ea58c155d827d24e5ba8d7958ec4738b26be0894c0881a91d88b39ff48bb06c9", size = 214611, upload-time = "2025-05-18T17:47:12.012Z" }, { url = "https://files.pythonhosted.org/packages/cb/8d/7b6b1ee6e3d9d1a06237bbdfe4c6bb21baf323d3f70a0cc8f203de40c6b2/jiter-0.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:be2e911ecdb438951290c2079fe4190e7cc5be9e849df4caeb085b83ed620ff6", size = 211171, upload-time = "2025-05-18T17:47:13.47Z" }, ] [[package]] name = "jiter" version = "0.11.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.10'", "python_full_version == '3.9.*'", ] sdist = { url = "https://files.pythonhosted.org/packages/9d/c0/a3bb4cc13aced219dd18191ea66e874266bd8aa7b96744e495e1c733aa2d/jiter-0.11.0.tar.gz", hash = "sha256:1d9637eaf8c1d6a63d6562f2a6e5ab3af946c66037eb1b894e8fad75422266e4", size = 167094, upload-time = "2025-09-15T09:20:38.212Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/25/21/7dd1235a19e26979be6098e87e4cced2e061752f3a40a17bbce6dea7fae1/jiter-0.11.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3893ce831e1c0094a83eeaf56c635a167d6fa8cc14393cc14298fd6fdc2a2449", size = 309875, upload-time = "2025-09-15T09:18:48.41Z" }, { url = "https://files.pythonhosted.org/packages/71/f9/462b54708aa85b135733ccba70529dd68a18511bf367a87c5fd28676c841/jiter-0.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:25c625b9b61b5a8725267fdf867ef2e51b429687f6a4eef211f4612e95607179", size = 316505, upload-time = "2025-09-15T09:18:51.057Z" }, { url = "https://files.pythonhosted.org/packages/bd/40/14e2eeaac6a47bff27d213834795472355fd39769272eb53cb7aa83d5aa8/jiter-0.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd4ca85fb6a62cf72e1c7f5e34ddef1b660ce4ed0886ec94a1ef9777d35eaa1f", size = 337613, upload-time = "2025-09-15T09:18:52.358Z" }, { url = "https://files.pythonhosted.org/packages/d3/ed/a5f1f8419c92b150a7c7fb5ccba1fb1e192887ad713d780e70874f0ce996/jiter-0.11.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:572208127034725e79c28437b82414028c3562335f2b4f451d98136d0fc5f9cd", size = 361438, upload-time = "2025-09-15T09:18:54.637Z" }, { url = "https://files.pythonhosted.org/packages/dd/f5/70682c023dfcdd463a53faf5d30205a7d99c51d70d3e303c932d0936e5a2/jiter-0.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:494ba627c7f550ad3dabb21862864b8f2216098dc18ff62f37b37796f2f7c325", size = 486180, upload-time = "2025-09-15T09:18:56.158Z" }, { url = "https://files.pythonhosted.org/packages/7c/39/020d08cbab4eab48142ad88b837c41eb08a15c0767fdb7c0d3265128a44b/jiter-0.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b8da18a99f58bca3ecc2d2bba99cac000a924e115b6c4f0a2b98f752b6fbf39a", size = 376681, upload-time = "2025-09-15T09:18:57.553Z" }, { url = "https://files.pythonhosted.org/packages/52/10/b86733f6e594cf51dd142f37c602d8df87c554c5844958deaab0de30eb5d/jiter-0.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4ffd3b0fff3fabbb02cc09910c08144db6bb5697a98d227a074401e01ee63dd", size = 348685, upload-time = "2025-09-15T09:18:59.208Z" }, { url = "https://files.pythonhosted.org/packages/fb/ee/8861665e83a9e703aa5f65fddddb6225428e163e6b0baa95a7f9a8fb9aae/jiter-0.11.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8fe6530aa738a4f7d4e4702aa8f9581425d04036a5f9e25af65ebe1f708f23be", size = 385573, upload-time = "2025-09-15T09:19:00.593Z" }, { url = "https://files.pythonhosted.org/packages/25/74/05afec03600951f128293813b5a208c9ba1bf587c57a344c05a42a69e1b1/jiter-0.11.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e35d66681c133a03d7e974e7eedae89720fe8ca3bd09f01a4909b86a8adf31f5", size = 516669, upload-time = "2025-09-15T09:19:02.369Z" }, { url = "https://files.pythonhosted.org/packages/93/d1/2e5bfe147cfbc2a5eef7f73eb75dc5c6669da4fa10fc7937181d93af9495/jiter-0.11.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c59459beca2fbc9718b6f1acb7bfb59ebc3eb4294fa4d40e9cb679dafdcc6c60", size = 508767, upload-time = "2025-09-15T09:19:04.011Z" }, { url = "https://files.pythonhosted.org/packages/87/50/597f71307e10426b5c082fd05d38c615ddbdd08c3348d8502963307f0652/jiter-0.11.0-cp310-cp310-win32.whl", hash = "sha256:b7b0178417b0dcfc5f259edbc6db2b1f5896093ed9035ee7bab0f2be8854726d", size = 205476, upload-time = "2025-09-15T09:19:05.594Z" }, { url = "https://files.pythonhosted.org/packages/c7/86/1e5214b3272e311754da26e63edec93a183811d4fc2e0118addec365df8b/jiter-0.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:11df2bf99fb4754abddd7f5d940a48e51f9d11624d6313ca4314145fcad347f0", size = 204708, upload-time = "2025-09-15T09:19:06.955Z" }, { url = "https://files.pythonhosted.org/packages/38/55/a69fefeef09c2eaabae44b935a1aa81517e49639c0a0c25d861cb18cd7ac/jiter-0.11.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:cb5d9db02979c3f49071fce51a48f4b4e4cf574175fb2b11c7a535fa4867b222", size = 309503, upload-time = "2025-09-15T09:19:08.191Z" }, { url = "https://files.pythonhosted.org/packages/bd/d5/a6aba9e6551f32f9c127184f398208e4eddb96c59ac065c8a92056089d28/jiter-0.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1dc6a123f3471c4730db7ca8ba75f1bb3dcb6faeb8d46dd781083e7dee88b32d", size = 317688, upload-time = "2025-09-15T09:19:09.918Z" }, { url = "https://files.pythonhosted.org/packages/bb/f3/5e86f57c1883971cdc8535d0429c2787bf734840a231da30a3be12850562/jiter-0.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09858f8d230f031c7b8e557429102bf050eea29c77ad9c34c8fe253c5329acb7", size = 337418, upload-time = "2025-09-15T09:19:11.078Z" }, { url = "https://files.pythonhosted.org/packages/5e/4f/a71d8a24c2a70664970574a8e0b766663f5ef788f7fe1cc20ee0c016d488/jiter-0.11.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dbe2196c4a0ce760925a74ab4456bf644748ab0979762139626ad138f6dac72d", size = 361423, upload-time = "2025-09-15T09:19:13.286Z" }, { url = "https://files.pythonhosted.org/packages/8f/e5/b09076f4e7fd9471b91e16f9f3dc7330b161b738f3b39b2c37054a36e26a/jiter-0.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5beb56d22b63647bafd0b74979216fdee80c580c0c63410be8c11053860ffd09", size = 486367, upload-time = "2025-09-15T09:19:14.546Z" }, { url = "https://files.pythonhosted.org/packages/fb/f1/98cb3a36f5e62f80cd860f0179f948d9eab5a316d55d3e1bab98d9767af5/jiter-0.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97025d09ef549795d8dc720a824312cee3253c890ac73c621721ddfc75066789", size = 376335, upload-time = "2025-09-15T09:19:15.939Z" }, { url = "https://files.pythonhosted.org/packages/9f/d8/ec74886497ea393c29dbd7651ddecc1899e86404a6b1f84a3ddab0ab59fd/jiter-0.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d50880a6da65d8c23a2cf53c412847d9757e74cc9a3b95c5704a1d1a24667347", size = 348981, upload-time = "2025-09-15T09:19:17.568Z" }, { url = "https://files.pythonhosted.org/packages/24/93/d22ad7fa3b86ade66c86153ceea73094fc2af8b20c59cb7fceab9fea4704/jiter-0.11.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:452d80a1c86c095a242007bd9fc5d21b8a8442307193378f891cb8727e469648", size = 385797, upload-time = "2025-09-15T09:19:19.121Z" }, { url = "https://files.pythonhosted.org/packages/c8/bd/e25ff4a4df226e9b885f7cb01ee4b9dc74e3000e612d6f723860d71a1f34/jiter-0.11.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e84e58198d4894668eec2da660ffff60e0f3e60afa790ecc50cb12b0e02ca1d4", size = 516597, upload-time = "2025-09-15T09:19:20.301Z" }, { url = "https://files.pythonhosted.org/packages/be/fb/beda613db7d93ffa2fdd2683f90f2f5dce8daf4bc2d0d2829e7de35308c6/jiter-0.11.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:df64edcfc5dd5279a791eea52aa113d432c933119a025b0b5739f90d2e4e75f1", size = 508853, upload-time = "2025-09-15T09:19:22.075Z" }, { url = "https://files.pythonhosted.org/packages/20/64/c5b0d93490634e41e38e2a15de5d54fdbd2c9f64a19abb0f95305b63373c/jiter-0.11.0-cp311-cp311-win32.whl", hash = "sha256:144fc21337d21b1d048f7f44bf70881e1586401d405ed3a98c95a114a9994982", size = 205140, upload-time = "2025-09-15T09:19:23.351Z" }, { url = "https://files.pythonhosted.org/packages/a1/e6/c347c0e6f5796e97d4356b7e5ff0ce336498b7f4ef848fae621a56f1ccf3/jiter-0.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:b0f32e644d241293b892b1a6dd8f0b9cc029bfd94c97376b2681c36548aabab7", size = 204311, upload-time = "2025-09-15T09:19:24.591Z" }, { url = "https://files.pythonhosted.org/packages/ba/b5/3009b112b8f673e568ef79af9863d8309a15f0a8cdcc06ed6092051f377e/jiter-0.11.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:2fb7b377688cc3850bbe5c192a6bd493562a0bc50cbc8b047316428fbae00ada", size = 305510, upload-time = "2025-09-15T09:19:25.893Z" }, { url = "https://files.pythonhosted.org/packages/fe/82/15514244e03b9e71e086bbe2a6de3e4616b48f07d5f834200c873956fb8c/jiter-0.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a1b7cbe3f25bd0d8abb468ba4302a5d45617ee61b2a7a638f63fee1dc086be99", size = 316521, upload-time = "2025-09-15T09:19:27.525Z" }, { url = "https://files.pythonhosted.org/packages/92/94/7a2e905f40ad2d6d660e00b68d818f9e29fb87ffe82774f06191e93cbe4a/jiter-0.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c0a7f0ec81d5b7588c5cade1eb1925b91436ae6726dc2df2348524aeabad5de6", size = 338214, upload-time = "2025-09-15T09:19:28.727Z" }, { url = "https://files.pythonhosted.org/packages/a8/9c/5791ed5bdc76f12110158d3316a7a3ec0b1413d018b41c5ed399549d3ad5/jiter-0.11.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07630bb46ea2a6b9c6ed986c6e17e35b26148cce2c535454b26ee3f0e8dcaba1", size = 361280, upload-time = "2025-09-15T09:19:30.013Z" }, { url = "https://files.pythonhosted.org/packages/d4/7f/b7d82d77ff0d2cb06424141000176b53a9e6b16a1125525bb51ea4990c2e/jiter-0.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7764f27d28cd4a9cbc61704dfcd80c903ce3aad106a37902d3270cd6673d17f4", size = 487895, upload-time = "2025-09-15T09:19:31.424Z" }, { url = "https://files.pythonhosted.org/packages/42/44/10a1475d46f1fc1fd5cc2e82c58e7bca0ce5852208e0fa5df2f949353321/jiter-0.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d4a6c4a737d486f77f842aeb22807edecb4a9417e6700c7b981e16d34ba7c72", size = 378421, upload-time = "2025-09-15T09:19:32.746Z" }, { url = "https://files.pythonhosted.org/packages/9a/5f/0dc34563d8164d31d07bc09d141d3da08157a68dcd1f9b886fa4e917805b/jiter-0.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf408d2a0abd919b60de8c2e7bc5eeab72d4dafd18784152acc7c9adc3291591", size = 347932, upload-time = "2025-09-15T09:19:34.612Z" }, { url = "https://files.pythonhosted.org/packages/f7/de/b68f32a4fcb7b4a682b37c73a0e5dae32180140cd1caf11aef6ad40ddbf2/jiter-0.11.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cdef53eda7d18e799625023e1e250dbc18fbc275153039b873ec74d7e8883e09", size = 386959, upload-time = "2025-09-15T09:19:35.994Z" }, { url = "https://files.pythonhosted.org/packages/76/0a/c08c92e713b6e28972a846a81ce374883dac2f78ec6f39a0dad9f2339c3a/jiter-0.11.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:53933a38ef7b551dd9c7f1064f9d7bb235bb3168d0fa5f14f0798d1b7ea0d9c5", size = 517187, upload-time = "2025-09-15T09:19:37.426Z" }, { url = "https://files.pythonhosted.org/packages/89/b5/4a283bec43b15aad54fcae18d951f06a2ec3f78db5708d3b59a48e9c3fbd/jiter-0.11.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:11840d2324c9ab5162fc1abba23bc922124fedcff0d7b7f85fffa291e2f69206", size = 509461, upload-time = "2025-09-15T09:19:38.761Z" }, { url = "https://files.pythonhosted.org/packages/34/a5/f8bad793010534ea73c985caaeef8cc22dfb1fedb15220ecdf15c623c07a/jiter-0.11.0-cp312-cp312-win32.whl", hash = "sha256:4f01a744d24a5f2bb4a11657a1b27b61dc038ae2e674621a74020406e08f749b", size = 206664, upload-time = "2025-09-15T09:19:40.096Z" }, { url = "https://files.pythonhosted.org/packages/ed/42/5823ec2b1469395a160b4bf5f14326b4a098f3b6898fbd327366789fa5d3/jiter-0.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:29fff31190ab3a26de026da2f187814f4b9c6695361e20a9ac2123e4d4378a4c", size = 203520, upload-time = "2025-09-15T09:19:41.798Z" }, { url = "https://files.pythonhosted.org/packages/97/c4/d530e514d0f4f29b2b68145e7b389cbc7cac7f9c8c23df43b04d3d10fa3e/jiter-0.11.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:4441a91b80a80249f9a6452c14b2c24708f139f64de959943dfeaa6cb915e8eb", size = 305021, upload-time = "2025-09-15T09:19:43.523Z" }, { url = "https://files.pythonhosted.org/packages/7a/77/796a19c567c5734cbfc736a6f987affc0d5f240af8e12063c0fb93990ffa/jiter-0.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ff85fc6d2a431251ad82dbd1ea953affb5a60376b62e7d6809c5cd058bb39471", size = 314384, upload-time = "2025-09-15T09:19:44.849Z" }, { url = "https://files.pythonhosted.org/packages/14/9c/824334de0b037b91b6f3fa9fe5a191c83977c7ec4abe17795d3cb6d174cf/jiter-0.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5e86126d64706fd28dfc46f910d496923c6f95b395138c02d0e252947f452bd", size = 337389, upload-time = "2025-09-15T09:19:46.094Z" }, { url = "https://files.pythonhosted.org/packages/a2/95/ed4feab69e6cf9b2176ea29d4ef9d01a01db210a3a2c8a31a44ecdc68c38/jiter-0.11.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4ad8bd82165961867a10f52010590ce0b7a8c53da5ddd8bbb62fef68c181b921", size = 360519, upload-time = "2025-09-15T09:19:47.494Z" }, { url = "https://files.pythonhosted.org/packages/b5/0c/2ad00f38d3e583caba3909d95b7da1c3a7cd82c0aa81ff4317a8016fb581/jiter-0.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b42c2cd74273455ce439fd9528db0c6e84b5623cb74572305bdd9f2f2961d3df", size = 487198, upload-time = "2025-09-15T09:19:49.116Z" }, { url = "https://files.pythonhosted.org/packages/ea/8b/919b64cf3499b79bdfba6036da7b0cac5d62d5c75a28fb45bad7819e22f0/jiter-0.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f0062dab98172dd0599fcdbf90214d0dcde070b1ff38a00cc1b90e111f071982", size = 377835, upload-time = "2025-09-15T09:19:50.468Z" }, { url = "https://files.pythonhosted.org/packages/29/7f/8ebe15b6e0a8026b0d286c083b553779b4dd63db35b43a3f171b544de91d/jiter-0.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb948402821bc76d1f6ef0f9e19b816f9b09f8577844ba7140f0b6afe994bc64", size = 347655, upload-time = "2025-09-15T09:19:51.726Z" }, { url = "https://files.pythonhosted.org/packages/8e/64/332127cef7e94ac75719dda07b9a472af6158ba819088d87f17f3226a769/jiter-0.11.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:25a5b1110cca7329fd0daf5060faa1234be5c11e988948e4f1a1923b6a457fe1", size = 386135, upload-time = "2025-09-15T09:19:53.075Z" }, { url = "https://files.pythonhosted.org/packages/20/c8/557b63527442f84c14774159948262a9d4fabb0d61166f11568f22fc60d2/jiter-0.11.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:bf11807e802a214daf6c485037778843fadd3e2ec29377ae17e0706ec1a25758", size = 516063, upload-time = "2025-09-15T09:19:54.447Z" }, { url = "https://files.pythonhosted.org/packages/86/13/4164c819df4a43cdc8047f9a42880f0ceef5afeb22e8b9675c0528ebdccd/jiter-0.11.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:dbb57da40631c267861dd0090461222060960012d70fd6e4c799b0f62d0ba166", size = 508139, upload-time = "2025-09-15T09:19:55.764Z" }, { url = "https://files.pythonhosted.org/packages/fa/70/6e06929b401b331d41ddb4afb9f91cd1168218e3371972f0afa51c9f3c31/jiter-0.11.0-cp313-cp313-win32.whl", hash = "sha256:8e36924dad32c48d3c5e188d169e71dc6e84d6cb8dedefea089de5739d1d2f80", size = 206369, upload-time = "2025-09-15T09:19:57.048Z" }, { url = "https://files.pythonhosted.org/packages/f4/0d/8185b8e15de6dce24f6afae63380e16377dd75686d56007baa4f29723ea1/jiter-0.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:452d13e4fd59698408087235259cebe67d9d49173b4dacb3e8d35ce4acf385d6", size = 202538, upload-time = "2025-09-15T09:19:58.35Z" }, { url = "https://files.pythonhosted.org/packages/13/3a/d61707803260d59520721fa326babfae25e9573a88d8b7b9cb54c5423a59/jiter-0.11.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:089f9df9f69532d1339e83142438668f52c97cd22ee2d1195551c2b1a9e6cf33", size = 313737, upload-time = "2025-09-15T09:19:59.638Z" }, { url = "https://files.pythonhosted.org/packages/cd/cc/c9f0eec5d00f2a1da89f6bdfac12b8afdf8d5ad974184863c75060026457/jiter-0.11.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29ed1fe69a8c69bf0f2a962d8d706c7b89b50f1332cd6b9fbda014f60bd03a03", size = 346183, upload-time = "2025-09-15T09:20:01.442Z" }, { url = "https://files.pythonhosted.org/packages/a6/87/fc632776344e7aabbab05a95a0075476f418c5d29ab0f2eec672b7a1f0ac/jiter-0.11.0-cp313-cp313t-win_amd64.whl", hash = "sha256:a4d71d7ea6ea8786291423fe209acf6f8d398a0759d03e7f24094acb8ab686ba", size = 204225, upload-time = "2025-09-15T09:20:03.102Z" }, { url = "https://files.pythonhosted.org/packages/ee/3b/e7f45be7d3969bdf2e3cd4b816a7a1d272507cd0edd2d6dc4b07514f2d9a/jiter-0.11.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:9a6dff27eca70930bdbe4cbb7c1a4ba8526e13b63dc808c0670083d2d51a4a72", size = 304414, upload-time = "2025-09-15T09:20:04.357Z" }, { url = "https://files.pythonhosted.org/packages/06/32/13e8e0d152631fcc1907ceb4943711471be70496d14888ec6e92034e2caf/jiter-0.11.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:b1ae2a7593a62132c7d4c2abbee80bbbb94fdc6d157e2c6cc966250c564ef774", size = 314223, upload-time = "2025-09-15T09:20:05.631Z" }, { url = "https://files.pythonhosted.org/packages/0c/7e/abedd5b5a20ca083f778d96bba0d2366567fcecb0e6e34ff42640d5d7a18/jiter-0.11.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b13a431dba4b059e9e43019d3022346d009baf5066c24dcdea321a303cde9f0", size = 337306, upload-time = "2025-09-15T09:20:06.917Z" }, { url = "https://files.pythonhosted.org/packages/ac/e2/30d59bdc1204c86aa975ec72c48c482fee6633120ee9c3ab755e4dfefea8/jiter-0.11.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:af62e84ca3889604ebb645df3b0a3f3bcf6b92babbff642bd214616f57abb93a", size = 360565, upload-time = "2025-09-15T09:20:08.283Z" }, { url = "https://files.pythonhosted.org/packages/fe/88/567288e0d2ed9fa8f7a3b425fdaf2cb82b998633c24fe0d98f5417321aa8/jiter-0.11.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c6f3b32bb723246e6b351aecace52aba78adb8eeb4b2391630322dc30ff6c773", size = 486465, upload-time = "2025-09-15T09:20:09.613Z" }, { url = "https://files.pythonhosted.org/packages/18/6e/7b72d09273214cadd15970e91dd5ed9634bee605176107db21e1e4205eb1/jiter-0.11.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:adcab442f4a099a358a7f562eaa54ed6456fb866e922c6545a717be51dbed7d7", size = 377581, upload-time = "2025-09-15T09:20:10.884Z" }, { url = "https://files.pythonhosted.org/packages/58/52/4db456319f9d14deed325f70102577492e9d7e87cf7097bda9769a1fcacb/jiter-0.11.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9967c2ab338ee2b2c0102fd379ec2693c496abf71ffd47e4d791d1f593b68e2", size = 347102, upload-time = "2025-09-15T09:20:12.175Z" }, { url = "https://files.pythonhosted.org/packages/ce/b4/433d5703c38b26083aec7a733eb5be96f9c6085d0e270a87ca6482cbf049/jiter-0.11.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e7d0bed3b187af8b47a981d9742ddfc1d9b252a7235471ad6078e7e4e5fe75c2", size = 386477, upload-time = "2025-09-15T09:20:13.428Z" }, { url = "https://files.pythonhosted.org/packages/c8/7a/a60bfd9c55b55b07c5c441c5085f06420b6d493ce9db28d069cc5b45d9f3/jiter-0.11.0-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:f6fe0283e903ebc55f1a6cc569b8c1f3bf4abd026fed85e3ff8598a9e6f982f0", size = 516004, upload-time = "2025-09-15T09:20:14.848Z" }, { url = "https://files.pythonhosted.org/packages/2e/46/f8363e5ecc179b4ed0ca6cb0a6d3bfc266078578c71ff30642ea2ce2f203/jiter-0.11.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:4ee5821e3d66606b29ae5b497230b304f1376f38137d69e35f8d2bd5f310ff73", size = 507855, upload-time = "2025-09-15T09:20:16.176Z" }, { url = "https://files.pythonhosted.org/packages/90/33/396083357d51d7ff0f9805852c288af47480d30dd31d8abc74909b020761/jiter-0.11.0-cp314-cp314-win32.whl", hash = "sha256:c2d13ba7567ca8799f17c76ed56b1d49be30df996eb7fa33e46b62800562a5e2", size = 205802, upload-time = "2025-09-15T09:20:17.661Z" }, { url = "https://files.pythonhosted.org/packages/e7/ab/eb06ca556b2551d41de7d03bf2ee24285fa3d0c58c5f8d95c64c9c3281b1/jiter-0.11.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:fb4790497369d134a07fc763cc88888c46f734abdd66f9fdf7865038bf3a8f40", size = 313405, upload-time = "2025-09-15T09:20:18.918Z" }, { url = "https://files.pythonhosted.org/packages/af/22/7ab7b4ec3a1c1f03aef376af11d23b05abcca3fb31fbca1e7557053b1ba2/jiter-0.11.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e2bbf24f16ba5ad4441a9845e40e4ea0cb9eed00e76ba94050664ef53ef4406", size = 347102, upload-time = "2025-09-15T09:20:20.16Z" }, { url = "https://files.pythonhosted.org/packages/e5/d9/51cf35d92bea21f2051da8ca2328831589e67e2bf971e85b1a6e6c0d2030/jiter-0.11.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:719891c2fb7628a41adff4f2f54c19380a27e6fdfdb743c24680ef1a54c67bd0", size = 312764, upload-time = "2025-09-15T09:20:21.378Z" }, { url = "https://files.pythonhosted.org/packages/da/48/eae309ce5c180faa1bb45e378a503717da22ceb2b0488f78e548f97c2b6b/jiter-0.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:df7f1927cbdf34cb91262a5418ca06920fd42f1cf733936d863aeb29b45a14ef", size = 305861, upload-time = "2025-09-15T09:20:22.603Z" }, { url = "https://files.pythonhosted.org/packages/83/4f/13b80e18b0331f0fecc09cb2f09f722530b9a395006941b01491fe58baea/jiter-0.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e71ae6d969d0c9bab336c5e9e2fabad31e74d823f19e3604eaf96d9a97f463df", size = 339507, upload-time = "2025-09-15T09:20:23.857Z" }, { url = "https://files.pythonhosted.org/packages/97/6d/c2fd1512873d3f23d24537e97765e7090a00de466516aa442b994b064918/jiter-0.11.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5661469a7b2be25ade3a4bb6c21ffd1e142e13351a0759f264dfdd3ad99af1ab", size = 363751, upload-time = "2025-09-15T09:20:25.12Z" }, { url = "https://files.pythonhosted.org/packages/b0/99/48d156c742e75d33b9c8be44b1142d233823be491acdb1009629e4109e6a/jiter-0.11.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:76c15ef0d3d02f8b389066fa4c410a0b89e9cc6468a1f0674c5925d2f3c3e890", size = 488591, upload-time = "2025-09-15T09:20:26.397Z" }, { url = "https://files.pythonhosted.org/packages/ba/fd/214452149f63847b791b1f6e9558f59e94674c47418c03e9787236ac8656/jiter-0.11.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:63782a1350917a27817030716566ed3d5b3c731500fd42d483cbd7094e2c5b25", size = 378906, upload-time = "2025-09-15T09:20:27.637Z" }, { url = "https://files.pythonhosted.org/packages/de/91/25e38fbbfc17111d7b70b24290a41d611cc2a27fa6cd0ed84ddae38ec3e6/jiter-0.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a7092b699646a1ddc03a7b112622d9c066172627c7382659befb0d2996f1659", size = 350288, upload-time = "2025-09-15T09:20:28.951Z" }, { url = "https://files.pythonhosted.org/packages/b5/d8/d6d2eefa9f0ff6ac6b725f5164a94f15bb4dee68584b5054043d735803da/jiter-0.11.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f637b8e818f6d75540f350a6011ce21252573c0998ea1b4365ee54b7672c23c5", size = 388442, upload-time = "2025-09-15T09:20:30.223Z" }, { url = "https://files.pythonhosted.org/packages/ed/e4/cd7e27852de498d441a575a147ac7a15cf66768ae2cde8c43ea5b464c827/jiter-0.11.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a624d87719e1b5d09c15286eaee7e1532a40c692a096ea7ca791121365f548c1", size = 518273, upload-time = "2025-09-15T09:20:31.569Z" }, { url = "https://files.pythonhosted.org/packages/77/a2/6681a9a503141752b33c92c58512ed8da13849ed3dbf88a3f8aba9bfb255/jiter-0.11.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9d0146d8d9b3995821bb586fc8256636258947c2f39da5bab709f3a28fb1a0b", size = 510254, upload-time = "2025-09-15T09:20:32.889Z" }, { url = "https://files.pythonhosted.org/packages/38/32/df1a06f397074da35cf8fe79ec07da203358a2912b2a6349a0d4a88a1e0a/jiter-0.11.0-cp39-cp39-win32.whl", hash = "sha256:d067655a7cf0831eb8ec3e39cbd752995e9b69a2206df3535b3a067fac23b032", size = 207076, upload-time = "2025-09-15T09:20:34.196Z" }, { url = "https://files.pythonhosted.org/packages/1d/91/11bc61fa76fd6197f5baa8576614852ee8586a16c2f25085edc6b47a369d/jiter-0.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:f05d03775a11aaf132c447436983169958439f1219069abf24662a672851f94e", size = 206077, upload-time = "2025-09-15T09:20:35.598Z" }, { url = "https://files.pythonhosted.org/packages/70/f3/ce100253c80063a7b8b406e1d1562657fd4b9b4e1b562db40e68645342fb/jiter-0.11.0-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:902b43386c04739229076bd1c4c69de5d115553d982ab442a8ae82947c72ede7", size = 336380, upload-time = "2025-09-15T09:20:36.867Z" }, ] [[package]] name = "jmespath" version = "1.0.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/00/2a/e867e8531cf3e36b41201936b7fa7ba7b5702dbef42922193f05c8976cd6/jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe", size = 25843, upload-time = "2022-06-17T18:00:12.224Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/31/b4/b9b800c45527aadd64d5b442f9b932b00648617eb5d63d2c7a6587b7cafc/jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980", size = 20256, upload-time = "2022-06-17T18:00:10.251Z" }, ] [[package]] name = "markdown-it-py" version = "3.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mdurl" }, ] 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 = "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.1.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/d6/be/504b89a5e9ca731cd47487e91c469064f8ae5af93b7259758dcfc2b9c848/multidict-6.1.0.tar.gz", hash = "sha256:22ae2ebf9b0c69d206c003e2f6a914ea33f0a932d4aa16f236afc049d9958f4a", size = 64002, upload-time = "2024-09-09T23:49:38.163Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/29/68/259dee7fd14cf56a17c554125e534f6274c2860159692a414d0b402b9a6d/multidict-6.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3380252550e372e8511d49481bd836264c009adb826b23fefcc5dd3c69692f60", size = 48628, upload-time = "2024-09-09T23:47:18.278Z" }, { url = "https://files.pythonhosted.org/packages/50/79/53ba256069fe5386a4a9e80d4e12857ced9de295baf3e20c68cdda746e04/multidict-6.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:99f826cbf970077383d7de805c0681799491cb939c25450b9b5b3ced03ca99f1", size = 29327, upload-time = "2024-09-09T23:47:20.224Z" }, { url = "https://files.pythonhosted.org/packages/ff/10/71f1379b05b196dae749b5ac062e87273e3f11634f447ebac12a571d90ae/multidict-6.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a114d03b938376557927ab23f1e950827c3b893ccb94b62fd95d430fd0e5cf53", size = 29689, upload-time = "2024-09-09T23:47:21.667Z" }, { url = "https://files.pythonhosted.org/packages/71/45/70bac4f87438ded36ad4793793c0095de6572d433d98575a5752629ef549/multidict-6.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1c416351ee6271b2f49b56ad7f308072f6f44b37118d69c2cad94f3fa8a40d5", size = 126639, upload-time = "2024-09-09T23:47:23.333Z" }, { url = "https://files.pythonhosted.org/packages/80/cf/17f35b3b9509b4959303c05379c4bfb0d7dd05c3306039fc79cf035bbac0/multidict-6.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6b5d83030255983181005e6cfbac1617ce9746b219bc2aad52201ad121226581", size = 134315, upload-time = "2024-09-09T23:47:24.99Z" }, { url = "https://files.pythonhosted.org/packages/ef/1f/652d70ab5effb33c031510a3503d4d6efc5ec93153562f1ee0acdc895a57/multidict-6.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3e97b5e938051226dc025ec80980c285b053ffb1e25a3db2a3aa3bc046bf7f56", size = 129471, upload-time = "2024-09-09T23:47:26.305Z" }, { url = "https://files.pythonhosted.org/packages/a6/64/2dd6c4c681688c0165dea3975a6a4eab4944ea30f35000f8b8af1df3148c/multidict-6.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d618649d4e70ac6efcbba75be98b26ef5078faad23592f9b51ca492953012429", size = 124585, upload-time = "2024-09-09T23:47:27.958Z" }, { url = "https://files.pythonhosted.org/packages/87/56/e6ee5459894c7e554b57ba88f7257dc3c3d2d379cb15baaa1e265b8c6165/multidict-6.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10524ebd769727ac77ef2278390fb0068d83f3acb7773792a5080f2b0abf7748", size = 116957, upload-time = "2024-09-09T23:47:29.376Z" }, { url = "https://files.pythonhosted.org/packages/36/9e/616ce5e8d375c24b84f14fc263c7ef1d8d5e8ef529dbc0f1df8ce71bb5b8/multidict-6.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ff3827aef427c89a25cc96ded1759271a93603aba9fb977a6d264648ebf989db", size = 128609, upload-time = "2024-09-09T23:47:31.038Z" }, { url = "https://files.pythonhosted.org/packages/8c/4f/4783e48a38495d000f2124020dc96bacc806a4340345211b1ab6175a6cb4/multidict-6.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:06809f4f0f7ab7ea2cabf9caca7d79c22c0758b58a71f9d32943ae13c7ace056", size = 123016, upload-time = "2024-09-09T23:47:32.47Z" }, { url = "https://files.pythonhosted.org/packages/3e/b3/4950551ab8fc39862ba5e9907dc821f896aa829b4524b4deefd3e12945ab/multidict-6.1.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:f179dee3b863ab1c59580ff60f9d99f632f34ccb38bf67a33ec6b3ecadd0fd76", size = 133542, upload-time = "2024-09-09T23:47:34.103Z" }, { url = "https://files.pythonhosted.org/packages/96/4d/f0ce6ac9914168a2a71df117935bb1f1781916acdecbb43285e225b484b8/multidict-6.1.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:aaed8b0562be4a0876ee3b6946f6869b7bcdb571a5d1496683505944e268b160", size = 130163, upload-time = "2024-09-09T23:47:35.716Z" }, { url = "https://files.pythonhosted.org/packages/be/72/17c9f67e7542a49dd252c5ae50248607dfb780bcc03035907dafefb067e3/multidict-6.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3c8b88a2ccf5493b6c8da9076fb151ba106960a2df90c2633f342f120751a9e7", size = 126832, upload-time = "2024-09-09T23:47:37.116Z" }, { url = "https://files.pythonhosted.org/packages/71/9f/72d719e248cbd755c8736c6d14780533a1606ffb3fbb0fbd77da9f0372da/multidict-6.1.0-cp310-cp310-win32.whl", hash = "sha256:4a9cb68166a34117d6646c0023c7b759bf197bee5ad4272f420a0141d7eb03a0", size = 26402, upload-time = "2024-09-09T23:47:38.863Z" }, { url = "https://files.pythonhosted.org/packages/04/5a/d88cd5d00a184e1ddffc82aa2e6e915164a6d2641ed3606e766b5d2f275a/multidict-6.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:20b9b5fbe0b88d0bdef2012ef7dee867f874b72528cf1d08f1d59b0e3850129d", size = 28800, upload-time = "2024-09-09T23:47:40.056Z" }, { url = "https://files.pythonhosted.org/packages/93/13/df3505a46d0cd08428e4c8169a196131d1b0c4b515c3649829258843dde6/multidict-6.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3efe2c2cb5763f2f1b275ad2bf7a287d3f7ebbef35648a9726e3b69284a4f3d6", size = 48570, upload-time = "2024-09-09T23:47:41.36Z" }, { url = "https://files.pythonhosted.org/packages/f0/e1/a215908bfae1343cdb72f805366592bdd60487b4232d039c437fe8f5013d/multidict-6.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7053d3b0353a8b9de430a4f4b4268ac9a4fb3481af37dfe49825bf45ca24156", size = 29316, upload-time = "2024-09-09T23:47:42.612Z" }, { url = "https://files.pythonhosted.org/packages/70/0f/6dc70ddf5d442702ed74f298d69977f904960b82368532c88e854b79f72b/multidict-6.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:27e5fc84ccef8dfaabb09d82b7d179c7cf1a3fbc8a966f8274fcb4ab2eb4cadb", size = 29640, upload-time = "2024-09-09T23:47:44.028Z" }, { url = "https://files.pythonhosted.org/packages/d8/6d/9c87b73a13d1cdea30b321ef4b3824449866bd7f7127eceed066ccb9b9ff/multidict-6.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e2b90b43e696f25c62656389d32236e049568b39320e2735d51f08fd362761b", size = 131067, upload-time = "2024-09-09T23:47:45.617Z" }, { url = "https://files.pythonhosted.org/packages/cc/1e/1b34154fef373371fd6c65125b3d42ff5f56c7ccc6bfff91b9b3c60ae9e0/multidict-6.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d83a047959d38a7ff552ff94be767b7fd79b831ad1cd9920662db05fec24fe72", size = 138507, upload-time = "2024-09-09T23:47:47.429Z" }, { url = "https://files.pythonhosted.org/packages/fb/e0/0bc6b2bac6e461822b5f575eae85da6aae76d0e2a79b6665d6206b8e2e48/multidict-6.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1a9dd711d0877a1ece3d2e4fea11a8e75741ca21954c919406b44e7cf971304", size = 133905, upload-time = "2024-09-09T23:47:48.878Z" }, { url = "https://files.pythonhosted.org/packages/ba/af/73d13b918071ff9b2205fcf773d316e0f8fefb4ec65354bbcf0b10908cc6/multidict-6.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec2abea24d98246b94913b76a125e855eb5c434f7c46546046372fe60f666351", size = 129004, upload-time = "2024-09-09T23:47:50.124Z" }, { url = "https://files.pythonhosted.org/packages/74/21/23960627b00ed39643302d81bcda44c9444ebcdc04ee5bedd0757513f259/multidict-6.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4867cafcbc6585e4b678876c489b9273b13e9fff9f6d6d66add5e15d11d926cb", size = 121308, upload-time = "2024-09-09T23:47:51.97Z" }, { url = "https://files.pythonhosted.org/packages/8b/5c/cf282263ffce4a596ed0bb2aa1a1dddfe1996d6a62d08842a8d4b33dca13/multidict-6.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5b48204e8d955c47c55b72779802b219a39acc3ee3d0116d5080c388970b76e3", size = 132608, upload-time = "2024-09-09T23:47:53.201Z" }, { url = "https://files.pythonhosted.org/packages/d7/3e/97e778c041c72063f42b290888daff008d3ab1427f5b09b714f5a8eff294/multidict-6.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:d8fff389528cad1618fb4b26b95550327495462cd745d879a8c7c2115248e399", size = 127029, upload-time = "2024-09-09T23:47:54.435Z" }, { url = "https://files.pythonhosted.org/packages/47/ac/3efb7bfe2f3aefcf8d103e9a7162572f01936155ab2f7ebcc7c255a23212/multidict-6.1.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:a7a9541cd308eed5e30318430a9c74d2132e9a8cb46b901326272d780bf2d423", size = 137594, upload-time = "2024-09-09T23:47:55.659Z" }, { url = "https://files.pythonhosted.org/packages/42/9b/6c6e9e8dc4f915fc90a9b7798c44a30773dea2995fdcb619870e705afe2b/multidict-6.1.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:da1758c76f50c39a2efd5e9859ce7d776317eb1dd34317c8152ac9251fc574a3", size = 134556, upload-time = "2024-09-09T23:47:56.98Z" }, { url = "https://files.pythonhosted.org/packages/1d/10/8e881743b26aaf718379a14ac58572a240e8293a1c9d68e1418fb11c0f90/multidict-6.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c943a53e9186688b45b323602298ab727d8865d8c9ee0b17f8d62d14b56f0753", size = 130993, upload-time = "2024-09-09T23:47:58.163Z" }, { url = "https://files.pythonhosted.org/packages/45/84/3eb91b4b557442802d058a7579e864b329968c8d0ea57d907e7023c677f2/multidict-6.1.0-cp311-cp311-win32.whl", hash = "sha256:90f8717cb649eea3504091e640a1b8568faad18bd4b9fcd692853a04475a4b80", size = 26405, upload-time = "2024-09-09T23:47:59.391Z" }, { url = "https://files.pythonhosted.org/packages/9f/0b/ad879847ecbf6d27e90a6eabb7eff6b62c129eefe617ea45eae7c1f0aead/multidict-6.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:82176036e65644a6cc5bd619f65f6f19781e8ec2e5330f51aa9ada7504cc1926", size = 28795, upload-time = "2024-09-09T23:48:00.359Z" }, { url = "https://files.pythonhosted.org/packages/fd/16/92057c74ba3b96d5e211b553895cd6dc7cc4d1e43d9ab8fafc727681ef71/multidict-6.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b04772ed465fa3cc947db808fa306d79b43e896beb677a56fb2347ca1a49c1fa", size = 48713, upload-time = "2024-09-09T23:48:01.893Z" }, { url = "https://files.pythonhosted.org/packages/94/3d/37d1b8893ae79716179540b89fc6a0ee56b4a65fcc0d63535c6f5d96f217/multidict-6.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6180c0ae073bddeb5a97a38c03f30c233e0a4d39cd86166251617d1bbd0af436", size = 29516, upload-time = "2024-09-09T23:48:03.463Z" }, { url = "https://files.pythonhosted.org/packages/a2/12/adb6b3200c363062f805275b4c1e656be2b3681aada66c80129932ff0bae/multidict-6.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:071120490b47aa997cca00666923a83f02c7fbb44f71cf7f136df753f7fa8761", size = 29557, upload-time = "2024-09-09T23:48:04.905Z" }, { url = "https://files.pythonhosted.org/packages/47/e9/604bb05e6e5bce1e6a5cf80a474e0f072e80d8ac105f1b994a53e0b28c42/multidict-6.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50b3a2710631848991d0bf7de077502e8994c804bb805aeb2925a981de58ec2e", size = 130170, upload-time = "2024-09-09T23:48:06.862Z" }, { url = "https://files.pythonhosted.org/packages/7e/13/9efa50801785eccbf7086b3c83b71a4fb501a4d43549c2f2f80b8787d69f/multidict-6.1.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b58c621844d55e71c1b7f7c498ce5aa6985d743a1a59034c57a905b3f153c1ef", size = 134836, upload-time = "2024-09-09T23:48:08.537Z" }, { url = "https://files.pythonhosted.org/packages/bf/0f/93808b765192780d117814a6dfcc2e75de6dcc610009ad408b8814dca3ba/multidict-6.1.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55b6d90641869892caa9ca42ff913f7ff1c5ece06474fbd32fb2cf6834726c95", size = 133475, upload-time = "2024-09-09T23:48:09.865Z" }, { url = "https://files.pythonhosted.org/packages/d3/c8/529101d7176fe7dfe1d99604e48d69c5dfdcadb4f06561f465c8ef12b4df/multidict-6.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b820514bfc0b98a30e3d85462084779900347e4d49267f747ff54060cc33925", size = 131049, upload-time = "2024-09-09T23:48:11.115Z" }, { url = "https://files.pythonhosted.org/packages/ca/0c/fc85b439014d5a58063e19c3a158a889deec399d47b5269a0f3b6a2e28bc/multidict-6.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10a9b09aba0c5b48c53761b7c720aaaf7cf236d5fe394cd399c7ba662d5f9966", size = 120370, upload-time = "2024-09-09T23:48:12.78Z" }, { url = "https://files.pythonhosted.org/packages/db/46/d4416eb20176492d2258fbd47b4abe729ff3b6e9c829ea4236f93c865089/multidict-6.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1e16bf3e5fc9f44632affb159d30a437bfe286ce9e02754759be5536b169b305", size = 125178, upload-time = "2024-09-09T23:48:14.295Z" }, { url = "https://files.pythonhosted.org/packages/5b/46/73697ad7ec521df7de5531a32780bbfd908ded0643cbe457f981a701457c/multidict-6.1.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:76f364861c3bfc98cbbcbd402d83454ed9e01a5224bb3a28bf70002a230f73e2", size = 119567, upload-time = "2024-09-09T23:48:16.284Z" }, { url = "https://files.pythonhosted.org/packages/cd/ed/51f060e2cb0e7635329fa6ff930aa5cffa17f4c7f5c6c3ddc3500708e2f2/multidict-6.1.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:820c661588bd01a0aa62a1283f20d2be4281b086f80dad9e955e690c75fb54a2", size = 129822, upload-time = "2024-09-09T23:48:17.835Z" }, { url = "https://files.pythonhosted.org/packages/df/9e/ee7d1954b1331da3eddea0c4e08d9142da5f14b1321c7301f5014f49d492/multidict-6.1.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:0e5f362e895bc5b9e67fe6e4ded2492d8124bdf817827f33c5b46c2fe3ffaca6", size = 128656, upload-time = "2024-09-09T23:48:19.576Z" }, { url = "https://files.pythonhosted.org/packages/77/00/8538f11e3356b5d95fa4b024aa566cde7a38aa7a5f08f4912b32a037c5dc/multidict-6.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3ec660d19bbc671e3a6443325f07263be452c453ac9e512f5eb935e7d4ac28b3", size = 125360, upload-time = "2024-09-09T23:48:20.957Z" }, { url = "https://files.pythonhosted.org/packages/be/05/5d334c1f2462d43fec2363cd00b1c44c93a78c3925d952e9a71caf662e96/multidict-6.1.0-cp312-cp312-win32.whl", hash = "sha256:58130ecf8f7b8112cdb841486404f1282b9c86ccb30d3519faf301b2e5659133", size = 26382, upload-time = "2024-09-09T23:48:22.351Z" }, { url = "https://files.pythonhosted.org/packages/a3/bf/f332a13486b1ed0496d624bcc7e8357bb8053823e8cd4b9a18edc1d97e73/multidict-6.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:188215fc0aafb8e03341995e7c4797860181562380f81ed0a87ff455b70bf1f1", size = 28529, upload-time = "2024-09-09T23:48:23.478Z" }, { url = "https://files.pythonhosted.org/packages/22/67/1c7c0f39fe069aa4e5d794f323be24bf4d33d62d2a348acdb7991f8f30db/multidict-6.1.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:d569388c381b24671589335a3be6e1d45546c2988c2ebe30fdcada8457a31008", size = 48771, upload-time = "2024-09-09T23:48:24.594Z" }, { url = "https://files.pythonhosted.org/packages/3c/25/c186ee7b212bdf0df2519eacfb1981a017bda34392c67542c274651daf23/multidict-6.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:052e10d2d37810b99cc170b785945421141bf7bb7d2f8799d431e7db229c385f", size = 29533, upload-time = "2024-09-09T23:48:26.187Z" }, { url = "https://files.pythonhosted.org/packages/67/5e/04575fd837e0958e324ca035b339cea174554f6f641d3fb2b4f2e7ff44a2/multidict-6.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f90c822a402cb865e396a504f9fc8173ef34212a342d92e362ca498cad308e28", size = 29595, upload-time = "2024-09-09T23:48:27.305Z" }, { url = "https://files.pythonhosted.org/packages/d3/b2/e56388f86663810c07cfe4a3c3d87227f3811eeb2d08450b9e5d19d78876/multidict-6.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b225d95519a5bf73860323e633a664b0d85ad3d5bede6d30d95b35d4dfe8805b", size = 130094, upload-time = "2024-09-09T23:48:28.544Z" }, { url = "https://files.pythonhosted.org/packages/6c/ee/30ae9b4186a644d284543d55d491fbd4239b015d36b23fea43b4c94f7052/multidict-6.1.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:23bfd518810af7de1116313ebd9092cb9aa629beb12f6ed631ad53356ed6b86c", size = 134876, upload-time = "2024-09-09T23:48:30.098Z" }, { url = "https://files.pythonhosted.org/packages/84/c7/70461c13ba8ce3c779503c70ec9d0345ae84de04521c1f45a04d5f48943d/multidict-6.1.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c09fcfdccdd0b57867577b719c69e347a436b86cd83747f179dbf0cc0d4c1f3", size = 133500, upload-time = "2024-09-09T23:48:31.793Z" }, { url = "https://files.pythonhosted.org/packages/4a/9f/002af221253f10f99959561123fae676148dd730e2daa2cd053846a58507/multidict-6.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf6bea52ec97e95560af5ae576bdac3aa3aae0b6758c6efa115236d9e07dae44", size = 131099, upload-time = "2024-09-09T23:48:33.193Z" }, { url = "https://files.pythonhosted.org/packages/82/42/d1c7a7301d52af79d88548a97e297f9d99c961ad76bbe6f67442bb77f097/multidict-6.1.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57feec87371dbb3520da6192213c7d6fc892d5589a93db548331954de8248fd2", size = 120403, upload-time = "2024-09-09T23:48:34.942Z" }, { url = "https://files.pythonhosted.org/packages/68/f3/471985c2c7ac707547553e8f37cff5158030d36bdec4414cb825fbaa5327/multidict-6.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0c3f390dc53279cbc8ba976e5f8035eab997829066756d811616b652b00a23a3", size = 125348, upload-time = "2024-09-09T23:48:36.222Z" }, { url = "https://files.pythonhosted.org/packages/67/2c/e6df05c77e0e433c214ec1d21ddd203d9a4770a1f2866a8ca40a545869a0/multidict-6.1.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:59bfeae4b25ec05b34f1956eaa1cb38032282cd4dfabc5056d0a1ec4d696d3aa", size = 119673, upload-time = "2024-09-09T23:48:37.588Z" }, { url = "https://files.pythonhosted.org/packages/c5/cd/bc8608fff06239c9fb333f9db7743a1b2eafe98c2666c9a196e867a3a0a4/multidict-6.1.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b2f59caeaf7632cc633b5cf6fc449372b83bbdf0da4ae04d5be36118e46cc0aa", size = 129927, upload-time = "2024-09-09T23:48:39.128Z" }, { url = "https://files.pythonhosted.org/packages/44/8e/281b69b7bc84fc963a44dc6e0bbcc7150e517b91df368a27834299a526ac/multidict-6.1.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:37bb93b2178e02b7b618893990941900fd25b6b9ac0fa49931a40aecdf083fe4", size = 128711, upload-time = "2024-09-09T23:48:40.55Z" }, { url = "https://files.pythonhosted.org/packages/12/a4/63e7cd38ed29dd9f1881d5119f272c898ca92536cdb53ffe0843197f6c85/multidict-6.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4e9f48f58c2c523d5a06faea47866cd35b32655c46b443f163d08c6d0ddb17d6", size = 125519, upload-time = "2024-09-09T23:48:42.446Z" }, { url = "https://files.pythonhosted.org/packages/38/e0/4f5855037a72cd8a7a2f60a3952d9aa45feedb37ae7831642102604e8a37/multidict-6.1.0-cp313-cp313-win32.whl", hash = "sha256:3a37ffb35399029b45c6cc33640a92bef403c9fd388acce75cdc88f58bd19a81", size = 26426, upload-time = "2024-09-09T23:48:43.936Z" }, { url = "https://files.pythonhosted.org/packages/7e/a5/17ee3a4db1e310b7405f5d25834460073a8ccd86198ce044dfaf69eac073/multidict-6.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:e9aa71e15d9d9beaad2c6b9319edcdc0a49a43ef5c0a4c8265ca9ee7d6c67774", size = 28531, upload-time = "2024-09-09T23:48:45.122Z" }, { url = "https://files.pythonhosted.org/packages/3e/6a/af41f3aaf5f00fd86cc7d470a2f5b25299b0c84691163b8757f4a1a205f2/multidict-6.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:db7457bac39421addd0c8449933ac32d8042aae84a14911a757ae6ca3eef1392", size = 48597, upload-time = "2024-09-09T23:48:46.391Z" }, { url = "https://files.pythonhosted.org/packages/d9/d6/3d4082760ed11b05734f8bf32a0615b99e7d9d2b3730ad698a4d7377c00a/multidict-6.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d094ddec350a2fb899fec68d8353c78233debde9b7d8b4beeafa70825f1c281a", size = 29338, upload-time = "2024-09-09T23:48:47.891Z" }, { url = "https://files.pythonhosted.org/packages/9d/7f/5d1ce7f47d44393d429922910afbe88fcd29ee3069babbb47507a4c3a7ea/multidict-6.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5845c1fd4866bb5dd3125d89b90e57ed3138241540897de748cdf19de8a2fca2", size = 29562, upload-time = "2024-09-09T23:48:49.254Z" }, { url = "https://files.pythonhosted.org/packages/ce/ec/c425257671af9308a9b626e2e21f7f43841616e4551de94eb3c92aca75b2/multidict-6.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9079dfc6a70abe341f521f78405b8949f96db48da98aeb43f9907f342f627cdc", size = 130980, upload-time = "2024-09-09T23:48:50.606Z" }, { url = "https://files.pythonhosted.org/packages/d8/d7/d4220ad2633a89b314593e9b85b5bc9287a7c563c7f9108a4a68d9da5374/multidict-6.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3914f5aaa0f36d5d60e8ece6a308ee1c9784cd75ec8151062614657a114c4478", size = 136694, upload-time = "2024-09-09T23:48:52.042Z" }, { url = "https://files.pythonhosted.org/packages/a1/2a/13e554db5830c8d40185a2e22aa8325516a5de9634c3fb2caf3886a829b3/multidict-6.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c08be4f460903e5a9d0f76818db3250f12e9c344e79314d1d570fc69d7f4eae4", size = 131616, upload-time = "2024-09-09T23:48:54.283Z" }, { url = "https://files.pythonhosted.org/packages/2e/a9/83692e37d8152f104333132105b67100aabfb2e96a87f6bed67f566035a7/multidict-6.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d093be959277cb7dee84b801eb1af388b6ad3ca6a6b6bf1ed7585895789d027d", size = 129664, upload-time = "2024-09-09T23:48:55.785Z" }, { url = "https://files.pythonhosted.org/packages/cc/1c/1718cd518fb9da7e8890d9d1611c1af0ea5e60f68ff415d026e38401ed36/multidict-6.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3702ea6872c5a2a4eeefa6ffd36b042e9773f05b1f37ae3ef7264b1163c2dcf6", size = 121855, upload-time = "2024-09-09T23:48:57.333Z" }, { url = "https://files.pythonhosted.org/packages/2b/92/f6ed67514b0e3894198f0eb42dcde22f0851ea35f4561a1e4acf36c7b1be/multidict-6.1.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:2090f6a85cafc5b2db085124d752757c9d251548cedabe9bd31afe6363e0aff2", size = 127928, upload-time = "2024-09-09T23:48:58.778Z" }, { url = "https://files.pythonhosted.org/packages/f7/30/c66954115a4dc4dc3c84e02c8ae11bb35a43d79ef93122c3c3a40c4d459b/multidict-6.1.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:f67f217af4b1ff66c68a87318012de788dd95fcfeb24cc889011f4e1c7454dfd", size = 122793, upload-time = "2024-09-09T23:49:00.244Z" }, { url = "https://files.pythonhosted.org/packages/62/c9/d386d01b43871e8e1631eb7b3695f6af071b7ae1ab716caf371100f0eb24/multidict-6.1.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:189f652a87e876098bbc67b4da1049afb5f5dfbaa310dd67c594b01c10388db6", size = 132762, upload-time = "2024-09-09T23:49:02.188Z" }, { url = "https://files.pythonhosted.org/packages/69/ff/f70cb0a2f7a358acf48e32139ce3a150ff18c961ee9c714cc8c0dc7e3584/multidict-6.1.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:6bb5992037f7a9eff7991ebe4273ea7f51f1c1c511e6a2ce511d0e7bdb754492", size = 127872, upload-time = "2024-09-09T23:49:04.389Z" }, { url = "https://files.pythonhosted.org/packages/89/5b/abea7db3ba4cd07752a9b560f9275a11787cd13f86849b5d99c1ceea921d/multidict-6.1.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f4c2b9e770c4e393876e35a7046879d195cd123b4f116d299d442b335bcd", size = 126161, upload-time = "2024-09-09T23:49:06.306Z" }, { url = "https://files.pythonhosted.org/packages/22/03/acc77a4667cca4462ee974fc39990803e58fa573d5a923d6e82b7ef6da7e/multidict-6.1.0-cp38-cp38-win32.whl", hash = "sha256:e27bbb6d14416713a8bd7aaa1313c0fc8d44ee48d74497a0ff4c3a1b6ccb5167", size = 26338, upload-time = "2024-09-09T23:49:07.782Z" }, { url = "https://files.pythonhosted.org/packages/90/bf/3d0c1cc9c8163abc24625fae89c0ade1ede9bccb6eceb79edf8cff3cca46/multidict-6.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:22f3105d4fb15c8f57ff3959a58fcab6ce36814486500cd7485651230ad4d4ef", size = 28736, upload-time = "2024-09-09T23:49:09.126Z" }, { url = "https://files.pythonhosted.org/packages/e7/c9/9e153a6572b38ac5ff4434113af38acf8d5e9957897cdb1f513b3d6614ed/multidict-6.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4e18b656c5e844539d506a0a06432274d7bd52a7487e6828c63a63d69185626c", size = 48550, upload-time = "2024-09-09T23:49:10.475Z" }, { url = "https://files.pythonhosted.org/packages/76/f5/79565ddb629eba6c7f704f09a09df085c8dc04643b12506f10f718cee37a/multidict-6.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a185f876e69897a6f3325c3f19f26a297fa058c5e456bfcff8015e9a27e83ae1", size = 29298, upload-time = "2024-09-09T23:49:12.119Z" }, { url = "https://files.pythonhosted.org/packages/60/1b/9851878b704bc98e641a3e0bce49382ae9e05743dac6d97748feb5b7baba/multidict-6.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ab7c4ceb38d91570a650dba194e1ca87c2b543488fe9309b4212694174fd539c", size = 29641, upload-time = "2024-09-09T23:49:13.714Z" }, { url = "https://files.pythonhosted.org/packages/89/87/d451d45aab9e422cb0fb2f7720c31a4c1d3012c740483c37f642eba568fb/multidict-6.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e617fb6b0b6953fffd762669610c1c4ffd05632c138d61ac7e14ad187870669c", size = 126202, upload-time = "2024-09-09T23:49:15.238Z" }, { url = "https://files.pythonhosted.org/packages/fa/b4/27cbe9f3e2e469359887653f2e45470272eef7295139916cc21107c6b48c/multidict-6.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16e5f4bf4e603eb1fdd5d8180f1a25f30056f22e55ce51fb3d6ad4ab29f7d96f", size = 133925, upload-time = "2024-09-09T23:49:16.786Z" }, { url = "https://files.pythonhosted.org/packages/4d/a3/afc841899face8adfd004235ce759a37619f6ec99eafd959650c5ce4df57/multidict-6.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4c035da3f544b1882bac24115f3e2e8760f10a0107614fc9839fd232200b875", size = 129039, upload-time = "2024-09-09T23:49:18.381Z" }, { url = "https://files.pythonhosted.org/packages/5e/41/0d0fb18c1ad574f807196f5f3d99164edf9de3e169a58c6dc2d6ed5742b9/multidict-6.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:957cf8e4b6e123a9eea554fa7ebc85674674b713551de587eb318a2df3e00255", size = 124072, upload-time = "2024-09-09T23:49:20.115Z" }, { url = "https://files.pythonhosted.org/packages/00/22/defd7a2e71a44e6e5b9a5428f972e5b572e7fe28e404dfa6519bbf057c93/multidict-6.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:483a6aea59cb89904e1ceabd2b47368b5600fb7de78a6e4a2c2987b2d256cf30", size = 116532, upload-time = "2024-09-09T23:49:21.685Z" }, { url = "https://files.pythonhosted.org/packages/91/25/f7545102def0b1d456ab6449388eed2dfd822debba1d65af60194904a23a/multidict-6.1.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:87701f25a2352e5bf7454caa64757642734da9f6b11384c1f9d1a8e699758057", size = 128173, upload-time = "2024-09-09T23:49:23.657Z" }, { url = "https://files.pythonhosted.org/packages/45/79/3dbe8d35fc99f5ea610813a72ab55f426cb9cf482f860fa8496e5409be11/multidict-6.1.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:682b987361e5fd7a139ed565e30d81fd81e9629acc7d925a205366877d8c8657", size = 122654, upload-time = "2024-09-09T23:49:25.7Z" }, { url = "https://files.pythonhosted.org/packages/97/cb/209e735eeab96e1b160825b5d0b36c56d3862abff828fc43999bb957dcad/multidict-6.1.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ce2186a7df133a9c895dea3331ddc5ddad42cdd0d1ea2f0a51e5d161e4762f28", size = 133197, upload-time = "2024-09-09T23:49:27.906Z" }, { url = "https://files.pythonhosted.org/packages/e4/3a/a13808a7ada62808afccea67837a79d00ad6581440015ef00f726d064c2d/multidict-6.1.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9f636b730f7e8cb19feb87094949ba54ee5357440b9658b2a32a5ce4bce53972", size = 129754, upload-time = "2024-09-09T23:49:29.508Z" }, { url = "https://files.pythonhosted.org/packages/77/dd/8540e139eafb240079242da8f8ffdf9d3f4b4ad1aac5a786cd4050923783/multidict-6.1.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:73eae06aa53af2ea5270cc066dcaf02cc60d2994bbb2c4ef5764949257d10f43", size = 126402, upload-time = "2024-09-09T23:49:31.243Z" }, { url = "https://files.pythonhosted.org/packages/86/99/e82e1a275d8b1ea16d3a251474262258dbbe41c05cce0c01bceda1fc8ea5/multidict-6.1.0-cp39-cp39-win32.whl", hash = "sha256:1ca0083e80e791cffc6efce7660ad24af66c8d4079d2a750b29001b53ff59ada", size = 26421, upload-time = "2024-09-09T23:49:32.648Z" }, { url = "https://files.pythonhosted.org/packages/86/1c/9fa630272355af7e4446a2c7550c259f11ee422ab2d30ff90a0a71cf3d9e/multidict-6.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:aa466da5b15ccea564bdab9c89175c762bc12825f4659c11227f515cee76fa4a", size = 28791, upload-time = "2024-09-09T23:49:34.725Z" }, { url = "https://files.pythonhosted.org/packages/99/b7/b9e70fde2c0f0c9af4cc5277782a89b66d35948ea3369ec9f598358c3ac5/multidict-6.1.0-py3-none-any.whl", hash = "sha256:48e171e52d1c4d33888e529b999e5900356b9ae588c2f09a52dcefb158b27506", size = 10051, upload-time = "2024-09-09T23:49:36.506Z" }, ] [[package]] name = "multidict" version = "6.6.3" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.10'", "python_full_version == '3.9.*'", ] dependencies = [ { name = "typing-extensions", marker = "(python_full_version >= '3.9' and python_full_version < '3.11') or (python_full_version < '3.9' and extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2') or (python_full_version >= '3.11' and extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/3d/2c/5dad12e82fbdf7470f29bff2171484bf07cb3b16ada60a6589af8f376440/multidict-6.6.3.tar.gz", hash = "sha256:798a9eb12dab0a6c2e29c1de6f3468af5cb2da6053a20dfa3344907eed0937cc", size = 101006, upload-time = "2025-06-30T15:53:46.929Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/0b/67/414933982bce2efce7cbcb3169eaaf901e0f25baec69432b4874dfb1f297/multidict-6.6.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a2be5b7b35271f7fff1397204ba6708365e3d773579fe2a30625e16c4b4ce817", size = 77017, upload-time = "2025-06-30T15:50:58.931Z" }, { url = "https://files.pythonhosted.org/packages/8a/fe/d8a3ee1fad37dc2ef4f75488b0d9d4f25bf204aad8306cbab63d97bff64a/multidict-6.6.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:12f4581d2930840295c461764b9a65732ec01250b46c6b2c510d7ee68872b140", size = 44897, upload-time = "2025-06-30T15:51:00.999Z" }, { url = "https://files.pythonhosted.org/packages/1f/e0/265d89af8c98240265d82b8cbcf35897f83b76cd59ee3ab3879050fd8c45/multidict-6.6.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dd7793bab517e706c9ed9d7310b06c8672fd0aeee5781bfad612f56b8e0f7d14", size = 44574, upload-time = "2025-06-30T15:51:02.449Z" }, { url = "https://files.pythonhosted.org/packages/e6/05/6b759379f7e8e04ccc97cfb2a5dcc5cdbd44a97f072b2272dc51281e6a40/multidict-6.6.3-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:72d8815f2cd3cf3df0f83cac3f3ef801d908b2d90409ae28102e0553af85545a", size = 225729, upload-time = "2025-06-30T15:51:03.794Z" }, { url = "https://files.pythonhosted.org/packages/4e/f5/8d5a15488edd9a91fa4aad97228d785df208ed6298580883aa3d9def1959/multidict-6.6.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:531e331a2ee53543ab32b16334e2deb26f4e6b9b28e41f8e0c87e99a6c8e2d69", size = 242515, upload-time = "2025-06-30T15:51:05.002Z" }, { url = "https://files.pythonhosted.org/packages/6e/b5/a8f317d47d0ac5bb746d6d8325885c8967c2a8ce0bb57be5399e3642cccb/multidict-6.6.3-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:42ca5aa9329a63be8dc49040f63817d1ac980e02eeddba763a9ae5b4027b9c9c", size = 222224, upload-time = "2025-06-30T15:51:06.148Z" }, { url = "https://files.pythonhosted.org/packages/76/88/18b2a0d5e80515fa22716556061189c2853ecf2aa2133081ebbe85ebea38/multidict-6.6.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:208b9b9757060b9faa6f11ab4bc52846e4f3c2fb8b14d5680c8aac80af3dc751", size = 253124, upload-time = "2025-06-30T15:51:07.375Z" }, { url = "https://files.pythonhosted.org/packages/62/bf/ebfcfd6b55a1b05ef16d0775ae34c0fe15e8dab570d69ca9941073b969e7/multidict-6.6.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:acf6b97bd0884891af6a8b43d0f586ab2fcf8e717cbd47ab4bdddc09e20652d8", size = 251529, upload-time = "2025-06-30T15:51:08.691Z" }, { url = "https://files.pythonhosted.org/packages/44/11/780615a98fd3775fc309d0234d563941af69ade2df0bb82c91dda6ddaea1/multidict-6.6.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:68e9e12ed00e2089725669bdc88602b0b6f8d23c0c95e52b95f0bc69f7fe9b55", size = 241627, upload-time = "2025-06-30T15:51:10.605Z" }, { url = "https://files.pythonhosted.org/packages/28/3d/35f33045e21034b388686213752cabc3a1b9d03e20969e6fa8f1b1d82db1/multidict-6.6.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:05db2f66c9addb10cfa226e1acb363450fab2ff8a6df73c622fefe2f5af6d4e7", size = 239351, upload-time = "2025-06-30T15:51:12.18Z" }, { url = "https://files.pythonhosted.org/packages/6e/cc/ff84c03b95b430015d2166d9aae775a3985d757b94f6635010d0038d9241/multidict-6.6.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:0db58da8eafb514db832a1b44f8fa7906fdd102f7d982025f816a93ba45e3dcb", size = 233429, upload-time = "2025-06-30T15:51:13.533Z" }, { url = "https://files.pythonhosted.org/packages/2e/f0/8cd49a0b37bdea673a4b793c2093f2f4ba8e7c9d6d7c9bd672fd6d38cd11/multidict-6.6.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:14117a41c8fdb3ee19c743b1c027da0736fdb79584d61a766da53d399b71176c", size = 243094, upload-time = "2025-06-30T15:51:14.815Z" }, { url = "https://files.pythonhosted.org/packages/96/19/5d9a0cfdafe65d82b616a45ae950975820289069f885328e8185e64283c2/multidict-6.6.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:877443eaaabcd0b74ff32ebeed6f6176c71850feb7d6a1d2db65945256ea535c", size = 248957, upload-time = "2025-06-30T15:51:16.076Z" }, { url = "https://files.pythonhosted.org/packages/e6/dc/c90066151da87d1e489f147b9b4327927241e65f1876702fafec6729c014/multidict-6.6.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:70b72e749a4f6e7ed8fb334fa8d8496384840319512746a5f42fa0aec79f4d61", size = 243590, upload-time = "2025-06-30T15:51:17.413Z" }, { url = "https://files.pythonhosted.org/packages/ec/39/458afb0cccbb0ee9164365273be3e039efddcfcb94ef35924b7dbdb05db0/multidict-6.6.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:43571f785b86afd02b3855c5ac8e86ec921b760298d6f82ff2a61daf5a35330b", size = 237487, upload-time = "2025-06-30T15:51:19.039Z" }, { url = "https://files.pythonhosted.org/packages/35/38/0016adac3990426610a081787011177e661875546b434f50a26319dc8372/multidict-6.6.3-cp310-cp310-win32.whl", hash = "sha256:20c5a0c3c13a15fd5ea86c42311859f970070e4e24de5a550e99d7c271d76318", size = 41390, upload-time = "2025-06-30T15:51:20.362Z" }, { url = "https://files.pythonhosted.org/packages/f3/d2/17897a8f3f2c5363d969b4c635aa40375fe1f09168dc09a7826780bfb2a4/multidict-6.6.3-cp310-cp310-win_amd64.whl", hash = "sha256:ab0a34a007704c625e25a9116c6770b4d3617a071c8a7c30cd338dfbadfe6485", size = 45954, upload-time = "2025-06-30T15:51:21.383Z" }, { url = "https://files.pythonhosted.org/packages/2d/5f/d4a717c1e457fe44072e33fa400d2b93eb0f2819c4d669381f925b7cba1f/multidict-6.6.3-cp310-cp310-win_arm64.whl", hash = "sha256:769841d70ca8bdd140a715746199fc6473414bd02efd678d75681d2d6a8986c5", size = 42981, upload-time = "2025-06-30T15:51:22.809Z" }, { url = "https://files.pythonhosted.org/packages/08/f0/1a39863ced51f639c81a5463fbfa9eb4df59c20d1a8769ab9ef4ca57ae04/multidict-6.6.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:18f4eba0cbac3546b8ae31e0bbc55b02c801ae3cbaf80c247fcdd89b456ff58c", size = 76445, upload-time = "2025-06-30T15:51:24.01Z" }, { url = "https://files.pythonhosted.org/packages/c9/0e/a7cfa451c7b0365cd844e90b41e21fab32edaa1e42fc0c9f68461ce44ed7/multidict-6.6.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef43b5dd842382329e4797c46f10748d8c2b6e0614f46b4afe4aee9ac33159df", size = 44610, upload-time = "2025-06-30T15:51:25.158Z" }, { url = "https://files.pythonhosted.org/packages/c6/bb/a14a4efc5ee748cc1904b0748be278c31b9295ce5f4d2ef66526f410b94d/multidict-6.6.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bf9bd1fd5eec01494e0f2e8e446a74a85d5e49afb63d75a9934e4a5423dba21d", size = 44267, upload-time = "2025-06-30T15:51:26.326Z" }, { url = "https://files.pythonhosted.org/packages/c2/f8/410677d563c2d55e063ef74fe578f9d53fe6b0a51649597a5861f83ffa15/multidict-6.6.3-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:5bd8d6f793a787153956cd35e24f60485bf0651c238e207b9a54f7458b16d539", size = 230004, upload-time = "2025-06-30T15:51:27.491Z" }, { url = "https://files.pythonhosted.org/packages/fd/df/2b787f80059314a98e1ec6a4cc7576244986df3e56b3c755e6fc7c99e038/multidict-6.6.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1bf99b4daf908c73856bd87ee0a2499c3c9a3d19bb04b9c6025e66af3fd07462", size = 247196, upload-time = "2025-06-30T15:51:28.762Z" }, { url = "https://files.pythonhosted.org/packages/05/f2/f9117089151b9a8ab39f9019620d10d9718eec2ac89e7ca9d30f3ec78e96/multidict-6.6.3-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0b9e59946b49dafaf990fd9c17ceafa62976e8471a14952163d10a7a630413a9", size = 225337, upload-time = "2025-06-30T15:51:30.025Z" }, { url = "https://files.pythonhosted.org/packages/93/2d/7115300ec5b699faa152c56799b089a53ed69e399c3c2d528251f0aeda1a/multidict-6.6.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e2db616467070d0533832d204c54eea6836a5e628f2cb1e6dfd8cd6ba7277cb7", size = 257079, upload-time = "2025-06-30T15:51:31.716Z" }, { url = "https://files.pythonhosted.org/packages/15/ea/ff4bab367623e39c20d3b07637225c7688d79e4f3cc1f3b9f89867677f9a/multidict-6.6.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7394888236621f61dcdd25189b2768ae5cc280f041029a5bcf1122ac63df79f9", size = 255461, upload-time = "2025-06-30T15:51:33.029Z" }, { url = "https://files.pythonhosted.org/packages/74/07/2c9246cda322dfe08be85f1b8739646f2c4c5113a1422d7a407763422ec4/multidict-6.6.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f114d8478733ca7388e7c7e0ab34b72547476b97009d643644ac33d4d3fe1821", size = 246611, upload-time = "2025-06-30T15:51:34.47Z" }, { url = "https://files.pythonhosted.org/packages/a8/62/279c13d584207d5697a752a66ffc9bb19355a95f7659140cb1b3cf82180e/multidict-6.6.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cdf22e4db76d323bcdc733514bf732e9fb349707c98d341d40ebcc6e9318ef3d", size = 243102, upload-time = "2025-06-30T15:51:36.525Z" }, { url = "https://files.pythonhosted.org/packages/69/cc/e06636f48c6d51e724a8bc8d9e1db5f136fe1df066d7cafe37ef4000f86a/multidict-6.6.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:e995a34c3d44ab511bfc11aa26869b9d66c2d8c799fa0e74b28a473a692532d6", size = 238693, upload-time = "2025-06-30T15:51:38.278Z" }, { url = "https://files.pythonhosted.org/packages/89/a4/66c9d8fb9acf3b226cdd468ed009537ac65b520aebdc1703dd6908b19d33/multidict-6.6.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:766a4a5996f54361d8d5a9050140aa5362fe48ce51c755a50c0bc3706460c430", size = 246582, upload-time = "2025-06-30T15:51:39.709Z" }, { url = "https://files.pythonhosted.org/packages/cf/01/c69e0317be556e46257826d5449feb4e6aa0d18573e567a48a2c14156f1f/multidict-6.6.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:3893a0d7d28a7fe6ca7a1f760593bc13038d1d35daf52199d431b61d2660602b", size = 253355, upload-time = "2025-06-30T15:51:41.013Z" }, { url = "https://files.pythonhosted.org/packages/c0/da/9cc1da0299762d20e626fe0042e71b5694f9f72d7d3f9678397cbaa71b2b/multidict-6.6.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:934796c81ea996e61914ba58064920d6cad5d99140ac3167901eb932150e2e56", size = 247774, upload-time = "2025-06-30T15:51:42.291Z" }, { url = "https://files.pythonhosted.org/packages/e6/91/b22756afec99cc31105ddd4a52f95ab32b1a4a58f4d417979c570c4a922e/multidict-6.6.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9ed948328aec2072bc00f05d961ceadfd3e9bfc2966c1319aeaf7b7c21219183", size = 242275, upload-time = "2025-06-30T15:51:43.642Z" }, { url = "https://files.pythonhosted.org/packages/be/f1/adcc185b878036a20399d5be5228f3cbe7f823d78985d101d425af35c800/multidict-6.6.3-cp311-cp311-win32.whl", hash = "sha256:9f5b28c074c76afc3e4c610c488e3493976fe0e596dd3db6c8ddfbb0134dcac5", size = 41290, upload-time = "2025-06-30T15:51:45.264Z" }, { url = "https://files.pythonhosted.org/packages/e0/d4/27652c1c6526ea6b4f5ddd397e93f4232ff5de42bea71d339bc6a6cc497f/multidict-6.6.3-cp311-cp311-win_amd64.whl", hash = "sha256:bc7f6fbc61b1c16050a389c630da0b32fc6d4a3d191394ab78972bf5edc568c2", size = 45942, upload-time = "2025-06-30T15:51:46.377Z" }, { url = "https://files.pythonhosted.org/packages/16/18/23f4932019804e56d3c2413e237f866444b774b0263bcb81df2fdecaf593/multidict-6.6.3-cp311-cp311-win_arm64.whl", hash = "sha256:d4e47d8faffaae822fb5cba20937c048d4f734f43572e7079298a6c39fb172cb", size = 42880, upload-time = "2025-06-30T15:51:47.561Z" }, { url = "https://files.pythonhosted.org/packages/0e/a0/6b57988ea102da0623ea814160ed78d45a2645e4bbb499c2896d12833a70/multidict-6.6.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:056bebbeda16b2e38642d75e9e5310c484b7c24e3841dc0fb943206a72ec89d6", size = 76514, upload-time = "2025-06-30T15:51:48.728Z" }, { url = "https://files.pythonhosted.org/packages/07/7a/d1e92665b0850c6c0508f101f9cf0410c1afa24973e1115fe9c6a185ebf7/multidict-6.6.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e5f481cccb3c5c5e5de5d00b5141dc589c1047e60d07e85bbd7dea3d4580d63f", size = 45394, upload-time = "2025-06-30T15:51:49.986Z" }, { url = "https://files.pythonhosted.org/packages/52/6f/dd104490e01be6ef8bf9573705d8572f8c2d2c561f06e3826b081d9e6591/multidict-6.6.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:10bea2ee839a759ee368b5a6e47787f399b41e70cf0c20d90dfaf4158dfb4e55", size = 43590, upload-time = "2025-06-30T15:51:51.331Z" }, { url = "https://files.pythonhosted.org/packages/44/fe/06e0e01b1b0611e6581b7fd5a85b43dacc08b6cea3034f902f383b0873e5/multidict-6.6.3-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:2334cfb0fa9549d6ce2c21af2bfbcd3ac4ec3646b1b1581c88e3e2b1779ec92b", size = 237292, upload-time = "2025-06-30T15:51:52.584Z" }, { url = "https://files.pythonhosted.org/packages/ce/71/4f0e558fb77696b89c233c1ee2d92f3e1d5459070a0e89153c9e9e804186/multidict-6.6.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b8fee016722550a2276ca2cb5bb624480e0ed2bd49125b2b73b7010b9090e888", size = 258385, upload-time = "2025-06-30T15:51:53.913Z" }, { url = "https://files.pythonhosted.org/packages/e3/25/cca0e68228addad24903801ed1ab42e21307a1b4b6dd2cf63da5d3ae082a/multidict-6.6.3-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5511cb35f5c50a2db21047c875eb42f308c5583edf96bd8ebf7d770a9d68f6d", size = 242328, upload-time = "2025-06-30T15:51:55.672Z" }, { url = "https://files.pythonhosted.org/packages/6e/a3/46f2d420d86bbcb8fe660b26a10a219871a0fbf4d43cb846a4031533f3e0/multidict-6.6.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:712b348f7f449948e0a6c4564a21c7db965af900973a67db432d724619b3c680", size = 268057, upload-time = "2025-06-30T15:51:57.037Z" }, { url = "https://files.pythonhosted.org/packages/9e/73/1c743542fe00794a2ec7466abd3f312ccb8fad8dff9f36d42e18fb1ec33e/multidict-6.6.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e4e15d2138ee2694e038e33b7c3da70e6b0ad8868b9f8094a72e1414aeda9c1a", size = 269341, upload-time = "2025-06-30T15:51:59.111Z" }, { url = "https://files.pythonhosted.org/packages/a4/11/6ec9dcbe2264b92778eeb85407d1df18812248bf3506a5a1754bc035db0c/multidict-6.6.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8df25594989aebff8a130f7899fa03cbfcc5d2b5f4a461cf2518236fe6f15961", size = 256081, upload-time = "2025-06-30T15:52:00.533Z" }, { url = "https://files.pythonhosted.org/packages/9b/2b/631b1e2afeb5f1696846d747d36cda075bfdc0bc7245d6ba5c319278d6c4/multidict-6.6.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:159ca68bfd284a8860f8d8112cf0521113bffd9c17568579e4d13d1f1dc76b65", size = 253581, upload-time = "2025-06-30T15:52:02.43Z" }, { url = "https://files.pythonhosted.org/packages/bf/0e/7e3b93f79efeb6111d3bf9a1a69e555ba1d07ad1c11bceb56b7310d0d7ee/multidict-6.6.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:e098c17856a8c9ade81b4810888c5ad1914099657226283cab3062c0540b0643", size = 250750, upload-time = "2025-06-30T15:52:04.26Z" }, { url = "https://files.pythonhosted.org/packages/ad/9e/086846c1d6601948e7de556ee464a2d4c85e33883e749f46b9547d7b0704/multidict-6.6.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:67c92ed673049dec52d7ed39f8cf9ebbadf5032c774058b4406d18c8f8fe7063", size = 251548, upload-time = "2025-06-30T15:52:06.002Z" }, { url = "https://files.pythonhosted.org/packages/8c/7b/86ec260118e522f1a31550e87b23542294880c97cfbf6fb18cc67b044c66/multidict-6.6.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:bd0578596e3a835ef451784053cfd327d607fc39ea1a14812139339a18a0dbc3", size = 262718, upload-time = "2025-06-30T15:52:07.707Z" }, { url = "https://files.pythonhosted.org/packages/8c/bd/22ce8f47abb0be04692c9fc4638508b8340987b18691aa7775d927b73f72/multidict-6.6.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:346055630a2df2115cd23ae271910b4cae40f4e336773550dca4889b12916e75", size = 259603, upload-time = "2025-06-30T15:52:09.58Z" }, { url = "https://files.pythonhosted.org/packages/07/9c/91b7ac1691be95cd1f4a26e36a74b97cda6aa9820632d31aab4410f46ebd/multidict-6.6.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:555ff55a359302b79de97e0468e9ee80637b0de1fce77721639f7cd9440b3a10", size = 251351, upload-time = "2025-06-30T15:52:10.947Z" }, { url = "https://files.pythonhosted.org/packages/6f/5c/4d7adc739884f7a9fbe00d1eac8c034023ef8bad71f2ebe12823ca2e3649/multidict-6.6.3-cp312-cp312-win32.whl", hash = "sha256:73ab034fb8d58ff85c2bcbadc470efc3fafeea8affcf8722855fb94557f14cc5", size = 41860, upload-time = "2025-06-30T15:52:12.334Z" }, { url = "https://files.pythonhosted.org/packages/6a/a3/0fbc7afdf7cb1aa12a086b02959307848eb6bcc8f66fcb66c0cb57e2a2c1/multidict-6.6.3-cp312-cp312-win_amd64.whl", hash = "sha256:04cbcce84f63b9af41bad04a54d4cc4e60e90c35b9e6ccb130be2d75b71f8c17", size = 45982, upload-time = "2025-06-30T15:52:13.6Z" }, { url = "https://files.pythonhosted.org/packages/b8/95/8c825bd70ff9b02462dc18d1295dd08d3e9e4eb66856d292ffa62cfe1920/multidict-6.6.3-cp312-cp312-win_arm64.whl", hash = "sha256:0f1130b896ecb52d2a1e615260f3ea2af55fa7dc3d7c3003ba0c3121a759b18b", size = 43210, upload-time = "2025-06-30T15:52:14.893Z" }, { url = "https://files.pythonhosted.org/packages/52/1d/0bebcbbb4f000751fbd09957257903d6e002943fc668d841a4cf2fb7f872/multidict-6.6.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:540d3c06d48507357a7d57721e5094b4f7093399a0106c211f33540fdc374d55", size = 75843, upload-time = "2025-06-30T15:52:16.155Z" }, { url = "https://files.pythonhosted.org/packages/07/8f/cbe241b0434cfe257f65c2b1bcf9e8d5fb52bc708c5061fb29b0fed22bdf/multidict-6.6.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9c19cea2a690f04247d43f366d03e4eb110a0dc4cd1bbeee4d445435428ed35b", size = 45053, upload-time = "2025-06-30T15:52:17.429Z" }, { url = "https://files.pythonhosted.org/packages/32/d2/0b3b23f9dbad5b270b22a3ac3ea73ed0a50ef2d9a390447061178ed6bdb8/multidict-6.6.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7af039820cfd00effec86bda5d8debef711a3e86a1d3772e85bea0f243a4bd65", size = 43273, upload-time = "2025-06-30T15:52:19.346Z" }, { url = "https://files.pythonhosted.org/packages/fd/fe/6eb68927e823999e3683bc49678eb20374ba9615097d085298fd5b386564/multidict-6.6.3-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:500b84f51654fdc3944e936f2922114349bf8fdcac77c3092b03449f0e5bc2b3", size = 237124, upload-time = "2025-06-30T15:52:20.773Z" }, { url = "https://files.pythonhosted.org/packages/e7/ab/320d8507e7726c460cb77117848b3834ea0d59e769f36fdae495f7669929/multidict-6.6.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3fc723ab8a5c5ed6c50418e9bfcd8e6dceba6c271cee6728a10a4ed8561520c", size = 256892, upload-time = "2025-06-30T15:52:22.242Z" }, { url = "https://files.pythonhosted.org/packages/76/60/38ee422db515ac69834e60142a1a69111ac96026e76e8e9aa347fd2e4591/multidict-6.6.3-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:94c47ea3ade005b5976789baaed66d4de4480d0a0bf31cef6edaa41c1e7b56a6", size = 240547, upload-time = "2025-06-30T15:52:23.736Z" }, { url = "https://files.pythonhosted.org/packages/27/fb/905224fde2dff042b030c27ad95a7ae744325cf54b890b443d30a789b80e/multidict-6.6.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:dbc7cf464cc6d67e83e136c9f55726da3a30176f020a36ead246eceed87f1cd8", size = 266223, upload-time = "2025-06-30T15:52:25.185Z" }, { url = "https://files.pythonhosted.org/packages/76/35/dc38ab361051beae08d1a53965e3e1a418752fc5be4d3fb983c5582d8784/multidict-6.6.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:900eb9f9da25ada070f8ee4a23f884e0ee66fe4e1a38c3af644256a508ad81ca", size = 267262, upload-time = "2025-06-30T15:52:26.969Z" }, { url = "https://files.pythonhosted.org/packages/1f/a3/0a485b7f36e422421b17e2bbb5a81c1af10eac1d4476f2ff92927c730479/multidict-6.6.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7c6df517cf177da5d47ab15407143a89cd1a23f8b335f3a28d57e8b0a3dbb884", size = 254345, upload-time = "2025-06-30T15:52:28.467Z" }, { url = "https://files.pythonhosted.org/packages/b4/59/bcdd52c1dab7c0e0d75ff19cac751fbd5f850d1fc39172ce809a74aa9ea4/multidict-6.6.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4ef421045f13879e21c994b36e728d8e7d126c91a64b9185810ab51d474f27e7", size = 252248, upload-time = "2025-06-30T15:52:29.938Z" }, { url = "https://files.pythonhosted.org/packages/bb/a4/2d96aaa6eae8067ce108d4acee6f45ced5728beda55c0f02ae1072c730d1/multidict-6.6.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:6c1e61bb4f80895c081790b6b09fa49e13566df8fbff817da3f85b3a8192e36b", size = 250115, upload-time = "2025-06-30T15:52:31.416Z" }, { url = "https://files.pythonhosted.org/packages/25/d2/ed9f847fa5c7d0677d4f02ea2c163d5e48573de3f57bacf5670e43a5ffaa/multidict-6.6.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:e5e8523bb12d7623cd8300dbd91b9e439a46a028cd078ca695eb66ba31adee3c", size = 249649, upload-time = "2025-06-30T15:52:32.996Z" }, { url = "https://files.pythonhosted.org/packages/1f/af/9155850372563fc550803d3f25373308aa70f59b52cff25854086ecb4a79/multidict-6.6.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:ef58340cc896219e4e653dade08fea5c55c6df41bcc68122e3be3e9d873d9a7b", size = 261203, upload-time = "2025-06-30T15:52:34.521Z" }, { url = "https://files.pythonhosted.org/packages/36/2f/c6a728f699896252cf309769089568a33c6439626648843f78743660709d/multidict-6.6.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fc9dc435ec8699e7b602b94fe0cd4703e69273a01cbc34409af29e7820f777f1", size = 258051, upload-time = "2025-06-30T15:52:35.999Z" }, { url = "https://files.pythonhosted.org/packages/d0/60/689880776d6b18fa2b70f6cc74ff87dd6c6b9b47bd9cf74c16fecfaa6ad9/multidict-6.6.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9e864486ef4ab07db5e9cb997bad2b681514158d6954dd1958dfb163b83d53e6", size = 249601, upload-time = "2025-06-30T15:52:37.473Z" }, { url = "https://files.pythonhosted.org/packages/75/5e/325b11f2222a549019cf2ef879c1f81f94a0d40ace3ef55cf529915ba6cc/multidict-6.6.3-cp313-cp313-win32.whl", hash = "sha256:5633a82fba8e841bc5c5c06b16e21529573cd654f67fd833650a215520a6210e", size = 41683, upload-time = "2025-06-30T15:52:38.927Z" }, { url = "https://files.pythonhosted.org/packages/b1/ad/cf46e73f5d6e3c775cabd2a05976547f3f18b39bee06260369a42501f053/multidict-6.6.3-cp313-cp313-win_amd64.whl", hash = "sha256:e93089c1570a4ad54c3714a12c2cef549dc9d58e97bcded193d928649cab78e9", size = 45811, upload-time = "2025-06-30T15:52:40.207Z" }, { url = "https://files.pythonhosted.org/packages/c5/c9/2e3fe950db28fb7c62e1a5f46e1e38759b072e2089209bc033c2798bb5ec/multidict-6.6.3-cp313-cp313-win_arm64.whl", hash = "sha256:c60b401f192e79caec61f166da9c924e9f8bc65548d4246842df91651e83d600", size = 43056, upload-time = "2025-06-30T15:52:41.575Z" }, { url = "https://files.pythonhosted.org/packages/3a/58/aaf8114cf34966e084a8cc9517771288adb53465188843d5a19862cb6dc3/multidict-6.6.3-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:02fd8f32d403a6ff13864b0851f1f523d4c988051eea0471d4f1fd8010f11134", size = 82811, upload-time = "2025-06-30T15:52:43.281Z" }, { url = "https://files.pythonhosted.org/packages/71/af/5402e7b58a1f5b987a07ad98f2501fdba2a4f4b4c30cf114e3ce8db64c87/multidict-6.6.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:f3aa090106b1543f3f87b2041eef3c156c8da2aed90c63a2fbed62d875c49c37", size = 48304, upload-time = "2025-06-30T15:52:45.026Z" }, { url = "https://files.pythonhosted.org/packages/39/65/ab3c8cafe21adb45b24a50266fd747147dec7847425bc2a0f6934b3ae9ce/multidict-6.6.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e924fb978615a5e33ff644cc42e6aa241effcf4f3322c09d4f8cebde95aff5f8", size = 46775, upload-time = "2025-06-30T15:52:46.459Z" }, { url = "https://files.pythonhosted.org/packages/49/ba/9fcc1b332f67cc0c0c8079e263bfab6660f87fe4e28a35921771ff3eea0d/multidict-6.6.3-cp313-cp313t-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:b9fe5a0e57c6dbd0e2ce81ca66272282c32cd11d31658ee9553849d91289e1c1", size = 229773, upload-time = "2025-06-30T15:52:47.88Z" }, { url = "https://files.pythonhosted.org/packages/a4/14/0145a251f555f7c754ce2dcbcd012939bbd1f34f066fa5d28a50e722a054/multidict-6.6.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b24576f208793ebae00280c59927c3b7c2a3b1655e443a25f753c4611bc1c373", size = 250083, upload-time = "2025-06-30T15:52:49.366Z" }, { url = "https://files.pythonhosted.org/packages/9e/d4/d5c0bd2bbb173b586c249a151a26d2fb3ec7d53c96e42091c9fef4e1f10c/multidict-6.6.3-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:135631cb6c58eac37d7ac0df380294fecdc026b28837fa07c02e459c7fb9c54e", size = 228980, upload-time = "2025-06-30T15:52:50.903Z" }, { url = "https://files.pythonhosted.org/packages/21/32/c9a2d8444a50ec48c4733ccc67254100c10e1c8ae8e40c7a2d2183b59b97/multidict-6.6.3-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:274d416b0df887aef98f19f21578653982cfb8a05b4e187d4a17103322eeaf8f", size = 257776, upload-time = "2025-06-30T15:52:52.764Z" }, { url = "https://files.pythonhosted.org/packages/68/d0/14fa1699f4ef629eae08ad6201c6b476098f5efb051b296f4c26be7a9fdf/multidict-6.6.3-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e252017a817fad7ce05cafbe5711ed40faeb580e63b16755a3a24e66fa1d87c0", size = 256882, upload-time = "2025-06-30T15:52:54.596Z" }, { url = "https://files.pythonhosted.org/packages/da/88/84a27570fbe303c65607d517a5f147cd2fc046c2d1da02b84b17b9bdc2aa/multidict-6.6.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e4cc8d848cd4fe1cdee28c13ea79ab0ed37fc2e89dd77bac86a2e7959a8c3bc", size = 247816, upload-time = "2025-06-30T15:52:56.175Z" }, { url = "https://files.pythonhosted.org/packages/1c/60/dca352a0c999ce96a5d8b8ee0b2b9f729dcad2e0b0c195f8286269a2074c/multidict-6.6.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9e236a7094b9c4c1b7585f6b9cca34b9d833cf079f7e4c49e6a4a6ec9bfdc68f", size = 245341, upload-time = "2025-06-30T15:52:57.752Z" }, { url = "https://files.pythonhosted.org/packages/50/ef/433fa3ed06028f03946f3993223dada70fb700f763f70c00079533c34578/multidict-6.6.3-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:e0cb0ab69915c55627c933f0b555a943d98ba71b4d1c57bc0d0a66e2567c7471", size = 235854, upload-time = "2025-06-30T15:52:59.74Z" }, { url = "https://files.pythonhosted.org/packages/1b/1f/487612ab56fbe35715320905215a57fede20de7db40a261759690dc80471/multidict-6.6.3-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:81ef2f64593aba09c5212a3d0f8c906a0d38d710a011f2f42759704d4557d3f2", size = 243432, upload-time = "2025-06-30T15:53:01.602Z" }, { url = "https://files.pythonhosted.org/packages/da/6f/ce8b79de16cd885c6f9052c96a3671373d00c59b3ee635ea93e6e81b8ccf/multidict-6.6.3-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:b9cbc60010de3562545fa198bfc6d3825df430ea96d2cc509c39bd71e2e7d648", size = 252731, upload-time = "2025-06-30T15:53:03.517Z" }, { url = "https://files.pythonhosted.org/packages/bb/fe/a2514a6aba78e5abefa1624ca85ae18f542d95ac5cde2e3815a9fbf369aa/multidict-6.6.3-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:70d974eaaa37211390cd02ef93b7e938de564bbffa866f0b08d07e5e65da783d", size = 247086, upload-time = "2025-06-30T15:53:05.48Z" }, { url = "https://files.pythonhosted.org/packages/8c/22/b788718d63bb3cce752d107a57c85fcd1a212c6c778628567c9713f9345a/multidict-6.6.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:3713303e4a6663c6d01d648a68f2848701001f3390a030edaaf3fc949c90bf7c", size = 243338, upload-time = "2025-06-30T15:53:07.522Z" }, { url = "https://files.pythonhosted.org/packages/22/d6/fdb3d0670819f2228f3f7d9af613d5e652c15d170c83e5f1c94fbc55a25b/multidict-6.6.3-cp313-cp313t-win32.whl", hash = "sha256:639ecc9fe7cd73f2495f62c213e964843826f44505a3e5d82805aa85cac6f89e", size = 47812, upload-time = "2025-06-30T15:53:09.263Z" }, { url = "https://files.pythonhosted.org/packages/b6/d6/a9d2c808f2c489ad199723197419207ecbfbc1776f6e155e1ecea9c883aa/multidict-6.6.3-cp313-cp313t-win_amd64.whl", hash = "sha256:9f97e181f344a0ef3881b573d31de8542cc0dbc559ec68c8f8b5ce2c2e91646d", size = 53011, upload-time = "2025-06-30T15:53:11.038Z" }, { url = "https://files.pythonhosted.org/packages/f2/40/b68001cba8188dd267590a111f9661b6256debc327137667e832bf5d66e8/multidict-6.6.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ce8b7693da41a3c4fde5871c738a81490cea5496c671d74374c8ab889e1834fb", size = 45254, upload-time = "2025-06-30T15:53:12.421Z" }, { url = "https://files.pythonhosted.org/packages/d2/64/ba29bd6dfc895e592b2f20f92378e692ac306cf25dd0be2f8e0a0f898edb/multidict-6.6.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c8161b5a7778d3137ea2ee7ae8a08cce0010de3b00ac671c5ebddeaa17cefd22", size = 76959, upload-time = "2025-06-30T15:53:13.827Z" }, { url = "https://files.pythonhosted.org/packages/ca/cd/872ae4c134257dacebff59834983c1615d6ec863b6e3d360f3203aad8400/multidict-6.6.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1328201ee930f069961ae707d59c6627ac92e351ed5b92397cf534d1336ce557", size = 44864, upload-time = "2025-06-30T15:53:15.658Z" }, { url = "https://files.pythonhosted.org/packages/15/35/d417d8f62f2886784b76df60522d608aba39dfc83dd53b230ca71f2d4c53/multidict-6.6.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b1db4d2093d6b235de76932febf9d50766cf49a5692277b2c28a501c9637f616", size = 44540, upload-time = "2025-06-30T15:53:17.208Z" }, { url = "https://files.pythonhosted.org/packages/85/59/25cddf781f12cddb2386baa29744a3fdd160eb705539b48065f0cffd86d5/multidict-6.6.3-cp39-cp39-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:53becb01dd8ebd19d1724bebe369cfa87e4e7f29abbbe5c14c98ce4c383e16cd", size = 224075, upload-time = "2025-06-30T15:53:18.705Z" }, { url = "https://files.pythonhosted.org/packages/c4/21/4055b6a527954c572498a8068c26bd3b75f2b959080e17e12104b592273c/multidict-6.6.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41bb9d1d4c303886e2d85bade86e59885112a7f4277af5ad47ab919a2251f306", size = 240535, upload-time = "2025-06-30T15:53:20.359Z" }, { url = "https://files.pythonhosted.org/packages/58/98/17f1f80bdba0b2fef49cf4ba59cebf8a81797f745f547abb5c9a4039df62/multidict-6.6.3-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:775b464d31dac90f23192af9c291dc9f423101857e33e9ebf0020a10bfcf4144", size = 219361, upload-time = "2025-06-30T15:53:22.371Z" }, { url = "https://files.pythonhosted.org/packages/f8/0e/a5e595fdd0820069f0c29911d5dc9dc3a75ec755ae733ce59a4e6962ae42/multidict-6.6.3-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d04d01f0a913202205a598246cf77826fe3baa5a63e9f6ccf1ab0601cf56eca0", size = 251207, upload-time = "2025-06-30T15:53:24.307Z" }, { url = "https://files.pythonhosted.org/packages/66/9e/0f51e4cffea2daf24c137feabc9ec848ce50f8379c9badcbac00b41ab55e/multidict-6.6.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d25594d3b38a2e6cabfdcafef339f754ca6e81fbbdb6650ad773ea9775af35ab", size = 249749, upload-time = "2025-06-30T15:53:26.056Z" }, { url = "https://files.pythonhosted.org/packages/49/a0/a7cfc13c9a71ceb8c1c55457820733af9ce01e121139271f7b13e30c29d2/multidict-6.6.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:35712f1748d409e0707b165bf49f9f17f9e28ae85470c41615778f8d4f7d9609", size = 239202, upload-time = "2025-06-30T15:53:28.096Z" }, { url = "https://files.pythonhosted.org/packages/c7/50/7ae0d1149ac71cab6e20bb7faf2a1868435974994595dadfdb7377f7140f/multidict-6.6.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1c8082e5814b662de8589d6a06c17e77940d5539080cbab9fe6794b5241b76d9", size = 237269, upload-time = "2025-06-30T15:53:30.124Z" }, { url = "https://files.pythonhosted.org/packages/b4/ac/2d0bf836c9c63a57360d57b773359043b371115e1c78ff648993bf19abd0/multidict-6.6.3-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:61af8a4b771f1d4d000b3168c12c3120ccf7284502a94aa58c68a81f5afac090", size = 232961, upload-time = "2025-06-30T15:53:31.766Z" }, { url = "https://files.pythonhosted.org/packages/85/e1/68a65f069df298615591e70e48bfd379c27d4ecb252117c18bf52eebc237/multidict-6.6.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:448e4a9afccbf297577f2eaa586f07067441e7b63c8362a3540ba5a38dc0f14a", size = 240863, upload-time = "2025-06-30T15:53:33.488Z" }, { url = "https://files.pythonhosted.org/packages/ae/ab/702f1baca649f88ea1dc6259fc2aa4509f4ad160ba48c8e61fbdb4a5a365/multidict-6.6.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:233ad16999afc2bbd3e534ad8dbe685ef8ee49a37dbc2cdc9514e57b6d589ced", size = 246800, upload-time = "2025-06-30T15:53:35.21Z" }, { url = "https://files.pythonhosted.org/packages/5e/0b/726e690bfbf887985a8710ef2f25f1d6dd184a35bd3b36429814f810a2fc/multidict-6.6.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:bb933c891cd4da6bdcc9733d048e994e22e1883287ff7540c2a0f3b117605092", size = 242034, upload-time = "2025-06-30T15:53:36.913Z" }, { url = "https://files.pythonhosted.org/packages/73/bb/839486b27bcbcc2e0d875fb9d4012b4b6aa99639137343106aa7210e047a/multidict-6.6.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:37b09ca60998e87734699e88c2363abfd457ed18cfbf88e4009a4e83788e63ed", size = 235377, upload-time = "2025-06-30T15:53:38.618Z" }, { url = "https://files.pythonhosted.org/packages/e3/46/574d75ab7b9ae8690fe27e89f5fcd0121633112b438edfb9ed2be8be096b/multidict-6.6.3-cp39-cp39-win32.whl", hash = "sha256:f54cb79d26d0cd420637d184af38f0668558f3c4bbe22ab7ad830e67249f2e0b", size = 41420, upload-time = "2025-06-30T15:53:40.309Z" }, { url = "https://files.pythonhosted.org/packages/78/c3/8b3bc755508b777868349f4bfa844d3d31832f075ee800a3d6f1807338c5/multidict-6.6.3-cp39-cp39-win_amd64.whl", hash = "sha256:295adc9c0551e5d5214b45cf29ca23dbc28c2d197a9c30d51aed9e037cb7c578", size = 46124, upload-time = "2025-06-30T15:53:41.984Z" }, { url = "https://files.pythonhosted.org/packages/b2/30/5a66e7e4550e80975faee5b5dd9e9bd09194d2fd8f62363119b9e46e204b/multidict-6.6.3-cp39-cp39-win_arm64.whl", hash = "sha256:15332783596f227db50fb261c2c251a58ac3873c457f3a550a95d5c0aa3c770d", size = 42973, upload-time = "2025-06-30T15:53:43.505Z" }, { url = "https://files.pythonhosted.org/packages/d8/30/9aec301e9772b098c1f5c0ca0279237c9766d94b97802e9888010c64b0ed/multidict-6.6.3-py3-none-any.whl", hash = "sha256:8db10f29c7541fc5da4defd8cd697e1ca429db743fa716325f236079b96f775a", size = 12313, upload-time = "2025-06-30T15:53:45.437Z" }, ] [[package]] name = "mypy" version = "1.14.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mypy-extensions" }, { name = "tomli", marker = "python_full_version < '3.11' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b9/eb/2c92d8ea1e684440f54fa49ac5d9a5f19967b7b472a281f419e69a8d228e/mypy-1.14.1.tar.gz", hash = "sha256:7ec88144fe9b510e8475ec2f5f251992690fcf89ccb4500b214b4226abcd32d6", size = 3216051, upload-time = "2024-12-30T16:39:07.335Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/9b/7a/87ae2adb31d68402da6da1e5f30c07ea6063e9f09b5e7cfc9dfa44075e74/mypy-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:52686e37cf13d559f668aa398dd7ddf1f92c5d613e4f8cb262be2fb4fedb0fcb", size = 11211002, upload-time = "2024-12-30T16:37:22.435Z" }, { url = "https://files.pythonhosted.org/packages/e1/23/eada4c38608b444618a132be0d199b280049ded278b24cbb9d3fc59658e4/mypy-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1fb545ca340537d4b45d3eecdb3def05e913299ca72c290326be19b3804b39c0", size = 10358400, upload-time = "2024-12-30T16:37:53.526Z" }, { url = "https://files.pythonhosted.org/packages/43/c9/d6785c6f66241c62fd2992b05057f404237deaad1566545e9f144ced07f5/mypy-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90716d8b2d1f4cd503309788e51366f07c56635a3309b0f6a32547eaaa36a64d", size = 12095172, upload-time = "2024-12-30T16:37:50.332Z" }, { url = "https://files.pythonhosted.org/packages/c3/62/daa7e787770c83c52ce2aaf1a111eae5893de9e004743f51bfcad9e487ec/mypy-1.14.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ae753f5c9fef278bcf12e1a564351764f2a6da579d4a81347e1d5a15819997b", size = 12828732, upload-time = "2024-12-30T16:37:29.96Z" }, { url = "https://files.pythonhosted.org/packages/1b/a2/5fb18318a3637f29f16f4e41340b795da14f4751ef4f51c99ff39ab62e52/mypy-1.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e0fe0f5feaafcb04505bcf439e991c6d8f1bf8b15f12b05feeed96e9e7bf1427", size = 13012197, upload-time = "2024-12-30T16:38:05.037Z" }, { url = "https://files.pythonhosted.org/packages/28/99/e153ce39105d164b5f02c06c35c7ba958aaff50a2babba7d080988b03fe7/mypy-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:7d54bd85b925e501c555a3227f3ec0cfc54ee8b6930bd6141ec872d1c572f81f", size = 9780836, upload-time = "2024-12-30T16:37:19.726Z" }, { url = "https://files.pythonhosted.org/packages/da/11/a9422850fd506edbcdc7f6090682ecceaf1f87b9dd847f9df79942da8506/mypy-1.14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f995e511de847791c3b11ed90084a7a0aafdc074ab88c5a9711622fe4751138c", size = 11120432, upload-time = "2024-12-30T16:37:11.533Z" }, { url = "https://files.pythonhosted.org/packages/b6/9e/47e450fd39078d9c02d620545b2cb37993a8a8bdf7db3652ace2f80521ca/mypy-1.14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d64169ec3b8461311f8ce2fd2eb5d33e2d0f2c7b49116259c51d0d96edee48d1", size = 10279515, upload-time = "2024-12-30T16:37:40.724Z" }, { url = "https://files.pythonhosted.org/packages/01/b5/6c8d33bd0f851a7692a8bfe4ee75eb82b6983a3cf39e5e32a5d2a723f0c1/mypy-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba24549de7b89b6381b91fbc068d798192b1b5201987070319889e93038967a8", size = 12025791, upload-time = "2024-12-30T16:36:58.73Z" }, { url = "https://files.pythonhosted.org/packages/f0/4c/e10e2c46ea37cab5c471d0ddaaa9a434dc1d28650078ac1b56c2d7b9b2e4/mypy-1.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:183cf0a45457d28ff9d758730cd0210419ac27d4d3f285beda038c9083363b1f", size = 12749203, upload-time = "2024-12-30T16:37:03.741Z" }, { url = "https://files.pythonhosted.org/packages/88/55/beacb0c69beab2153a0f57671ec07861d27d735a0faff135a494cd4f5020/mypy-1.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f2a0ecc86378f45347f586e4163d1769dd81c5a223d577fe351f26b179e148b1", size = 12885900, upload-time = "2024-12-30T16:37:57.948Z" }, { url = "https://files.pythonhosted.org/packages/a2/75/8c93ff7f315c4d086a2dfcde02f713004357d70a163eddb6c56a6a5eff40/mypy-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:ad3301ebebec9e8ee7135d8e3109ca76c23752bac1e717bc84cd3836b4bf3eae", size = 9777869, upload-time = "2024-12-30T16:37:33.428Z" }, { url = "https://files.pythonhosted.org/packages/43/1b/b38c079609bb4627905b74fc6a49849835acf68547ac33d8ceb707de5f52/mypy-1.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:30ff5ef8519bbc2e18b3b54521ec319513a26f1bba19a7582e7b1f58a6e69f14", size = 11266668, upload-time = "2024-12-30T16:38:02.211Z" }, { url = "https://files.pythonhosted.org/packages/6b/75/2ed0d2964c1ffc9971c729f7a544e9cd34b2cdabbe2d11afd148d7838aa2/mypy-1.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cb9f255c18052343c70234907e2e532bc7e55a62565d64536dbc7706a20b78b9", size = 10254060, upload-time = "2024-12-30T16:37:46.131Z" }, { url = "https://files.pythonhosted.org/packages/a1/5f/7b8051552d4da3c51bbe8fcafffd76a6823779101a2b198d80886cd8f08e/mypy-1.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b4e3413e0bddea671012b063e27591b953d653209e7a4fa5e48759cda77ca11", size = 11933167, upload-time = "2024-12-30T16:37:43.534Z" }, { url = "https://files.pythonhosted.org/packages/04/90/f53971d3ac39d8b68bbaab9a4c6c58c8caa4d5fd3d587d16f5927eeeabe1/mypy-1.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:553c293b1fbdebb6c3c4030589dab9fafb6dfa768995a453d8a5d3b23784af2e", size = 12864341, upload-time = "2024-12-30T16:37:36.249Z" }, { url = "https://files.pythonhosted.org/packages/03/d2/8bc0aeaaf2e88c977db41583559319f1821c069e943ada2701e86d0430b7/mypy-1.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fad79bfe3b65fe6a1efaed97b445c3d37f7be9fdc348bdb2d7cac75579607c89", size = 12972991, upload-time = "2024-12-30T16:37:06.743Z" }, { url = "https://files.pythonhosted.org/packages/6f/17/07815114b903b49b0f2cf7499f1c130e5aa459411596668267535fe9243c/mypy-1.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:8fa2220e54d2946e94ab6dbb3ba0a992795bd68b16dc852db33028df2b00191b", size = 9879016, upload-time = "2024-12-30T16:37:15.02Z" }, { url = "https://files.pythonhosted.org/packages/9e/15/bb6a686901f59222275ab228453de741185f9d54fecbaacec041679496c6/mypy-1.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:92c3ed5afb06c3a8e188cb5da4984cab9ec9a77ba956ee419c68a388b4595255", size = 11252097, upload-time = "2024-12-30T16:37:25.144Z" }, { url = "https://files.pythonhosted.org/packages/f8/b3/8b0f74dfd072c802b7fa368829defdf3ee1566ba74c32a2cb2403f68024c/mypy-1.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dbec574648b3e25f43d23577309b16534431db4ddc09fda50841f1e34e64ed34", size = 10239728, upload-time = "2024-12-30T16:38:08.634Z" }, { url = "https://files.pythonhosted.org/packages/c5/9b/4fd95ab20c52bb5b8c03cc49169be5905d931de17edfe4d9d2986800b52e/mypy-1.14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8c6d94b16d62eb3e947281aa7347d78236688e21081f11de976376cf010eb31a", size = 11924965, upload-time = "2024-12-30T16:38:12.132Z" }, { url = "https://files.pythonhosted.org/packages/56/9d/4a236b9c57f5d8f08ed346914b3f091a62dd7e19336b2b2a0d85485f82ff/mypy-1.14.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d4b19b03fdf54f3c5b2fa474c56b4c13c9dbfb9a2db4370ede7ec11a2c5927d9", size = 12867660, upload-time = "2024-12-30T16:38:17.342Z" }, { url = "https://files.pythonhosted.org/packages/40/88/a61a5497e2f68d9027de2bb139c7bb9abaeb1be1584649fa9d807f80a338/mypy-1.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0c911fde686394753fff899c409fd4e16e9b294c24bfd5e1ea4675deae1ac6fd", size = 12969198, upload-time = "2024-12-30T16:38:32.839Z" }, { url = "https://files.pythonhosted.org/packages/54/da/3d6fc5d92d324701b0c23fb413c853892bfe0e1dbe06c9138037d459756b/mypy-1.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:8b21525cb51671219f5307be85f7e646a153e5acc656e5cebf64bfa076c50107", size = 9885276, upload-time = "2024-12-30T16:38:20.828Z" }, { url = "https://files.pythonhosted.org/packages/39/02/1817328c1372be57c16148ce7d2bfcfa4a796bedaed897381b1aad9b267c/mypy-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7084fb8f1128c76cd9cf68fe5971b37072598e7c31b2f9f95586b65c741a9d31", size = 11143050, upload-time = "2024-12-30T16:38:29.743Z" }, { url = "https://files.pythonhosted.org/packages/b9/07/99db9a95ece5e58eee1dd87ca456a7e7b5ced6798fd78182c59c35a7587b/mypy-1.14.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8f845a00b4f420f693f870eaee5f3e2692fa84cc8514496114649cfa8fd5e2c6", size = 10321087, upload-time = "2024-12-30T16:38:14.739Z" }, { url = "https://files.pythonhosted.org/packages/9a/eb/85ea6086227b84bce79b3baf7f465b4732e0785830726ce4a51528173b71/mypy-1.14.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44bf464499f0e3a2d14d58b54674dee25c031703b2ffc35064bd0df2e0fac319", size = 12066766, upload-time = "2024-12-30T16:38:47.038Z" }, { url = "https://files.pythonhosted.org/packages/4b/bb/f01bebf76811475d66359c259eabe40766d2f8ac8b8250d4e224bb6df379/mypy-1.14.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c99f27732c0b7dc847adb21c9d47ce57eb48fa33a17bc6d7d5c5e9f9e7ae5bac", size = 12787111, upload-time = "2024-12-30T16:39:02.444Z" }, { url = "https://files.pythonhosted.org/packages/2f/c9/84837ff891edcb6dcc3c27d85ea52aab0c4a34740ff5f0ccc0eb87c56139/mypy-1.14.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:bce23c7377b43602baa0bd22ea3265c49b9ff0b76eb315d6c34721af4cdf1d9b", size = 12974331, upload-time = "2024-12-30T16:38:23.849Z" }, { url = "https://files.pythonhosted.org/packages/84/5f/901e18464e6a13f8949b4909535be3fa7f823291b8ab4e4b36cfe57d6769/mypy-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:8edc07eeade7ebc771ff9cf6b211b9a7d93687ff892150cb5692e4f4272b0837", size = 9763210, upload-time = "2024-12-30T16:38:36.299Z" }, { url = "https://files.pythonhosted.org/packages/ca/1f/186d133ae2514633f8558e78cd658070ba686c0e9275c5a5c24a1e1f0d67/mypy-1.14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3888a1816d69f7ab92092f785a462944b3ca16d7c470d564165fe703b0970c35", size = 11200493, upload-time = "2024-12-30T16:38:26.935Z" }, { url = "https://files.pythonhosted.org/packages/af/fc/4842485d034e38a4646cccd1369f6b1ccd7bc86989c52770d75d719a9941/mypy-1.14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:46c756a444117c43ee984bd055db99e498bc613a70bbbc120272bd13ca579fbc", size = 10357702, upload-time = "2024-12-30T16:38:50.623Z" }, { url = "https://files.pythonhosted.org/packages/b4/e6/457b83f2d701e23869cfec013a48a12638f75b9d37612a9ddf99072c1051/mypy-1.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:27fc248022907e72abfd8e22ab1f10e903915ff69961174784a3900a8cba9ad9", size = 12091104, upload-time = "2024-12-30T16:38:53.735Z" }, { url = "https://files.pythonhosted.org/packages/f1/bf/76a569158db678fee59f4fd30b8e7a0d75bcbaeef49edd882a0d63af6d66/mypy-1.14.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:499d6a72fb7e5de92218db961f1a66d5f11783f9ae549d214617edab5d4dbdbb", size = 12830167, upload-time = "2024-12-30T16:38:56.437Z" }, { url = "https://files.pythonhosted.org/packages/43/bc/0bc6b694b3103de9fed61867f1c8bd33336b913d16831431e7cb48ef1c92/mypy-1.14.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:57961db9795eb566dc1d1b4e9139ebc4c6b0cb6e7254ecde69d1552bf7613f60", size = 13013834, upload-time = "2024-12-30T16:38:59.204Z" }, { url = "https://files.pythonhosted.org/packages/b0/79/5f5ec47849b6df1e6943d5fd8e6632fbfc04b4fd4acfa5a5a9535d11b4e2/mypy-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:07ba89fdcc9451f2ebb02853deb6aaaa3d2239a236669a63ab3801bbf923ef5c", size = 9781231, upload-time = "2024-12-30T16:39:05.124Z" }, { url = "https://files.pythonhosted.org/packages/a0/b5/32dd67b69a16d088e533962e5044e51004176a9952419de0370cdaead0f8/mypy-1.14.1-py3-none-any.whl", hash = "sha256:b66a60cc4073aeb8ae00057f9c1f64d49e90f918fbcef9a977eb121da8b8f1d1", size = 2752905, upload-time = "2024-12-30T16:38:42.021Z" }, ] [[package]] name = "mypy-extensions" version = "1.0.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782", size = 4433, upload-time = "2023-02-04T12:11:27.157Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695, upload-time = "2023-02-04T12:11:25.002Z" }, ] [[package]] name = "nodeenv" version = "1.9.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437, upload-time = "2024-06-04T18:44:11.171Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" }, ] [[package]] name = "packaging" version = "24.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950, upload-time = "2024-11-08T09:47:47.202Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451, upload-time = "2024-11-08T09:47:44.722Z" }, ] [[package]] name = "pluggy" version = "1.5.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955, upload-time = "2024-04-20T21:34:42.531Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556, upload-time = "2024-04-20T21:34:40.434Z" }, ] [[package]] name = "propcache" version = "0.2.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] sdist = { url = "https://files.pythonhosted.org/packages/a9/4d/5e5a60b78dbc1d464f8a7bbaeb30957257afdc8512cbb9dfd5659304f5cd/propcache-0.2.0.tar.gz", hash = "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70", size = 40951, upload-time = "2024-10-07T12:56:36.896Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/3a/08/1963dfb932b8d74d5b09098507b37e9b96c835ba89ab8aad35aa330f4ff3/propcache-0.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c5869b8fd70b81835a6f187c5fdbe67917a04d7e52b6e7cc4e5fe39d55c39d58", size = 80712, upload-time = "2024-10-07T12:54:02.193Z" }, { url = "https://files.pythonhosted.org/packages/e6/59/49072aba9bf8a8ed958e576182d46f038e595b17ff7408bc7e8807e721e1/propcache-0.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:952e0d9d07609d9c5be361f33b0d6d650cd2bae393aabb11d9b719364521984b", size = 46301, upload-time = "2024-10-07T12:54:03.576Z" }, { url = "https://files.pythonhosted.org/packages/33/a2/6b1978c2e0d80a678e2c483f45e5443c15fe5d32c483902e92a073314ef1/propcache-0.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:33ac8f098df0585c0b53009f039dfd913b38c1d2edafed0cedcc0c32a05aa110", size = 45581, upload-time = "2024-10-07T12:54:05.415Z" }, { url = "https://files.pythonhosted.org/packages/43/95/55acc9adff8f997c7572f23d41993042290dfb29e404cdadb07039a4386f/propcache-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97e48e8875e6c13909c800fa344cd54cc4b2b0db1d5f911f840458a500fde2c2", size = 208659, upload-time = "2024-10-07T12:54:06.742Z" }, { url = "https://files.pythonhosted.org/packages/bd/2c/ef7371ff715e6cd19ea03fdd5637ecefbaa0752fee5b0f2fe8ea8407ee01/propcache-0.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:388f3217649d6d59292b722d940d4d2e1e6a7003259eb835724092a1cca0203a", size = 222613, upload-time = "2024-10-07T12:54:08.204Z" }, { url = "https://files.pythonhosted.org/packages/5e/1c/fef251f79fd4971a413fa4b1ae369ee07727b4cc2c71e2d90dfcde664fbb/propcache-0.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f571aea50ba5623c308aa146eb650eebf7dbe0fd8c5d946e28343cb3b5aad577", size = 221067, upload-time = "2024-10-07T12:54:10.449Z" }, { url = "https://files.pythonhosted.org/packages/8d/e7/22e76ae6fc5a1708bdce92bdb49de5ebe89a173db87e4ef597d6bbe9145a/propcache-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3dfafb44f7bb35c0c06eda6b2ab4bfd58f02729e7c4045e179f9a861b07c9850", size = 208920, upload-time = "2024-10-07T12:54:11.903Z" }, { url = "https://files.pythonhosted.org/packages/04/3e/f10aa562781bcd8a1e0b37683a23bef32bdbe501d9cc7e76969becaac30d/propcache-0.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3ebe9a75be7ab0b7da2464a77bb27febcb4fab46a34f9288f39d74833db7f61", size = 200050, upload-time = "2024-10-07T12:54:13.292Z" }, { url = "https://files.pythonhosted.org/packages/d0/98/8ac69f638358c5f2a0043809c917802f96f86026e86726b65006830f3dc6/propcache-0.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d2f0d0f976985f85dfb5f3d685697ef769faa6b71993b46b295cdbbd6be8cc37", size = 202346, upload-time = "2024-10-07T12:54:14.644Z" }, { url = "https://files.pythonhosted.org/packages/ee/78/4acfc5544a5075d8e660af4d4e468d60c418bba93203d1363848444511ad/propcache-0.2.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a3dc1a4b165283bd865e8f8cb5f0c64c05001e0718ed06250d8cac9bec115b48", size = 199750, upload-time = "2024-10-07T12:54:16.286Z" }, { url = "https://files.pythonhosted.org/packages/a2/8f/90ada38448ca2e9cf25adc2fe05d08358bda1b9446f54a606ea38f41798b/propcache-0.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e0f07b42d2a50c7dd2d8675d50f7343d998c64008f1da5fef888396b7f84630", size = 201279, upload-time = "2024-10-07T12:54:17.752Z" }, { url = "https://files.pythonhosted.org/packages/08/31/0e299f650f73903da851f50f576ef09bfffc8e1519e6a2f1e5ed2d19c591/propcache-0.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e63e3e1e0271f374ed489ff5ee73d4b6e7c60710e1f76af5f0e1a6117cd26394", size = 211035, upload-time = "2024-10-07T12:54:19.109Z" }, { url = "https://files.pythonhosted.org/packages/85/3e/e356cc6b09064bff1c06d0b2413593e7c925726f0139bc7acef8a21e87a8/propcache-0.2.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:56bb5c98f058a41bb58eead194b4db8c05b088c93d94d5161728515bd52b052b", size = 215565, upload-time = "2024-10-07T12:54:20.578Z" }, { url = "https://files.pythonhosted.org/packages/8b/54/4ef7236cd657e53098bd05aa59cbc3cbf7018fba37b40eaed112c3921e51/propcache-0.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7665f04d0c7f26ff8bb534e1c65068409bf4687aa2534faf7104d7182debb336", size = 207604, upload-time = "2024-10-07T12:54:22.588Z" }, { url = "https://files.pythonhosted.org/packages/1f/27/d01d7799c068443ee64002f0655d82fb067496897bf74b632e28ee6a32cf/propcache-0.2.0-cp310-cp310-win32.whl", hash = "sha256:7cf18abf9764746b9c8704774d8b06714bcb0a63641518a3a89c7f85cc02c2ad", size = 40526, upload-time = "2024-10-07T12:54:23.867Z" }, { url = "https://files.pythonhosted.org/packages/bb/44/6c2add5eeafb7f31ff0d25fbc005d930bea040a1364cf0f5768750ddf4d1/propcache-0.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:cfac69017ef97db2438efb854edf24f5a29fd09a536ff3a992b75990720cdc99", size = 44958, upload-time = "2024-10-07T12:54:24.983Z" }, { url = "https://files.pythonhosted.org/packages/e0/1c/71eec730e12aec6511e702ad0cd73c2872eccb7cad39de8ba3ba9de693ef/propcache-0.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:63f13bf09cc3336eb04a837490b8f332e0db41da66995c9fd1ba04552e516354", size = 80811, upload-time = "2024-10-07T12:54:26.165Z" }, { url = "https://files.pythonhosted.org/packages/89/c3/7e94009f9a4934c48a371632197406a8860b9f08e3f7f7d922ab69e57a41/propcache-0.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608cce1da6f2672a56b24a015b42db4ac612ee709f3d29f27a00c943d9e851de", size = 46365, upload-time = "2024-10-07T12:54:28.034Z" }, { url = "https://files.pythonhosted.org/packages/c0/1d/c700d16d1d6903aeab28372fe9999762f074b80b96a0ccc953175b858743/propcache-0.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:466c219deee4536fbc83c08d09115249db301550625c7fef1c5563a584c9bc87", size = 45602, upload-time = "2024-10-07T12:54:29.148Z" }, { url = "https://files.pythonhosted.org/packages/2e/5e/4a3e96380805bf742712e39a4534689f4cddf5fa2d3a93f22e9fd8001b23/propcache-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc2db02409338bf36590aa985a461b2c96fce91f8e7e0f14c50c5fcc4f229016", size = 236161, upload-time = "2024-10-07T12:54:31.557Z" }, { url = "https://files.pythonhosted.org/packages/a5/85/90132481183d1436dff6e29f4fa81b891afb6cb89a7306f32ac500a25932/propcache-0.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6ed8db0a556343d566a5c124ee483ae113acc9a557a807d439bcecc44e7dfbb", size = 244938, upload-time = "2024-10-07T12:54:33.051Z" }, { url = "https://files.pythonhosted.org/packages/4a/89/c893533cb45c79c970834274e2d0f6d64383ec740be631b6a0a1d2b4ddc0/propcache-0.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91997d9cb4a325b60d4e3f20967f8eb08dfcb32b22554d5ef78e6fd1dda743a2", size = 243576, upload-time = "2024-10-07T12:54:34.497Z" }, { url = "https://files.pythonhosted.org/packages/8c/56/98c2054c8526331a05f205bf45cbb2cda4e58e56df70e76d6a509e5d6ec6/propcache-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c7dde9e533c0a49d802b4f3f218fa9ad0a1ce21f2c2eb80d5216565202acab4", size = 236011, upload-time = "2024-10-07T12:54:35.903Z" }, { url = "https://files.pythonhosted.org/packages/2d/0c/8b8b9f8a6e1abd869c0fa79b907228e7abb966919047d294ef5df0d136cf/propcache-0.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffcad6c564fe6b9b8916c1aefbb37a362deebf9394bd2974e9d84232e3e08504", size = 224834, upload-time = "2024-10-07T12:54:37.238Z" }, { url = "https://files.pythonhosted.org/packages/18/bb/397d05a7298b7711b90e13108db697732325cafdcd8484c894885c1bf109/propcache-0.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:97a58a28bcf63284e8b4d7b460cbee1edaab24634e82059c7b8c09e65284f178", size = 224946, upload-time = "2024-10-07T12:54:38.72Z" }, { url = "https://files.pythonhosted.org/packages/25/19/4fc08dac19297ac58135c03770b42377be211622fd0147f015f78d47cd31/propcache-0.2.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:945db8ee295d3af9dbdbb698cce9bbc5c59b5c3fe328bbc4387f59a8a35f998d", size = 217280, upload-time = "2024-10-07T12:54:40.089Z" }, { url = "https://files.pythonhosted.org/packages/7e/76/c79276a43df2096ce2aba07ce47576832b1174c0c480fe6b04bd70120e59/propcache-0.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39e104da444a34830751715f45ef9fc537475ba21b7f1f5b0f4d71a3b60d7fe2", size = 220088, upload-time = "2024-10-07T12:54:41.726Z" }, { url = "https://files.pythonhosted.org/packages/c3/9a/8a8cf428a91b1336b883f09c8b884e1734c87f724d74b917129a24fe2093/propcache-0.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c5ecca8f9bab618340c8e848d340baf68bcd8ad90a8ecd7a4524a81c1764b3db", size = 233008, upload-time = "2024-10-07T12:54:43.742Z" }, { url = "https://files.pythonhosted.org/packages/25/7b/768a8969abd447d5f0f3333df85c6a5d94982a1bc9a89c53c154bf7a8b11/propcache-0.2.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c436130cc779806bdf5d5fae0d848713105472b8566b75ff70048c47d3961c5b", size = 237719, upload-time = "2024-10-07T12:54:45.065Z" }, { url = "https://files.pythonhosted.org/packages/ed/0d/e5d68ccc7976ef8b57d80613ac07bbaf0614d43f4750cf953f0168ef114f/propcache-0.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:191db28dc6dcd29d1a3e063c3be0b40688ed76434622c53a284e5427565bbd9b", size = 227729, upload-time = "2024-10-07T12:54:46.405Z" }, { url = "https://files.pythonhosted.org/packages/05/64/17eb2796e2d1c3d0c431dc5f40078d7282f4645af0bb4da9097fbb628c6c/propcache-0.2.0-cp311-cp311-win32.whl", hash = "sha256:5f2564ec89058ee7c7989a7b719115bdfe2a2fb8e7a4543b8d1c0cc4cf6478c1", size = 40473, upload-time = "2024-10-07T12:54:47.694Z" }, { url = "https://files.pythonhosted.org/packages/83/c5/e89fc428ccdc897ade08cd7605f174c69390147526627a7650fb883e0cd0/propcache-0.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e2e54267980349b723cff366d1e29b138b9a60fa376664a157a342689553f71", size = 44921, upload-time = "2024-10-07T12:54:48.935Z" }, { url = "https://files.pythonhosted.org/packages/7c/46/a41ca1097769fc548fc9216ec4c1471b772cc39720eb47ed7e38ef0006a9/propcache-0.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2", size = 80800, upload-time = "2024-10-07T12:54:50.409Z" }, { url = "https://files.pythonhosted.org/packages/75/4f/93df46aab9cc473498ff56be39b5f6ee1e33529223d7a4d8c0a6101a9ba2/propcache-0.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7", size = 46443, upload-time = "2024-10-07T12:54:51.634Z" }, { url = "https://files.pythonhosted.org/packages/0b/17/308acc6aee65d0f9a8375e36c4807ac6605d1f38074b1581bd4042b9fb37/propcache-0.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8", size = 45676, upload-time = "2024-10-07T12:54:53.454Z" }, { url = "https://files.pythonhosted.org/packages/65/44/626599d2854d6c1d4530b9a05e7ff2ee22b790358334b475ed7c89f7d625/propcache-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793", size = 246191, upload-time = "2024-10-07T12:54:55.438Z" }, { url = "https://files.pythonhosted.org/packages/f2/df/5d996d7cb18df076debae7d76ac3da085c0575a9f2be6b1f707fe227b54c/propcache-0.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09", size = 251791, upload-time = "2024-10-07T12:54:57.441Z" }, { url = "https://files.pythonhosted.org/packages/2e/6d/9f91e5dde8b1f662f6dd4dff36098ed22a1ef4e08e1316f05f4758f1576c/propcache-0.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89", size = 253434, upload-time = "2024-10-07T12:54:58.857Z" }, { url = "https://files.pythonhosted.org/packages/3c/e9/1b54b7e26f50b3e0497cd13d3483d781d284452c2c50dd2a615a92a087a3/propcache-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e", size = 248150, upload-time = "2024-10-07T12:55:00.19Z" }, { url = "https://files.pythonhosted.org/packages/a7/ef/a35bf191c8038fe3ce9a414b907371c81d102384eda5dbafe6f4dce0cf9b/propcache-0.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9", size = 233568, upload-time = "2024-10-07T12:55:01.723Z" }, { url = "https://files.pythonhosted.org/packages/97/d9/d00bb9277a9165a5e6d60f2142cd1a38a750045c9c12e47ae087f686d781/propcache-0.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4", size = 229874, upload-time = "2024-10-07T12:55:03.962Z" }, { url = "https://files.pythonhosted.org/packages/8e/78/c123cf22469bdc4b18efb78893e69c70a8b16de88e6160b69ca6bdd88b5d/propcache-0.2.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c", size = 225857, upload-time = "2024-10-07T12:55:06.439Z" }, { url = "https://files.pythonhosted.org/packages/31/1b/fd6b2f1f36d028820d35475be78859d8c89c8f091ad30e377ac49fd66359/propcache-0.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887", size = 227604, upload-time = "2024-10-07T12:55:08.254Z" }, { url = "https://files.pythonhosted.org/packages/99/36/b07be976edf77a07233ba712e53262937625af02154353171716894a86a6/propcache-0.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57", size = 238430, upload-time = "2024-10-07T12:55:09.766Z" }, { url = "https://files.pythonhosted.org/packages/0d/64/5822f496c9010e3966e934a011ac08cac8734561842bc7c1f65586e0683c/propcache-0.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23", size = 244814, upload-time = "2024-10-07T12:55:11.145Z" }, { url = "https://files.pythonhosted.org/packages/fd/bd/8657918a35d50b18a9e4d78a5df7b6c82a637a311ab20851eef4326305c1/propcache-0.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348", size = 235922, upload-time = "2024-10-07T12:55:12.508Z" }, { url = "https://files.pythonhosted.org/packages/a8/6f/ec0095e1647b4727db945213a9f395b1103c442ef65e54c62e92a72a3f75/propcache-0.2.0-cp312-cp312-win32.whl", hash = "sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5", size = 40177, upload-time = "2024-10-07T12:55:13.814Z" }, { url = "https://files.pythonhosted.org/packages/20/a2/bd0896fdc4f4c1db46d9bc361c8c79a9bf08ccc08ba054a98e38e7ba1557/propcache-0.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3", size = 44446, upload-time = "2024-10-07T12:55:14.972Z" }, { url = "https://files.pythonhosted.org/packages/a8/a7/5f37b69197d4f558bfef5b4bceaff7c43cc9b51adf5bd75e9081d7ea80e4/propcache-0.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ecddc221a077a8132cf7c747d5352a15ed763b674c0448d811f408bf803d9ad7", size = 78120, upload-time = "2024-10-07T12:55:16.179Z" }, { url = "https://files.pythonhosted.org/packages/c8/cd/48ab2b30a6b353ecb95a244915f85756d74f815862eb2ecc7a518d565b48/propcache-0.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0e53cb83fdd61cbd67202735e6a6687a7b491c8742dfc39c9e01e80354956763", size = 45127, upload-time = "2024-10-07T12:55:18.275Z" }, { url = "https://files.pythonhosted.org/packages/a5/ba/0a1ef94a3412aab057bd996ed5f0ac7458be5bf469e85c70fa9ceb43290b/propcache-0.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92fe151145a990c22cbccf9ae15cae8ae9eddabfc949a219c9f667877e40853d", size = 44419, upload-time = "2024-10-07T12:55:19.487Z" }, { url = "https://files.pythonhosted.org/packages/b4/6c/ca70bee4f22fa99eacd04f4d2f1699be9d13538ccf22b3169a61c60a27fa/propcache-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a21ef516d36909931a2967621eecb256018aeb11fc48656e3257e73e2e247a", size = 229611, upload-time = "2024-10-07T12:55:21.377Z" }, { url = "https://files.pythonhosted.org/packages/19/70/47b872a263e8511ca33718d96a10c17d3c853aefadeb86dc26e8421184b9/propcache-0.2.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f88a4095e913f98988f5b338c1d4d5d07dbb0b6bad19892fd447484e483ba6b", size = 234005, upload-time = "2024-10-07T12:55:22.898Z" }, { url = "https://files.pythonhosted.org/packages/4f/be/3b0ab8c84a22e4a3224719099c1229ddfdd8a6a1558cf75cb55ee1e35c25/propcache-0.2.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a5b3bb545ead161be780ee85a2b54fdf7092815995661947812dde94a40f6fb", size = 237270, upload-time = "2024-10-07T12:55:24.354Z" }, { url = "https://files.pythonhosted.org/packages/04/d8/f071bb000d4b8f851d312c3c75701e586b3f643fe14a2e3409b1b9ab3936/propcache-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67aeb72e0f482709991aa91345a831d0b707d16b0257e8ef88a2ad246a7280bf", size = 231877, upload-time = "2024-10-07T12:55:25.774Z" }, { url = "https://files.pythonhosted.org/packages/93/e7/57a035a1359e542bbb0a7df95aad6b9871ebee6dce2840cb157a415bd1f3/propcache-0.2.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c997f8c44ec9b9b0bcbf2d422cc00a1d9b9c681f56efa6ca149a941e5560da2", size = 217848, upload-time = "2024-10-07T12:55:27.148Z" }, { url = "https://files.pythonhosted.org/packages/f0/93/d1dea40f112ec183398fb6c42fde340edd7bab202411c4aa1a8289f461b6/propcache-0.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2a66df3d4992bc1d725b9aa803e8c5a66c010c65c741ad901e260ece77f58d2f", size = 216987, upload-time = "2024-10-07T12:55:29.294Z" }, { url = "https://files.pythonhosted.org/packages/62/4c/877340871251145d3522c2b5d25c16a1690ad655fbab7bb9ece6b117e39f/propcache-0.2.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3ebbcf2a07621f29638799828b8d8668c421bfb94c6cb04269130d8de4fb7136", size = 212451, upload-time = "2024-10-07T12:55:30.643Z" }, { url = "https://files.pythonhosted.org/packages/7c/bb/a91b72efeeb42906ef58ccf0cdb87947b54d7475fee3c93425d732f16a61/propcache-0.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1235c01ddaa80da8235741e80815ce381c5267f96cc49b1477fdcf8c047ef325", size = 212879, upload-time = "2024-10-07T12:55:32.024Z" }, { url = "https://files.pythonhosted.org/packages/9b/7f/ee7fea8faac57b3ec5d91ff47470c6c5d40d7f15d0b1fccac806348fa59e/propcache-0.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3947483a381259c06921612550867b37d22e1df6d6d7e8361264b6d037595f44", size = 222288, upload-time = "2024-10-07T12:55:33.401Z" }, { url = "https://files.pythonhosted.org/packages/ff/d7/acd67901c43d2e6b20a7a973d9d5fd543c6e277af29b1eb0e1f7bd7ca7d2/propcache-0.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d5bed7f9805cc29c780f3aee05de3262ee7ce1f47083cfe9f77471e9d6777e83", size = 228257, upload-time = "2024-10-07T12:55:35.381Z" }, { url = "https://files.pythonhosted.org/packages/8d/6f/6272ecc7a8daad1d0754cfc6c8846076a8cb13f810005c79b15ce0ef0cf2/propcache-0.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4a91d44379f45f5e540971d41e4626dacd7f01004826a18cb048e7da7e96544", size = 221075, upload-time = "2024-10-07T12:55:36.789Z" }, { url = "https://files.pythonhosted.org/packages/7c/bd/c7a6a719a6b3dd8b3aeadb3675b5783983529e4a3185946aa444d3e078f6/propcache-0.2.0-cp313-cp313-win32.whl", hash = "sha256:f902804113e032e2cdf8c71015651c97af6418363bea8d78dc0911d56c335032", size = 39654, upload-time = "2024-10-07T12:55:38.762Z" }, { url = "https://files.pythonhosted.org/packages/88/e7/0eef39eff84fa3e001b44de0bd41c7c0e3432e7648ffd3d64955910f002d/propcache-0.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:8f188cfcc64fb1266f4684206c9de0e80f54622c3f22a910cbd200478aeae61e", size = 43705, upload-time = "2024-10-07T12:55:39.921Z" }, { url = "https://files.pythonhosted.org/packages/b4/94/2c3d64420fd58ed462e2b416386d48e72dec027cf7bb572066cf3866e939/propcache-0.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:53d1bd3f979ed529f0805dd35ddaca330f80a9a6d90bc0121d2ff398f8ed8861", size = 82315, upload-time = "2024-10-07T12:55:41.166Z" }, { url = "https://files.pythonhosted.org/packages/73/b7/9e2a17d9a126f2012b22ddc5d0979c28ca75104e24945214790c1d787015/propcache-0.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:83928404adf8fb3d26793665633ea79b7361efa0287dfbd372a7e74311d51ee6", size = 47188, upload-time = "2024-10-07T12:55:42.316Z" }, { url = "https://files.pythonhosted.org/packages/80/ef/18af27caaae5589c08bb5a461cfa136b83b7e7983be604f2140d91f92b97/propcache-0.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:77a86c261679ea5f3896ec060be9dc8e365788248cc1e049632a1be682442063", size = 46314, upload-time = "2024-10-07T12:55:43.544Z" }, { url = "https://files.pythonhosted.org/packages/fa/df/8dbd3e472baf73251c0fbb571a3f0a4e3a40c52a1c8c2a6c46ab08736ff9/propcache-0.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:218db2a3c297a3768c11a34812e63b3ac1c3234c3a086def9c0fee50d35add1f", size = 212874, upload-time = "2024-10-07T12:55:44.823Z" }, { url = "https://files.pythonhosted.org/packages/7c/57/5d4d783ac594bd56434679b8643673ae12de1ce758116fd8912a7f2313ec/propcache-0.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7735e82e3498c27bcb2d17cb65d62c14f1100b71723b68362872bca7d0913d90", size = 224578, upload-time = "2024-10-07T12:55:46.253Z" }, { url = "https://files.pythonhosted.org/packages/66/27/072be8ad434c9a3aa1b561f527984ea0ed4ac072fd18dfaaa2aa2d6e6a2b/propcache-0.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:20a617c776f520c3875cf4511e0d1db847a076d720714ae35ffe0df3e440be68", size = 222636, upload-time = "2024-10-07T12:55:47.608Z" }, { url = "https://files.pythonhosted.org/packages/c3/f1/69a30ff0928d07f50bdc6f0147fd9a08e80904fd3fdb711785e518de1021/propcache-0.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67b69535c870670c9f9b14a75d28baa32221d06f6b6fa6f77a0a13c5a7b0a5b9", size = 213573, upload-time = "2024-10-07T12:55:49.82Z" }, { url = "https://files.pythonhosted.org/packages/a8/2e/c16716ae113fe0a3219978df3665a6fea049d81d50bd28c4ae72a4c77567/propcache-0.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4569158070180c3855e9c0791c56be3ceeb192defa2cdf6a3f39e54319e56b89", size = 205438, upload-time = "2024-10-07T12:55:51.231Z" }, { url = "https://files.pythonhosted.org/packages/e1/df/80e2c5cd5ed56a7bfb1aa58cedb79617a152ae43de7c0a7e800944a6b2e2/propcache-0.2.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:db47514ffdbd91ccdc7e6f8407aac4ee94cc871b15b577c1c324236b013ddd04", size = 202352, upload-time = "2024-10-07T12:55:52.596Z" }, { url = "https://files.pythonhosted.org/packages/0f/4e/79f665fa04839f30ffb2903211c718b9660fbb938ac7a4df79525af5aeb3/propcache-0.2.0-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:2a60ad3e2553a74168d275a0ef35e8c0a965448ffbc3b300ab3a5bb9956c2162", size = 200476, upload-time = "2024-10-07T12:55:54.016Z" }, { url = "https://files.pythonhosted.org/packages/a9/39/b9ea7b011521dd7cfd2f89bb6b8b304f3c789ea6285445bc145bebc83094/propcache-0.2.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:662dd62358bdeaca0aee5761de8727cfd6861432e3bb828dc2a693aa0471a563", size = 201581, upload-time = "2024-10-07T12:55:56.246Z" }, { url = "https://files.pythonhosted.org/packages/e4/81/e8e96c97aa0b675a14e37b12ca9c9713b15cfacf0869e64bf3ab389fabf1/propcache-0.2.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:25a1f88b471b3bc911d18b935ecb7115dff3a192b6fef46f0bfaf71ff4f12418", size = 225628, upload-time = "2024-10-07T12:55:57.686Z" }, { url = "https://files.pythonhosted.org/packages/eb/99/15f998c502c214f6c7f51462937605d514a8943a9a6c1fa10f40d2710976/propcache-0.2.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:f60f0ac7005b9f5a6091009b09a419ace1610e163fa5deaba5ce3484341840e7", size = 229270, upload-time = "2024-10-07T12:55:59.065Z" }, { url = "https://files.pythonhosted.org/packages/ff/3a/a9f1a0c0e5b994b8f1a1c71bea56bb3e9eeec821cb4dd61e14051c4ba00b/propcache-0.2.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:74acd6e291f885678631b7ebc85d2d4aec458dd849b8c841b57ef04047833bed", size = 207771, upload-time = "2024-10-07T12:56:00.393Z" }, { url = "https://files.pythonhosted.org/packages/ff/3e/6103906a66d6713f32880cf6a5ba84a1406b4d66e1b9389bb9b8e1789f9e/propcache-0.2.0-cp38-cp38-win32.whl", hash = "sha256:d9b6ddac6408194e934002a69bcaadbc88c10b5f38fb9307779d1c629181815d", size = 41015, upload-time = "2024-10-07T12:56:01.953Z" }, { url = "https://files.pythonhosted.org/packages/37/23/a30214b4c1f2bea24cc1197ef48d67824fbc41d5cf5472b17c37fef6002c/propcache-0.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:676135dcf3262c9c5081cc8f19ad55c8a64e3f7282a21266d05544450bffc3a5", size = 45749, upload-time = "2024-10-07T12:56:03.095Z" }, { url = "https://files.pythonhosted.org/packages/38/05/797e6738c9f44ab5039e3ff329540c934eabbe8ad7e63c305c75844bc86f/propcache-0.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:25c8d773a62ce0451b020c7b29a35cfbc05de8b291163a7a0f3b7904f27253e6", size = 81903, upload-time = "2024-10-07T12:56:04.651Z" }, { url = "https://files.pythonhosted.org/packages/9f/84/8d5edb9a73e1a56b24dd8f2adb6aac223109ff0e8002313d52e5518258ba/propcache-0.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:375a12d7556d462dc64d70475a9ee5982465fbb3d2b364f16b86ba9135793638", size = 46960, upload-time = "2024-10-07T12:56:06.38Z" }, { url = "https://files.pythonhosted.org/packages/e7/77/388697bedda984af0d12d68e536b98129b167282da3401965c8450de510e/propcache-0.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1ec43d76b9677637a89d6ab86e1fef70d739217fefa208c65352ecf0282be957", size = 46133, upload-time = "2024-10-07T12:56:07.606Z" }, { url = "https://files.pythonhosted.org/packages/e2/dc/60d444610bc5b1d7a758534f58362b1bcee736a785473f8a39c91f05aad1/propcache-0.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f45eec587dafd4b2d41ac189c2156461ebd0c1082d2fe7013571598abb8505d1", size = 211105, upload-time = "2024-10-07T12:56:08.826Z" }, { url = "https://files.pythonhosted.org/packages/bc/c6/40eb0dd1de6f8e84f454615ab61f68eb4a58f9d63d6f6eaf04300ac0cc17/propcache-0.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc092ba439d91df90aea38168e11f75c655880c12782facf5cf9c00f3d42b562", size = 226613, upload-time = "2024-10-07T12:56:11.184Z" }, { url = "https://files.pythonhosted.org/packages/de/b6/e078b5e9de58e20db12135eb6a206b4b43cb26c6b62ee0fe36ac40763a64/propcache-0.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa1076244f54bb76e65e22cb6910365779d5c3d71d1f18b275f1dfc7b0d71b4d", size = 225587, upload-time = "2024-10-07T12:56:15.294Z" }, { url = "https://files.pythonhosted.org/packages/ce/4e/97059dd24494d1c93d1efb98bb24825e1930265b41858dd59c15cb37a975/propcache-0.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:682a7c79a2fbf40f5dbb1eb6bfe2cd865376deeac65acf9beb607505dced9e12", size = 211826, upload-time = "2024-10-07T12:56:16.997Z" }, { url = "https://files.pythonhosted.org/packages/fc/23/4dbf726602a989d2280fe130a9b9dd71faa8d3bb8cd23d3261ff3c23f692/propcache-0.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e40876731f99b6f3c897b66b803c9e1c07a989b366c6b5b475fafd1f7ba3fb8", size = 203140, upload-time = "2024-10-07T12:56:18.368Z" }, { url = "https://files.pythonhosted.org/packages/5b/ce/f3bff82c885dbd9ae9e43f134d5b02516c3daa52d46f7a50e4f52ef9121f/propcache-0.2.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:363ea8cd3c5cb6679f1c2f5f1f9669587361c062e4899fce56758efa928728f8", size = 208841, upload-time = "2024-10-07T12:56:19.859Z" }, { url = "https://files.pythonhosted.org/packages/29/d7/19a4d3b4c7e95d08f216da97035d0b103d0c90411c6f739d47088d2da1f0/propcache-0.2.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:140fbf08ab3588b3468932974a9331aff43c0ab8a2ec2c608b6d7d1756dbb6cb", size = 203315, upload-time = "2024-10-07T12:56:21.256Z" }, { url = "https://files.pythonhosted.org/packages/db/87/5748212a18beb8d4ab46315c55ade8960d1e2cdc190764985b2d229dd3f4/propcache-0.2.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e70fac33e8b4ac63dfc4c956fd7d85a0b1139adcfc0d964ce288b7c527537fea", size = 204724, upload-time = "2024-10-07T12:56:23.644Z" }, { url = "https://files.pythonhosted.org/packages/84/2a/c3d2f989fc571a5bad0fabcd970669ccb08c8f9b07b037ecddbdab16a040/propcache-0.2.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:b33d7a286c0dc1a15f5fc864cc48ae92a846df287ceac2dd499926c3801054a6", size = 215514, upload-time = "2024-10-07T12:56:25.733Z" }, { url = "https://files.pythonhosted.org/packages/c9/1f/4c44c133b08bc5f776afcb8f0833889c2636b8a83e07ea1d9096c1e401b0/propcache-0.2.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:f6d5749fdd33d90e34c2efb174c7e236829147a2713334d708746e94c4bde40d", size = 220063, upload-time = "2024-10-07T12:56:28.497Z" }, { url = "https://files.pythonhosted.org/packages/2e/25/280d0a3bdaee68db74c0acd9a472e59e64b516735b59cffd3a326ff9058a/propcache-0.2.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22aa8f2272d81d9317ff5756bb108021a056805ce63dd3630e27d042c8092798", size = 211620, upload-time = "2024-10-07T12:56:29.891Z" }, { url = "https://files.pythonhosted.org/packages/28/8c/266898981b7883c1563c35954f9ce9ced06019fdcc487a9520150c48dc91/propcache-0.2.0-cp39-cp39-win32.whl", hash = "sha256:73e4b40ea0eda421b115248d7e79b59214411109a5bc47d0d48e4c73e3b8fcf9", size = 41049, upload-time = "2024-10-07T12:56:31.246Z" }, { url = "https://files.pythonhosted.org/packages/af/53/a3e5b937f58e757a940716b88105ec4c211c42790c1ea17052b46dc16f16/propcache-0.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:9517d5e9e0731957468c29dbfd0f976736a0e55afaea843726e887f36fe017df", size = 45587, upload-time = "2024-10-07T12:56:33.416Z" }, { url = "https://files.pythonhosted.org/packages/3d/b6/e6d98278f2d49b22b4d033c9f792eda783b9ab2094b041f013fc69bcde87/propcache-0.2.0-py3-none-any.whl", hash = "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036", size = 11603, upload-time = "2024-10-07T12:56:35.137Z" }, ] [[package]] name = "propcache" version = "0.3.2" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.10'", "python_full_version == '3.9.*'", ] sdist = { url = "https://files.pythonhosted.org/packages/a6/16/43264e4a779dd8588c21a70f0709665ee8f611211bdd2c87d952cfa7c776/propcache-0.3.2.tar.gz", hash = "sha256:20d7d62e4e7ef05f221e0db2856b979540686342e7dd9973b815599c7057e168", size = 44139, upload-time = "2025-06-09T22:56:06.081Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ab/14/510deed325e262afeb8b360043c5d7c960da7d3ecd6d6f9496c9c56dc7f4/propcache-0.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:22d9962a358aedbb7a2e36187ff273adeaab9743373a272976d2e348d08c7770", size = 73178, upload-time = "2025-06-09T22:53:40.126Z" }, { url = "https://files.pythonhosted.org/packages/cd/4e/ad52a7925ff01c1325653a730c7ec3175a23f948f08626a534133427dcff/propcache-0.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0d0fda578d1dc3f77b6b5a5dce3b9ad69a8250a891760a548df850a5e8da87f3", size = 43133, upload-time = "2025-06-09T22:53:41.965Z" }, { url = "https://files.pythonhosted.org/packages/63/7c/e9399ba5da7780871db4eac178e9c2e204c23dd3e7d32df202092a1ed400/propcache-0.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3def3da3ac3ce41562d85db655d18ebac740cb3fa4367f11a52b3da9d03a5cc3", size = 43039, upload-time = "2025-06-09T22:53:43.268Z" }, { url = "https://files.pythonhosted.org/packages/22/e1/58da211eb8fdc6fc854002387d38f415a6ca5f5c67c1315b204a5d3e9d7a/propcache-0.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9bec58347a5a6cebf239daba9bda37dffec5b8d2ce004d9fe4edef3d2815137e", size = 201903, upload-time = "2025-06-09T22:53:44.872Z" }, { url = "https://files.pythonhosted.org/packages/c4/0a/550ea0f52aac455cb90111c8bab995208443e46d925e51e2f6ebdf869525/propcache-0.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55ffda449a507e9fbd4aca1a7d9aa6753b07d6166140e5a18d2ac9bc49eac220", size = 213362, upload-time = "2025-06-09T22:53:46.707Z" }, { url = "https://files.pythonhosted.org/packages/5a/af/9893b7d878deda9bb69fcf54600b247fba7317761b7db11fede6e0f28bd0/propcache-0.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64a67fb39229a8a8491dd42f864e5e263155e729c2e7ff723d6e25f596b1e8cb", size = 210525, upload-time = "2025-06-09T22:53:48.547Z" }, { url = "https://files.pythonhosted.org/packages/7c/bb/38fd08b278ca85cde36d848091ad2b45954bc5f15cce494bb300b9285831/propcache-0.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9da1cf97b92b51253d5b68cf5a2b9e0dafca095e36b7f2da335e27dc6172a614", size = 198283, upload-time = "2025-06-09T22:53:50.067Z" }, { url = "https://files.pythonhosted.org/packages/78/8c/9fe55bd01d362bafb413dfe508c48753111a1e269737fa143ba85693592c/propcache-0.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5f559e127134b07425134b4065be45b166183fdcb433cb6c24c8e4149056ad50", size = 191872, upload-time = "2025-06-09T22:53:51.438Z" }, { url = "https://files.pythonhosted.org/packages/54/14/4701c33852937a22584e08abb531d654c8bcf7948a8f87ad0a4822394147/propcache-0.3.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:aff2e4e06435d61f11a428360a932138d0ec288b0a31dd9bd78d200bd4a2b339", size = 199452, upload-time = "2025-06-09T22:53:53.229Z" }, { url = "https://files.pythonhosted.org/packages/16/44/447f2253d859602095356007657ee535e0093215ea0b3d1d6a41d16e5201/propcache-0.3.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:4927842833830942a5d0a56e6f4839bc484785b8e1ce8d287359794818633ba0", size = 191567, upload-time = "2025-06-09T22:53:54.541Z" }, { url = "https://files.pythonhosted.org/packages/f2/b3/e4756258749bb2d3b46defcff606a2f47410bab82be5824a67e84015b267/propcache-0.3.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:6107ddd08b02654a30fb8ad7a132021759d750a82578b94cd55ee2772b6ebea2", size = 193015, upload-time = "2025-06-09T22:53:56.44Z" }, { url = "https://files.pythonhosted.org/packages/1e/df/e6d3c7574233164b6330b9fd697beeac402afd367280e6dc377bb99b43d9/propcache-0.3.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:70bd8b9cd6b519e12859c99f3fc9a93f375ebd22a50296c3a295028bea73b9e7", size = 204660, upload-time = "2025-06-09T22:53:57.839Z" }, { url = "https://files.pythonhosted.org/packages/b2/53/e4d31dd5170b4a0e2e6b730f2385a96410633b4833dc25fe5dffd1f73294/propcache-0.3.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2183111651d710d3097338dd1893fcf09c9f54e27ff1a8795495a16a469cc90b", size = 206105, upload-time = "2025-06-09T22:53:59.638Z" }, { url = "https://files.pythonhosted.org/packages/7f/fe/74d54cf9fbe2a20ff786e5f7afcfde446588f0cf15fb2daacfbc267b866c/propcache-0.3.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fb075ad271405dcad8e2a7ffc9a750a3bf70e533bd86e89f0603e607b93aa64c", size = 196980, upload-time = "2025-06-09T22:54:01.071Z" }, { url = "https://files.pythonhosted.org/packages/22/ec/c469c9d59dada8a7679625e0440b544fe72e99311a4679c279562051f6fc/propcache-0.3.2-cp310-cp310-win32.whl", hash = "sha256:404d70768080d3d3bdb41d0771037da19d8340d50b08e104ca0e7f9ce55fce70", size = 37679, upload-time = "2025-06-09T22:54:03.003Z" }, { url = "https://files.pythonhosted.org/packages/38/35/07a471371ac89d418f8d0b699c75ea6dca2041fbda360823de21f6a9ce0a/propcache-0.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:7435d766f978b4ede777002e6b3b6641dd229cd1da8d3d3106a45770365f9ad9", size = 41459, upload-time = "2025-06-09T22:54:04.134Z" }, { url = "https://files.pythonhosted.org/packages/80/8d/e8b436717ab9c2cfc23b116d2c297305aa4cd8339172a456d61ebf5669b8/propcache-0.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0b8d2f607bd8f80ddc04088bc2a037fdd17884a6fcadc47a96e334d72f3717be", size = 74207, upload-time = "2025-06-09T22:54:05.399Z" }, { url = "https://files.pythonhosted.org/packages/d6/29/1e34000e9766d112171764b9fa3226fa0153ab565d0c242c70e9945318a7/propcache-0.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06766d8f34733416e2e34f46fea488ad5d60726bb9481d3cddf89a6fa2d9603f", size = 43648, upload-time = "2025-06-09T22:54:08.023Z" }, { url = "https://files.pythonhosted.org/packages/46/92/1ad5af0df781e76988897da39b5f086c2bf0f028b7f9bd1f409bb05b6874/propcache-0.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2dc1f4a1df4fecf4e6f68013575ff4af84ef6f478fe5344317a65d38a8e6dc9", size = 43496, upload-time = "2025-06-09T22:54:09.228Z" }, { url = "https://files.pythonhosted.org/packages/b3/ce/e96392460f9fb68461fabab3e095cb00c8ddf901205be4eae5ce246e5b7e/propcache-0.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be29c4f4810c5789cf10ddf6af80b041c724e629fa51e308a7a0fb19ed1ef7bf", size = 217288, upload-time = "2025-06-09T22:54:10.466Z" }, { url = "https://files.pythonhosted.org/packages/c5/2a/866726ea345299f7ceefc861a5e782b045545ae6940851930a6adaf1fca6/propcache-0.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59d61f6970ecbd8ff2e9360304d5c8876a6abd4530cb752c06586849ac8a9dc9", size = 227456, upload-time = "2025-06-09T22:54:11.828Z" }, { url = "https://files.pythonhosted.org/packages/de/03/07d992ccb6d930398689187e1b3c718339a1c06b8b145a8d9650e4726166/propcache-0.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:62180e0b8dbb6b004baec00a7983e4cc52f5ada9cd11f48c3528d8cfa7b96a66", size = 225429, upload-time = "2025-06-09T22:54:13.823Z" }, { url = "https://files.pythonhosted.org/packages/5d/e6/116ba39448753b1330f48ab8ba927dcd6cf0baea8a0ccbc512dfb49ba670/propcache-0.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c144ca294a204c470f18cf4c9d78887810d04a3e2fbb30eea903575a779159df", size = 213472, upload-time = "2025-06-09T22:54:15.232Z" }, { url = "https://files.pythonhosted.org/packages/a6/85/f01f5d97e54e428885a5497ccf7f54404cbb4f906688a1690cd51bf597dc/propcache-0.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5c2a784234c28854878d68978265617aa6dc0780e53d44b4d67f3651a17a9a2", size = 204480, upload-time = "2025-06-09T22:54:17.104Z" }, { url = "https://files.pythonhosted.org/packages/e3/79/7bf5ab9033b8b8194cc3f7cf1aaa0e9c3256320726f64a3e1f113a812dce/propcache-0.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5745bc7acdafa978ca1642891b82c19238eadc78ba2aaa293c6863b304e552d7", size = 214530, upload-time = "2025-06-09T22:54:18.512Z" }, { url = "https://files.pythonhosted.org/packages/31/0b/bd3e0c00509b609317df4a18e6b05a450ef2d9a963e1d8bc9c9415d86f30/propcache-0.3.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:c0075bf773d66fa8c9d41f66cc132ecc75e5bb9dd7cce3cfd14adc5ca184cb95", size = 205230, upload-time = "2025-06-09T22:54:19.947Z" }, { url = "https://files.pythonhosted.org/packages/7a/23/fae0ff9b54b0de4e819bbe559508da132d5683c32d84d0dc2ccce3563ed4/propcache-0.3.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5f57aa0847730daceff0497f417c9de353c575d8da3579162cc74ac294c5369e", size = 206754, upload-time = "2025-06-09T22:54:21.716Z" }, { url = "https://files.pythonhosted.org/packages/b7/7f/ad6a3c22630aaa5f618b4dc3c3598974a72abb4c18e45a50b3cdd091eb2f/propcache-0.3.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:eef914c014bf72d18efb55619447e0aecd5fb7c2e3fa7441e2e5d6099bddff7e", size = 218430, upload-time = "2025-06-09T22:54:23.17Z" }, { url = "https://files.pythonhosted.org/packages/5b/2c/ba4f1c0e8a4b4c75910742f0d333759d441f65a1c7f34683b4a74c0ee015/propcache-0.3.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2a4092e8549031e82facf3decdbc0883755d5bbcc62d3aea9d9e185549936dcf", size = 223884, upload-time = "2025-06-09T22:54:25.539Z" }, { url = "https://files.pythonhosted.org/packages/88/e4/ebe30fc399e98572019eee82ad0caf512401661985cbd3da5e3140ffa1b0/propcache-0.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:85871b050f174bc0bfb437efbdb68aaf860611953ed12418e4361bc9c392749e", size = 211480, upload-time = "2025-06-09T22:54:26.892Z" }, { url = "https://files.pythonhosted.org/packages/96/0a/7d5260b914e01d1d0906f7f38af101f8d8ed0dc47426219eeaf05e8ea7c2/propcache-0.3.2-cp311-cp311-win32.whl", hash = "sha256:36c8d9b673ec57900c3554264e630d45980fd302458e4ac801802a7fd2ef7897", size = 37757, upload-time = "2025-06-09T22:54:28.241Z" }, { url = "https://files.pythonhosted.org/packages/e1/2d/89fe4489a884bc0da0c3278c552bd4ffe06a1ace559db5ef02ef24ab446b/propcache-0.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:e53af8cb6a781b02d2ea079b5b853ba9430fcbe18a8e3ce647d5982a3ff69f39", size = 41500, upload-time = "2025-06-09T22:54:29.4Z" }, { url = "https://files.pythonhosted.org/packages/a8/42/9ca01b0a6f48e81615dca4765a8f1dd2c057e0540f6116a27dc5ee01dfb6/propcache-0.3.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8de106b6c84506b31c27168582cd3cb3000a6412c16df14a8628e5871ff83c10", size = 73674, upload-time = "2025-06-09T22:54:30.551Z" }, { url = "https://files.pythonhosted.org/packages/af/6e/21293133beb550f9c901bbece755d582bfaf2176bee4774000bd4dd41884/propcache-0.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:28710b0d3975117239c76600ea351934ac7b5ff56e60953474342608dbbb6154", size = 43570, upload-time = "2025-06-09T22:54:32.296Z" }, { url = "https://files.pythonhosted.org/packages/0c/c8/0393a0a3a2b8760eb3bde3c147f62b20044f0ddac81e9d6ed7318ec0d852/propcache-0.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce26862344bdf836650ed2487c3d724b00fbfec4233a1013f597b78c1cb73615", size = 43094, upload-time = "2025-06-09T22:54:33.929Z" }, { url = "https://files.pythonhosted.org/packages/37/2c/489afe311a690399d04a3e03b069225670c1d489eb7b044a566511c1c498/propcache-0.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bca54bd347a253af2cf4544bbec232ab982f4868de0dd684246b67a51bc6b1db", size = 226958, upload-time = "2025-06-09T22:54:35.186Z" }, { url = "https://files.pythonhosted.org/packages/9d/ca/63b520d2f3d418c968bf596839ae26cf7f87bead026b6192d4da6a08c467/propcache-0.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55780d5e9a2ddc59711d727226bb1ba83a22dd32f64ee15594b9392b1f544eb1", size = 234894, upload-time = "2025-06-09T22:54:36.708Z" }, { url = "https://files.pythonhosted.org/packages/11/60/1d0ed6fff455a028d678df30cc28dcee7af77fa2b0e6962ce1df95c9a2a9/propcache-0.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:035e631be25d6975ed87ab23153db6a73426a48db688070d925aa27e996fe93c", size = 233672, upload-time = "2025-06-09T22:54:38.062Z" }, { url = "https://files.pythonhosted.org/packages/37/7c/54fd5301ef38505ab235d98827207176a5c9b2aa61939b10a460ca53e123/propcache-0.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee6f22b6eaa39297c751d0e80c0d3a454f112f5c6481214fcf4c092074cecd67", size = 224395, upload-time = "2025-06-09T22:54:39.634Z" }, { url = "https://files.pythonhosted.org/packages/ee/1a/89a40e0846f5de05fdc6779883bf46ba980e6df4d2ff8fb02643de126592/propcache-0.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ca3aee1aa955438c4dba34fc20a9f390e4c79967257d830f137bd5a8a32ed3b", size = 212510, upload-time = "2025-06-09T22:54:41.565Z" }, { url = "https://files.pythonhosted.org/packages/5e/33/ca98368586c9566a6b8d5ef66e30484f8da84c0aac3f2d9aec6d31a11bd5/propcache-0.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7a4f30862869fa2b68380d677cc1c5fcf1e0f2b9ea0cf665812895c75d0ca3b8", size = 222949, upload-time = "2025-06-09T22:54:43.038Z" }, { url = "https://files.pythonhosted.org/packages/ba/11/ace870d0aafe443b33b2f0b7efdb872b7c3abd505bfb4890716ad7865e9d/propcache-0.3.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:b77ec3c257d7816d9f3700013639db7491a434644c906a2578a11daf13176251", size = 217258, upload-time = "2025-06-09T22:54:44.376Z" }, { url = "https://files.pythonhosted.org/packages/5b/d2/86fd6f7adffcfc74b42c10a6b7db721d1d9ca1055c45d39a1a8f2a740a21/propcache-0.3.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:cab90ac9d3f14b2d5050928483d3d3b8fb6b4018893fc75710e6aa361ecb2474", size = 213036, upload-time = "2025-06-09T22:54:46.243Z" }, { url = "https://files.pythonhosted.org/packages/07/94/2d7d1e328f45ff34a0a284cf5a2847013701e24c2a53117e7c280a4316b3/propcache-0.3.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0b504d29f3c47cf6b9e936c1852246c83d450e8e063d50562115a6be6d3a2535", size = 227684, upload-time = "2025-06-09T22:54:47.63Z" }, { url = "https://files.pythonhosted.org/packages/b7/05/37ae63a0087677e90b1d14710e532ff104d44bc1efa3b3970fff99b891dc/propcache-0.3.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:ce2ac2675a6aa41ddb2a0c9cbff53780a617ac3d43e620f8fd77ba1c84dcfc06", size = 234562, upload-time = "2025-06-09T22:54:48.982Z" }, { url = "https://files.pythonhosted.org/packages/a4/7c/3f539fcae630408d0bd8bf3208b9a647ccad10976eda62402a80adf8fc34/propcache-0.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:62b4239611205294cc433845b914131b2a1f03500ff3c1ed093ed216b82621e1", size = 222142, upload-time = "2025-06-09T22:54:50.424Z" }, { url = "https://files.pythonhosted.org/packages/7c/d2/34b9eac8c35f79f8a962546b3e97e9d4b990c420ee66ac8255d5d9611648/propcache-0.3.2-cp312-cp312-win32.whl", hash = "sha256:df4a81b9b53449ebc90cc4deefb052c1dd934ba85012aa912c7ea7b7e38b60c1", size = 37711, upload-time = "2025-06-09T22:54:52.072Z" }, { url = "https://files.pythonhosted.org/packages/19/61/d582be5d226cf79071681d1b46b848d6cb03d7b70af7063e33a2787eaa03/propcache-0.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:7046e79b989d7fe457bb755844019e10f693752d169076138abf17f31380800c", size = 41479, upload-time = "2025-06-09T22:54:53.234Z" }, { url = "https://files.pythonhosted.org/packages/dc/d1/8c747fafa558c603c4ca19d8e20b288aa0c7cda74e9402f50f31eb65267e/propcache-0.3.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ca592ed634a73ca002967458187109265e980422116c0a107cf93d81f95af945", size = 71286, upload-time = "2025-06-09T22:54:54.369Z" }, { url = "https://files.pythonhosted.org/packages/61/99/d606cb7986b60d89c36de8a85d58764323b3a5ff07770a99d8e993b3fa73/propcache-0.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9ecb0aad4020e275652ba3975740f241bd12a61f1a784df044cf7477a02bc252", size = 42425, upload-time = "2025-06-09T22:54:55.642Z" }, { url = "https://files.pythonhosted.org/packages/8c/96/ef98f91bbb42b79e9bb82bdd348b255eb9d65f14dbbe3b1594644c4073f7/propcache-0.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7f08f1cc28bd2eade7a8a3d2954ccc673bb02062e3e7da09bc75d843386b342f", size = 41846, upload-time = "2025-06-09T22:54:57.246Z" }, { url = "https://files.pythonhosted.org/packages/5b/ad/3f0f9a705fb630d175146cd7b1d2bf5555c9beaed54e94132b21aac098a6/propcache-0.3.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1a342c834734edb4be5ecb1e9fb48cb64b1e2320fccbd8c54bf8da8f2a84c33", size = 208871, upload-time = "2025-06-09T22:54:58.975Z" }, { url = "https://files.pythonhosted.org/packages/3a/38/2085cda93d2c8b6ec3e92af2c89489a36a5886b712a34ab25de9fbca7992/propcache-0.3.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a544caaae1ac73f1fecfae70ded3e93728831affebd017d53449e3ac052ac1e", size = 215720, upload-time = "2025-06-09T22:55:00.471Z" }, { url = "https://files.pythonhosted.org/packages/61/c1/d72ea2dc83ac7f2c8e182786ab0fc2c7bd123a1ff9b7975bee671866fe5f/propcache-0.3.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:310d11aa44635298397db47a3ebce7db99a4cc4b9bbdfcf6c98a60c8d5261cf1", size = 215203, upload-time = "2025-06-09T22:55:01.834Z" }, { url = "https://files.pythonhosted.org/packages/af/81/b324c44ae60c56ef12007105f1460d5c304b0626ab0cc6b07c8f2a9aa0b8/propcache-0.3.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c1396592321ac83157ac03a2023aa6cc4a3cc3cfdecb71090054c09e5a7cce3", size = 206365, upload-time = "2025-06-09T22:55:03.199Z" }, { url = "https://files.pythonhosted.org/packages/09/73/88549128bb89e66d2aff242488f62869014ae092db63ccea53c1cc75a81d/propcache-0.3.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cabf5b5902272565e78197edb682017d21cf3b550ba0460ee473753f28d23c1", size = 196016, upload-time = "2025-06-09T22:55:04.518Z" }, { url = "https://files.pythonhosted.org/packages/b9/3f/3bdd14e737d145114a5eb83cb172903afba7242f67c5877f9909a20d948d/propcache-0.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0a2f2235ac46a7aa25bdeb03a9e7060f6ecbd213b1f9101c43b3090ffb971ef6", size = 205596, upload-time = "2025-06-09T22:55:05.942Z" }, { url = "https://files.pythonhosted.org/packages/0f/ca/2f4aa819c357d3107c3763d7ef42c03980f9ed5c48c82e01e25945d437c1/propcache-0.3.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:92b69e12e34869a6970fd2f3da91669899994b47c98f5d430b781c26f1d9f387", size = 200977, upload-time = "2025-06-09T22:55:07.792Z" }, { url = "https://files.pythonhosted.org/packages/cd/4a/e65276c7477533c59085251ae88505caf6831c0e85ff8b2e31ebcbb949b1/propcache-0.3.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:54e02207c79968ebbdffc169591009f4474dde3b4679e16634d34c9363ff56b4", size = 197220, upload-time = "2025-06-09T22:55:09.173Z" }, { url = "https://files.pythonhosted.org/packages/7c/54/fc7152e517cf5578278b242396ce4d4b36795423988ef39bb8cd5bf274c8/propcache-0.3.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4adfb44cb588001f68c5466579d3f1157ca07f7504fc91ec87862e2b8e556b88", size = 210642, upload-time = "2025-06-09T22:55:10.62Z" }, { url = "https://files.pythonhosted.org/packages/b9/80/abeb4a896d2767bf5f1ea7b92eb7be6a5330645bd7fb844049c0e4045d9d/propcache-0.3.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fd3e6019dc1261cd0291ee8919dd91fbab7b169bb76aeef6c716833a3f65d206", size = 212789, upload-time = "2025-06-09T22:55:12.029Z" }, { url = "https://files.pythonhosted.org/packages/b3/db/ea12a49aa7b2b6d68a5da8293dcf50068d48d088100ac016ad92a6a780e6/propcache-0.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4c181cad81158d71c41a2bce88edce078458e2dd5ffee7eddd6b05da85079f43", size = 205880, upload-time = "2025-06-09T22:55:13.45Z" }, { url = "https://files.pythonhosted.org/packages/d1/e5/9076a0bbbfb65d1198007059c65639dfd56266cf8e477a9707e4b1999ff4/propcache-0.3.2-cp313-cp313-win32.whl", hash = "sha256:8a08154613f2249519e549de2330cf8e2071c2887309a7b07fb56098f5170a02", size = 37220, upload-time = "2025-06-09T22:55:15.284Z" }, { url = "https://files.pythonhosted.org/packages/d3/f5/b369e026b09a26cd77aa88d8fffd69141d2ae00a2abaaf5380d2603f4b7f/propcache-0.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:e41671f1594fc4ab0a6dec1351864713cb3a279910ae8b58f884a88a0a632c05", size = 40678, upload-time = "2025-06-09T22:55:16.445Z" }, { url = "https://files.pythonhosted.org/packages/a4/3a/6ece377b55544941a08d03581c7bc400a3c8cd3c2865900a68d5de79e21f/propcache-0.3.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:9a3cf035bbaf035f109987d9d55dc90e4b0e36e04bbbb95af3055ef17194057b", size = 76560, upload-time = "2025-06-09T22:55:17.598Z" }, { url = "https://files.pythonhosted.org/packages/0c/da/64a2bb16418740fa634b0e9c3d29edff1db07f56d3546ca2d86ddf0305e1/propcache-0.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:156c03d07dc1323d8dacaa221fbe028c5c70d16709cdd63502778e6c3ccca1b0", size = 44676, upload-time = "2025-06-09T22:55:18.922Z" }, { url = "https://files.pythonhosted.org/packages/36/7b/f025e06ea51cb72c52fb87e9b395cced02786610b60a3ed51da8af017170/propcache-0.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74413c0ba02ba86f55cf60d18daab219f7e531620c15f1e23d95563f505efe7e", size = 44701, upload-time = "2025-06-09T22:55:20.106Z" }, { url = "https://files.pythonhosted.org/packages/a4/00/faa1b1b7c3b74fc277f8642f32a4c72ba1d7b2de36d7cdfb676db7f4303e/propcache-0.3.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f066b437bb3fa39c58ff97ab2ca351db465157d68ed0440abecb21715eb24b28", size = 276934, upload-time = "2025-06-09T22:55:21.5Z" }, { url = "https://files.pythonhosted.org/packages/74/ab/935beb6f1756e0476a4d5938ff44bf0d13a055fed880caf93859b4f1baf4/propcache-0.3.2-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1304b085c83067914721e7e9d9917d41ad87696bf70f0bc7dee450e9c71ad0a", size = 278316, upload-time = "2025-06-09T22:55:22.918Z" }, { url = "https://files.pythonhosted.org/packages/f8/9d/994a5c1ce4389610838d1caec74bdf0e98b306c70314d46dbe4fcf21a3e2/propcache-0.3.2-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab50cef01b372763a13333b4e54021bdcb291fc9a8e2ccb9c2df98be51bcde6c", size = 282619, upload-time = "2025-06-09T22:55:24.651Z" }, { url = "https://files.pythonhosted.org/packages/2b/00/a10afce3d1ed0287cef2e09506d3be9822513f2c1e96457ee369adb9a6cd/propcache-0.3.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fad3b2a085ec259ad2c2842666b2a0a49dea8463579c606426128925af1ed725", size = 265896, upload-time = "2025-06-09T22:55:26.049Z" }, { url = "https://files.pythonhosted.org/packages/2e/a8/2aa6716ffa566ca57c749edb909ad27884680887d68517e4be41b02299f3/propcache-0.3.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:261fa020c1c14deafd54c76b014956e2f86991af198c51139faf41c4d5e83892", size = 252111, upload-time = "2025-06-09T22:55:27.381Z" }, { url = "https://files.pythonhosted.org/packages/36/4f/345ca9183b85ac29c8694b0941f7484bf419c7f0fea2d1e386b4f7893eed/propcache-0.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:46d7f8aa79c927e5f987ee3a80205c987717d3659f035c85cf0c3680526bdb44", size = 268334, upload-time = "2025-06-09T22:55:28.747Z" }, { url = "https://files.pythonhosted.org/packages/3e/ca/fcd54f78b59e3f97b3b9715501e3147f5340167733d27db423aa321e7148/propcache-0.3.2-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:6d8f3f0eebf73e3c0ff0e7853f68be638b4043c65a70517bb575eff54edd8dbe", size = 255026, upload-time = "2025-06-09T22:55:30.184Z" }, { url = "https://files.pythonhosted.org/packages/8b/95/8e6a6bbbd78ac89c30c225210a5c687790e532ba4088afb8c0445b77ef37/propcache-0.3.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:03c89c1b14a5452cf15403e291c0ccd7751d5b9736ecb2c5bab977ad6c5bcd81", size = 250724, upload-time = "2025-06-09T22:55:31.646Z" }, { url = "https://files.pythonhosted.org/packages/ee/b0/0dd03616142baba28e8b2d14ce5df6631b4673850a3d4f9c0f9dd714a404/propcache-0.3.2-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:0cc17efde71e12bbaad086d679ce575268d70bc123a5a71ea7ad76f70ba30bba", size = 268868, upload-time = "2025-06-09T22:55:33.209Z" }, { url = "https://files.pythonhosted.org/packages/c5/98/2c12407a7e4fbacd94ddd32f3b1e3d5231e77c30ef7162b12a60e2dd5ce3/propcache-0.3.2-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:acdf05d00696bc0447e278bb53cb04ca72354e562cf88ea6f9107df8e7fd9770", size = 271322, upload-time = "2025-06-09T22:55:35.065Z" }, { url = "https://files.pythonhosted.org/packages/35/91/9cb56efbb428b006bb85db28591e40b7736847b8331d43fe335acf95f6c8/propcache-0.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4445542398bd0b5d32df908031cb1b30d43ac848e20470a878b770ec2dcc6330", size = 265778, upload-time = "2025-06-09T22:55:36.45Z" }, { url = "https://files.pythonhosted.org/packages/9a/4c/b0fe775a2bdd01e176b14b574be679d84fc83958335790f7c9a686c1f468/propcache-0.3.2-cp313-cp313t-win32.whl", hash = "sha256:f86e5d7cd03afb3a1db8e9f9f6eff15794e79e791350ac48a8c924e6f439f394", size = 41175, upload-time = "2025-06-09T22:55:38.436Z" }, { url = "https://files.pythonhosted.org/packages/a4/ff/47f08595e3d9b5e149c150f88d9714574f1a7cbd89fe2817158a952674bf/propcache-0.3.2-cp313-cp313t-win_amd64.whl", hash = "sha256:9704bedf6e7cbe3c65eca4379a9b53ee6a83749f047808cbb5044d40d7d72198", size = 44857, upload-time = "2025-06-09T22:55:39.687Z" }, { url = "https://files.pythonhosted.org/packages/6c/39/8ea9bcfaaff16fd0b0fc901ee522e24c9ec44b4ca0229cfffb8066a06959/propcache-0.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a7fad897f14d92086d6b03fdd2eb844777b0c4d7ec5e3bac0fbae2ab0602bbe5", size = 74678, upload-time = "2025-06-09T22:55:41.227Z" }, { url = "https://files.pythonhosted.org/packages/d3/85/cab84c86966e1d354cf90cdc4ba52f32f99a5bca92a1529d666d957d7686/propcache-0.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1f43837d4ca000243fd7fd6301947d7cb93360d03cd08369969450cc6b2ce3b4", size = 43829, upload-time = "2025-06-09T22:55:42.417Z" }, { url = "https://files.pythonhosted.org/packages/23/f7/9cb719749152d8b26d63801b3220ce2d3931312b2744d2b3a088b0ee9947/propcache-0.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:261df2e9474a5949c46e962065d88eb9b96ce0f2bd30e9d3136bcde84befd8f2", size = 43729, upload-time = "2025-06-09T22:55:43.651Z" }, { url = "https://files.pythonhosted.org/packages/a2/a2/0b2b5a210ff311260002a315f6f9531b65a36064dfb804655432b2f7d3e3/propcache-0.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e514326b79e51f0a177daab1052bc164d9d9e54133797a3a58d24c9c87a3fe6d", size = 204483, upload-time = "2025-06-09T22:55:45.327Z" }, { url = "https://files.pythonhosted.org/packages/3f/e0/7aff5de0c535f783b0c8be5bdb750c305c1961d69fbb136939926e155d98/propcache-0.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d4a996adb6904f85894570301939afeee65f072b4fd265ed7e569e8d9058e4ec", size = 217425, upload-time = "2025-06-09T22:55:46.729Z" }, { url = "https://files.pythonhosted.org/packages/92/1d/65fa889eb3b2a7d6e4ed3c2b568a9cb8817547a1450b572de7bf24872800/propcache-0.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:76cace5d6b2a54e55b137669b30f31aa15977eeed390c7cbfb1dafa8dfe9a701", size = 214723, upload-time = "2025-06-09T22:55:48.342Z" }, { url = "https://files.pythonhosted.org/packages/9a/e2/eecf6989870988dfd731de408a6fa366e853d361a06c2133b5878ce821ad/propcache-0.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31248e44b81d59d6addbb182c4720f90b44e1efdc19f58112a3c3a1615fb47ef", size = 200166, upload-time = "2025-06-09T22:55:49.775Z" }, { url = "https://files.pythonhosted.org/packages/12/06/c32be4950967f18f77489268488c7cdc78cbfc65a8ba8101b15e526b83dc/propcache-0.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abb7fa19dbf88d3857363e0493b999b8011eea856b846305d8c0512dfdf8fbb1", size = 194004, upload-time = "2025-06-09T22:55:51.335Z" }, { url = "https://files.pythonhosted.org/packages/46/6c/17b521a6b3b7cbe277a4064ff0aa9129dd8c89f425a5a9b6b4dd51cc3ff4/propcache-0.3.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d81ac3ae39d38588ad0549e321e6f773a4e7cc68e7751524a22885d5bbadf886", size = 203075, upload-time = "2025-06-09T22:55:52.681Z" }, { url = "https://files.pythonhosted.org/packages/62/cb/3bdba2b736b3e45bc0e40f4370f745b3e711d439ffbffe3ae416393eece9/propcache-0.3.2-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:cc2782eb0f7a16462285b6f8394bbbd0e1ee5f928034e941ffc444012224171b", size = 195407, upload-time = "2025-06-09T22:55:54.048Z" }, { url = "https://files.pythonhosted.org/packages/29/bd/760c5c6a60a4a2c55a421bc34a25ba3919d49dee411ddb9d1493bb51d46e/propcache-0.3.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:db429c19a6c7e8a1c320e6a13c99799450f411b02251fb1b75e6217cf4a14fcb", size = 196045, upload-time = "2025-06-09T22:55:55.485Z" }, { url = "https://files.pythonhosted.org/packages/76/58/ced2757a46f55b8c84358d6ab8de4faf57cba831c51e823654da7144b13a/propcache-0.3.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:21d8759141a9e00a681d35a1f160892a36fb6caa715ba0b832f7747da48fb6ea", size = 208432, upload-time = "2025-06-09T22:55:56.884Z" }, { url = "https://files.pythonhosted.org/packages/bb/ec/d98ea8d5a4d8fe0e372033f5254eddf3254344c0c5dc6c49ab84349e4733/propcache-0.3.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2ca6d378f09adb13837614ad2754fa8afaee330254f404299611bce41a8438cb", size = 210100, upload-time = "2025-06-09T22:55:58.498Z" }, { url = "https://files.pythonhosted.org/packages/56/84/b6d8a7ecf3f62d7dd09d9d10bbf89fad6837970ef868b35b5ffa0d24d9de/propcache-0.3.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:34a624af06c048946709f4278b4176470073deda88d91342665d95f7c6270fbe", size = 200712, upload-time = "2025-06-09T22:55:59.906Z" }, { url = "https://files.pythonhosted.org/packages/bf/32/889f4903ddfe4a9dc61da71ee58b763758cf2d608fe1decede06e6467f8d/propcache-0.3.2-cp39-cp39-win32.whl", hash = "sha256:4ba3fef1c30f306b1c274ce0b8baaa2c3cdd91f645c48f06394068f37d3837a1", size = 38187, upload-time = "2025-06-09T22:56:01.212Z" }, { url = "https://files.pythonhosted.org/packages/67/74/d666795fb9ba1dc139d30de64f3b6fd1ff9c9d3d96ccfdb992cd715ce5d2/propcache-0.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:7a2368eed65fc69a7a7a40b27f22e85e7627b74216f0846b04ba5c116e191ec9", size = 42025, upload-time = "2025-06-09T22:56:02.875Z" }, { url = "https://files.pythonhosted.org/packages/cc/35/cc0aaecf278bb4575b8555f2b137de5ab821595ddae9da9d3cd1da4072c7/propcache-0.3.2-py3-none-any.whl", hash = "sha256:98f1ec44fb675f5052cccc8e609c46ed23a35a1cfd18545ad4e29002d858a43f", size = 12663, upload-time = "2025-06-09T22:56:04.484Z" }, ] [[package]] name = "pyasn1" version = "0.6.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/ba/e9/01f1a64245b89f039897cb0130016d79f77d52669aae6ee7b159a6c4c018/pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034", size = 145322, upload-time = "2024-09-10T22:41:42.55Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/c8/f1/d6a797abb14f6283c0ddff96bbdd46937f64122b8c925cab503dd37f8214/pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629", size = 83135, upload-time = "2024-09-11T16:00:36.122Z" }, ] [[package]] name = "pyasn1-modules" version = "0.4.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyasn1" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e9/e6/78ebbb10a8c8e4b61a59249394a4a594c1a7af95593dc933a349c8d00964/pyasn1_modules-0.4.2.tar.gz", hash = "sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6", size = 307892, upload-time = "2025-03-28T02:41:22.17Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/47/8d/d529b5d697919ba8c11ad626e835d4039be708a35b0d22de83a269a6682c/pyasn1_modules-0.4.2-py3-none-any.whl", hash = "sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a", size = 181259, upload-time = "2025-03-28T02:41:19.028Z" }, ] [[package]] name = "pydantic" version = "1.10.23" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.10'", "python_full_version == '3.9.*'", "python_full_version < '3.9'", ] dependencies = [ { name = "typing-extensions", marker = "extra == 'group-9-anthropic-pydantic-v1'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/8f/3d/bd64466a91ec17b73f5c6c723373c352086dedd405c9f8dc1141aaddc59e/pydantic-1.10.23.tar.gz", hash = "sha256:81ee80fe4bd69236aeb65c8beeb5150655b8a49b946fce6664a720d6cf5ec717", size = 356864, upload-time = "2025-09-13T02:39:34.915Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b3/76/0252dc9e6aea421728006e2734f02848a5676bfe7736cc1f9de438aa42a0/pydantic-1.10.23-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1ce178e49a471ebf867451872a3403b89da6194bc2c9761e78ce22f619794d0d", size = 2493024, upload-time = "2025-09-13T02:38:05.322Z" }, { url = "https://files.pythonhosted.org/packages/b9/11/45f651f4646f451ff9c6ead61837693c052feaf1ac296fd9411d897cf0a2/pydantic-1.10.23-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d5f2ab29db92a2b11c7cd49466f68858583bf227165c42a3fae2b50042a1ab51", size = 2300271, upload-time = "2025-09-13T02:38:08.589Z" }, { url = "https://files.pythonhosted.org/packages/50/4b/341c4d714ce1238c4c16a3698c38284f499f1d7769029b9f94fee26702ac/pydantic-1.10.23-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e84ece91eb806586ffa4f92c149308cb07b0fa14a7e1204e18cde01aac283f7", size = 2959673, upload-time = "2025-09-13T02:38:10.231Z" }, { url = "https://files.pythonhosted.org/packages/82/7f/8db5317689dc10809abac464c6db8f8936292899953b6acf9e96c73cfa63/pydantic-1.10.23-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:757c8a2f459311bf277f6ddb4891222f69ba93fb301eee095c985fc7239d5afd", size = 3029774, upload-time = "2025-09-13T02:38:11.851Z" }, { url = "https://files.pythonhosted.org/packages/ae/ef/71fea5e0ec14180f63226717b7723857b31b1e5a3e9635ad6607a42296f0/pydantic-1.10.23-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:50b4726ab72a027fb69da865e849ae16107bdbea01ff1670daf4560e078a1606", size = 3099346, upload-time = "2025-09-13T02:38:13.711Z" }, { url = "https://files.pythonhosted.org/packages/2d/70/1573e4ddcd69f88137e82d405b702631bea48c6a9816b6d0626b468a8d65/pydantic-1.10.23-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4ed07c43d5c3f6f391eceeef7ead84c8c54083e0a1b5fa009302191c07775a73", size = 3038047, upload-time = "2025-09-13T02:38:15.559Z" }, { url = "https://files.pythonhosted.org/packages/ba/1f/c06b6a1d4ac137ff63f3dd0a74b3b2e00ceca26572e14373b3deeef3d068/pydantic-1.10.23-cp310-cp310-win_amd64.whl", hash = "sha256:bc5547c3be3b8494a444adf3703c037bdf2170e30af802f5d7bb14a232698106", size = 2092280, upload-time = "2025-09-13T02:38:18.076Z" }, { url = "https://files.pythonhosted.org/packages/d6/40/c239b68381a2201b1241c0e417cb2cebe29f6e6029f01a2a3a208ed0c7be/pydantic-1.10.23-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b2e9d81546af42331248bbffde26a441631c8823515ebf328ee2ec04d771cd73", size = 2525346, upload-time = "2025-09-13T02:38:19.706Z" }, { url = "https://files.pythonhosted.org/packages/df/18/2138690053ae63a410dd758061404c5426f7e0ee4edb427a379ff679ef80/pydantic-1.10.23-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7e13f39ce65232a2826d1c32a9e2c6f9ca5451d6e51c6e5ea9fdebc285fc2980", size = 2305920, upload-time = "2025-09-13T02:38:21.89Z" }, { url = "https://files.pythonhosted.org/packages/2b/e7/618bb71aafd4bade35d1d9fc0427b1621b5966b550ce0c4afb2a326e1348/pydantic-1.10.23-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:041308bdb4804f0b387b02f870ebdf4e86020de344a969020de853f5ea8d5508", size = 2902994, upload-time = "2025-09-13T02:38:23.812Z" }, { url = "https://files.pythonhosted.org/packages/ce/dd/7044afbe9f805ee57efd7e059a4704111a77664f97e0e821749de8bf065c/pydantic-1.10.23-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed01648e2a469e2c35984bab9ff5080648c53af3b8b98312e1d7823eacd33d77", size = 2975707, upload-time = "2025-09-13T02:38:25.795Z" }, { url = "https://files.pythonhosted.org/packages/18/fc/5dc725d18a7f99b4731c1f6301acb89f5d86816f625b3910ed1e6c762ebb/pydantic-1.10.23-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:18056741c9febebeb043798414099ada8d8e74cc47ec2059d7fbdc7d091d0e7b", size = 3063227, upload-time = "2025-09-13T02:38:27.717Z" }, { url = "https://files.pythonhosted.org/packages/3c/bb/499c9881cbfb4b858ead5264bf740461f8cd10b06dda25379584f5516a43/pydantic-1.10.23-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7411a18deef02a6b7825edb3930b9ab0251f7b131ebb1cb1ffe0aadf74d60c6d", size = 2989099, upload-time = "2025-09-13T02:38:29.637Z" }, { url = "https://files.pythonhosted.org/packages/47/84/593aa9e2229151b563f844b4dfc67c5307116389a5b78fa5230ca26b2ccb/pydantic-1.10.23-cp311-cp311-win_amd64.whl", hash = "sha256:890213289bf40481a715b1d8b3e8a602af9e481d9f0e0b2b00dc375a12b0cfbb", size = 2095481, upload-time = "2025-09-13T02:38:31.42Z" }, { url = "https://files.pythonhosted.org/packages/7d/db/91114a2c7ae0ee946ef54f51aeaba188eb728fa265eea16a2e83801e7174/pydantic-1.10.23-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:136b6428b644691d0ee2a3a7de395d0d1b01ce6388b747bd371bb9ca65b4cc32", size = 2532742, upload-time = "2025-09-13T02:38:33.273Z" }, { url = "https://files.pythonhosted.org/packages/12/95/5a5b2413eb68c996f9ebe36d3d40c72f79417710f72c3347fe2f7436d699/pydantic-1.10.23-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b47c210416606b7c8e236c7546647500856eaba0d01564d5cddacb30d1b5daec", size = 2321478, upload-time = "2025-09-13T02:38:35.285Z" }, { url = "https://files.pythonhosted.org/packages/23/4b/34996785baf88fb907fb51a608b81085167b0acfdee3e6920c67bb145738/pydantic-1.10.23-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c9c436e12d81b7c3d3208f66a5d35b401c8ec25fafc9bff446c77f1072ed5f5", size = 2778508, upload-time = "2025-09-13T02:38:37.046Z" }, { url = "https://files.pythonhosted.org/packages/13/d7/5a748c85d4cd0e82016484642ab6a2ab86cdf4b3d94a3e4969a4f22a85a4/pydantic-1.10.23-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edba6ac9bd6040daf3e876c284257624171884011e0729d90b90f5fe11f7217d", size = 2828364, upload-time = "2025-09-13T02:38:38.829Z" }, { url = "https://files.pythonhosted.org/packages/d5/8a/8a04eb44ebf5e64644a3c6c8dbd1b7c3c506774b88bd6bdc4fff9779cfc2/pydantic-1.10.23-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:101ae7dcd77c23003d4766bcf23e08cd3d012173379ad549bdb2c898855b2a57", size = 2910201, upload-time = "2025-09-13T02:38:40.603Z" }, { url = "https://files.pythonhosted.org/packages/99/a0/9f4c10a0673996f2980c131a857f6eb4d7711fc047df06f4346561af03a0/pydantic-1.10.23-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9b05416d8dcf36fd291348bba8f565d015fce4c594577d2ef5bc0c5ec8f54a29", size = 2858353, upload-time = "2025-09-13T02:38:42.12Z" }, { url = "https://files.pythonhosted.org/packages/67/48/5719e361f87245fe798b4ddcfa70ad69a8aa7cf143b4e15467e26d46d453/pydantic-1.10.23-cp312-cp312-win_amd64.whl", hash = "sha256:0f309b3dd80ed4d3487b1219c69dfd9036e51a863aeaa41a3b67497b81c4cb8f", size = 1968607, upload-time = "2025-09-13T02:38:43.788Z" }, { url = "https://files.pythonhosted.org/packages/fa/d8/02fc15e5af12cf6ee3b58b47ec71bbf0236bc32f621c7d18fd09035c54e5/pydantic-1.10.23-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a6aa6881a18657fe66b9249e0572a9690ebc6f0b37c32872beb06bc51bff738f", size = 2588217, upload-time = "2025-09-13T02:38:45.588Z" }, { url = "https://files.pythonhosted.org/packages/4c/0a/f56de9d891ef61cf64dcd6c9324a3168b46b268a7489c2f0f62b45bf29aa/pydantic-1.10.23-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c57bfade74111335062c8ac830d5a14004742ff5b037c52c410d9e9011258bf5", size = 2349602, upload-time = "2025-09-13T02:38:47.598Z" }, { url = "https://files.pythonhosted.org/packages/02/9c/3e1854d854a11169e7865e55c9e1f081aed3039a9fa3f90b2ae6aa1d1bfc/pydantic-1.10.23-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:723cb7f6aca0b471bac9d7dceb42d151d26aabdca655bd4190be3a7de008a054", size = 2762249, upload-time = "2025-09-13T02:38:49.862Z" }, { url = "https://files.pythonhosted.org/packages/51/b9/910fb8ea0b347f9b02b7641d14a86e1c2d2306d0aeca785f0efc18e23500/pydantic-1.10.23-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1b81db6c9108c3f6509c897fcdf842e5993d7233e9140a7f1c4dc1c2f85b0a8d", size = 2799069, upload-time = "2025-09-13T02:38:51.427Z" }, { url = "https://files.pythonhosted.org/packages/b5/bf/b9eb1bf92f229a4420627f23f2be8d92decc4f9b33d43fcad220baee0a0a/pydantic-1.10.23-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9e9544d07d96df6c6405b64462fb3122e5d0af46a1c4ddf94c180b17ac29f047", size = 2888516, upload-time = "2025-09-13T02:38:53.882Z" }, { url = "https://files.pythonhosted.org/packages/a6/35/58ef579a4ad591f54b20787d123fe7c356c553bdcbde40abb1745778e49d/pydantic-1.10.23-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4dff5e26a14424f4e6cf44cbd45861b458f31e37d316e92a78bf99ec6d1ef2ee", size = 2850293, upload-time = "2025-09-13T02:38:55.839Z" }, { url = "https://files.pythonhosted.org/packages/54/73/f9825643f110ac763edd1abef9559d17e0a440348f94f6e5803b23d5aaaf/pydantic-1.10.23-cp313-cp313-win_amd64.whl", hash = "sha256:633235236c9af4a16e7cf47be3ffab15445552613a122b44a8946868c2ace426", size = 1970494, upload-time = "2025-09-13T02:38:57.378Z" }, { url = "https://files.pythonhosted.org/packages/f0/5b/117c637af7b1680bae4c1e16d35530b8f2d4078e9ee7a5092f32a5b606b4/pydantic-1.10.23-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f71590dcd1ff354107cecc1c26b85406dd11e6f87d9b8416c5defd3cf4d54a51", size = 2386186, upload-time = "2025-09-13T02:39:09.756Z" }, { url = "https://files.pythonhosted.org/packages/ed/16/37dbd0bf8212b2cd616fd1defab1f6ee60e65dee62c6ceef90e19392cfa5/pydantic-1.10.23-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:46b3cd6fb8edf973380ddf1ac7387cca5f0624c07579bf9d15121dd77986b57c", size = 2216810, upload-time = "2025-09-13T02:39:11.379Z" }, { url = "https://files.pythonhosted.org/packages/8e/e7/c30043d13d379ed781bba210027729dbb0370f58cf4b41302ac11860e303/pydantic-1.10.23-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89e9a801a538d056fd91edf0d01dec02abde1b325e3c019c5c06d75fcca86929", size = 2843784, upload-time = "2025-09-13T02:39:12.892Z" }, { url = "https://files.pythonhosted.org/packages/c6/7d/5e94a21cd479717825f30ad2947454674026ef00ff9a070eacec316ced6f/pydantic-1.10.23-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ee7fa1a9bfa45aad5652001efa552a79a40f9ea7a1b11185685dd047895d3a8", size = 2944921, upload-time = "2025-09-13T02:39:14.803Z" }, { url = "https://files.pythonhosted.org/packages/6f/42/90b4d1db7d4e9a5706fd53e9872db7c09d7e96d980f62b6301d524e40dac/pydantic-1.10.23-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:0db70ae0e58eed1ffd01fbfdd23f6c6e5ae5e1bf2cd50dfeb0a2853656766e68", size = 3092583, upload-time = "2025-09-13T02:39:16.853Z" }, { url = "https://files.pythonhosted.org/packages/96/38/a4cc7b1d0b8a8a315f08b7d8be998fc4c7753f90e7549b8cb95ce8dd51a9/pydantic-1.10.23-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:d037210949ac9e837360239d91a834cab3cf02e84cf295ea66c6ff73137f3723", size = 2991731, upload-time = "2025-09-13T02:39:18.368Z" }, { url = "https://files.pythonhosted.org/packages/35/58/7e2583870769eaaef76e2c46d0de61feaf6e1f4cb955f8de0c83e2e6349c/pydantic-1.10.23-cp38-cp38-win_amd64.whl", hash = "sha256:aa8d57384c6305febd9724b4f8de6860b5ba5821b7948dbbd0ddf733d50d7677", size = 2154727, upload-time = "2025-09-13T02:39:19.929Z" }, { url = "https://files.pythonhosted.org/packages/3c/4f/6d542dae6da93903d4cced16a91d2a2bfee826066feba91c0399f5ccd308/pydantic-1.10.23-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cdb4c8fdf8344b912285ca85c99d44433bd3d877f44b9ffcfc79cefedbc08869", size = 2502925, upload-time = "2025-09-13T02:39:21.533Z" }, { url = "https://files.pythonhosted.org/packages/17/66/ebd7428e6db2bff093bc754660db24af4ee5b4d227868937cd114195f1bd/pydantic-1.10.23-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:144f739a617f2c12fa8d135d2efe26b9cf16033a44f2fe5400d7d0e9d9c90dca", size = 2309038, upload-time = "2025-09-13T02:39:23.012Z" }, { url = "https://files.pythonhosted.org/packages/3c/1e/d696eaff2b1ed889d8de8839012144f1b9be7b743a138e669ca5056efac2/pydantic-1.10.23-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3449e59f27a42ba2c35c2e92aea345794696e5dddba3b5d88d123155eac4ee83", size = 2968173, upload-time = "2025-09-13T02:39:24.536Z" }, { url = "https://files.pythonhosted.org/packages/b2/5a/f53e05f877509007457314fdec1a7572cd889f17e7e92b5f090ca28bde78/pydantic-1.10.23-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10e9d8259fab4599498c3246703b84a5e9500240544bf49c54fc57996c6d093a", size = 3038899, upload-time = "2025-09-13T02:39:26.082Z" }, { url = "https://files.pythonhosted.org/packages/1b/a6/9f9d18d754b21d57e45adb5035ed020ed4e5b70e23fb48cb17b6d2f9c57c/pydantic-1.10.23-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:08b576239a4acbbfd35365b603cbee5fee6d3c56323abba54f0142e7ad6ff406", size = 3107617, upload-time = "2025-09-13T02:39:28.092Z" }, { url = "https://files.pythonhosted.org/packages/67/ed/e2b6d31a0bda6f78ba8b84ffbeeba2501f2b5efd5b4a584bc728de2abb88/pydantic-1.10.23-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0f20e4dfe6413ee79fc1b4ac9c9f4112ff9d4cf44a19577592422d09774ee085", size = 3048822, upload-time = "2025-09-13T02:39:29.732Z" }, { url = "https://files.pythonhosted.org/packages/43/cc/272190268db5c7a12f9106e3ed7925fc93d1c3a2dffc6f3beebf0e06b990/pydantic-1.10.23-cp39-cp39-win_amd64.whl", hash = "sha256:45fcc5ed6adde6703f9f22f898362a087d1d140a337ecc4caca2477f4d735390", size = 2099360, upload-time = "2025-09-13T02:39:31.376Z" }, { url = "https://files.pythonhosted.org/packages/f0/d6/43d8913ca252c52c5f5b8d84ae7bfa05059d4d7be3b428170f303d67fe3f/pydantic-1.10.23-py3-none-any.whl", hash = "sha256:6294bb84565c294a3a6408c52b26a42803f258d5ebfdb3ae896cd7cccfa07211", size = 166525, upload-time = "2025-09-13T02:39:33.055Z" }, ] [[package]] name = "pydantic" version = "2.10.6" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] dependencies = [ { name = "annotated-types", marker = "(python_full_version < '3.9' and extra != 'group-9-anthropic-pydantic-v1') or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "pydantic-core", version = "2.27.2", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.9' and extra != 'group-9-anthropic-pydantic-v1') or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "typing-extensions", marker = "(python_full_version < '3.9' and extra != 'group-9-anthropic-pydantic-v1') or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b7/ae/d5220c5c52b158b1de7ca89fc5edb72f304a70a4c540c84c8844bf4008de/pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236", size = 761681, upload-time = "2025-01-24T01:42:12.693Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/f4/3c/8cc1cc84deffa6e25d2d0c688ebb80635dfdbf1dbea3e30c541c8cf4d860/pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584", size = 431696, upload-time = "2025-01-24T01:42:10.371Z" }, ] [[package]] name = "pydantic" version = "2.11.9" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.10'", "python_full_version == '3.9.*'", ] dependencies = [ { name = "annotated-types", marker = "(python_full_version >= '3.9' and extra != 'group-9-anthropic-pydantic-v1') or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "pydantic-core", version = "2.33.2", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.9' and extra != 'group-9-anthropic-pydantic-v1') or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "typing-extensions", marker = "(python_full_version >= '3.9' and extra != 'group-9-anthropic-pydantic-v1') or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "typing-inspection", marker = "(python_full_version >= '3.9' and extra != 'group-9-anthropic-pydantic-v1') or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ff/5d/09a551ba512d7ca404d785072700d3f6727a02f6f3c24ecfd081c7cf0aa8/pydantic-2.11.9.tar.gz", hash = "sha256:6b8ffda597a14812a7975c90b82a8a2e777d9257aba3453f973acd3c032a18e2", size = 788495, upload-time = "2025-09-13T11:26:39.325Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/3e/d3/108f2006987c58e76691d5ae5d200dd3e0f532cb4e5fa3560751c3a1feba/pydantic-2.11.9-py3-none-any.whl", hash = "sha256:c42dd626f5cfc1c6950ce6205ea58c93efa406da65f479dcb4029d5934857da2", size = 444855, upload-time = "2025-09-13T11:26:36.909Z" }, ] [[package]] name = "pydantic-core" version = "2.27.2" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] dependencies = [ { name = "typing-extensions", marker = "(python_full_version < '3.9' and extra != 'group-9-anthropic-pydantic-v1') or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/fc/01/f3e5ac5e7c25833db5eb555f7b7ab24cd6f8c322d3a3ad2d67a952dc0abc/pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39", size = 413443, upload-time = "2024-12-18T11:31:54.917Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/3a/bc/fed5f74b5d802cf9a03e83f60f18864e90e3aed7223adaca5ffb7a8d8d64/pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa", size = 1895938, upload-time = "2024-12-18T11:27:14.406Z" }, { url = "https://files.pythonhosted.org/packages/71/2a/185aff24ce844e39abb8dd680f4e959f0006944f4a8a0ea372d9f9ae2e53/pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c", size = 1815684, upload-time = "2024-12-18T11:27:16.489Z" }, { url = "https://files.pythonhosted.org/packages/c3/43/fafabd3d94d159d4f1ed62e383e264f146a17dd4d48453319fd782e7979e/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a", size = 1829169, upload-time = "2024-12-18T11:27:22.16Z" }, { url = "https://files.pythonhosted.org/packages/a2/d1/f2dfe1a2a637ce6800b799aa086d079998959f6f1215eb4497966efd2274/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5", size = 1867227, upload-time = "2024-12-18T11:27:25.097Z" }, { url = "https://files.pythonhosted.org/packages/7d/39/e06fcbcc1c785daa3160ccf6c1c38fea31f5754b756e34b65f74e99780b5/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c", size = 2037695, upload-time = "2024-12-18T11:27:28.656Z" }, { url = "https://files.pythonhosted.org/packages/7a/67/61291ee98e07f0650eb756d44998214231f50751ba7e13f4f325d95249ab/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7", size = 2741662, upload-time = "2024-12-18T11:27:30.798Z" }, { url = "https://files.pythonhosted.org/packages/32/90/3b15e31b88ca39e9e626630b4c4a1f5a0dfd09076366f4219429e6786076/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a", size = 1993370, upload-time = "2024-12-18T11:27:33.692Z" }, { url = "https://files.pythonhosted.org/packages/ff/83/c06d333ee3a67e2e13e07794995c1535565132940715931c1c43bfc85b11/pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236", size = 1996813, upload-time = "2024-12-18T11:27:37.111Z" }, { url = "https://files.pythonhosted.org/packages/7c/f7/89be1c8deb6e22618a74f0ca0d933fdcb8baa254753b26b25ad3acff8f74/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962", size = 2005287, upload-time = "2024-12-18T11:27:40.566Z" }, { url = "https://files.pythonhosted.org/packages/b7/7d/8eb3e23206c00ef7feee17b83a4ffa0a623eb1a9d382e56e4aa46fd15ff2/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9", size = 2128414, upload-time = "2024-12-18T11:27:43.757Z" }, { url = "https://files.pythonhosted.org/packages/4e/99/fe80f3ff8dd71a3ea15763878d464476e6cb0a2db95ff1c5c554133b6b83/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af", size = 2155301, upload-time = "2024-12-18T11:27:47.36Z" }, { url = "https://files.pythonhosted.org/packages/2b/a3/e50460b9a5789ca1451b70d4f52546fa9e2b420ba3bfa6100105c0559238/pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4", size = 1816685, upload-time = "2024-12-18T11:27:50.508Z" }, { url = "https://files.pythonhosted.org/packages/57/4c/a8838731cb0f2c2a39d3535376466de6049034d7b239c0202a64aaa05533/pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31", size = 1982876, upload-time = "2024-12-18T11:27:53.54Z" }, { url = "https://files.pythonhosted.org/packages/c2/89/f3450af9d09d44eea1f2c369f49e8f181d742f28220f88cc4dfaae91ea6e/pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc", size = 1893421, upload-time = "2024-12-18T11:27:55.409Z" }, { url = "https://files.pythonhosted.org/packages/9e/e3/71fe85af2021f3f386da42d291412e5baf6ce7716bd7101ea49c810eda90/pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7", size = 1814998, upload-time = "2024-12-18T11:27:57.252Z" }, { url = "https://files.pythonhosted.org/packages/a6/3c/724039e0d848fd69dbf5806894e26479577316c6f0f112bacaf67aa889ac/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15", size = 1826167, upload-time = "2024-12-18T11:27:59.146Z" }, { url = "https://files.pythonhosted.org/packages/2b/5b/1b29e8c1fb5f3199a9a57c1452004ff39f494bbe9bdbe9a81e18172e40d3/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306", size = 1865071, upload-time = "2024-12-18T11:28:02.625Z" }, { url = "https://files.pythonhosted.org/packages/89/6c/3985203863d76bb7d7266e36970d7e3b6385148c18a68cc8915fd8c84d57/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99", size = 2036244, upload-time = "2024-12-18T11:28:04.442Z" }, { url = "https://files.pythonhosted.org/packages/0e/41/f15316858a246b5d723f7d7f599f79e37493b2e84bfc789e58d88c209f8a/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459", size = 2737470, upload-time = "2024-12-18T11:28:07.679Z" }, { url = "https://files.pythonhosted.org/packages/a8/7c/b860618c25678bbd6d1d99dbdfdf0510ccb50790099b963ff78a124b754f/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048", size = 1992291, upload-time = "2024-12-18T11:28:10.297Z" }, { url = "https://files.pythonhosted.org/packages/bf/73/42c3742a391eccbeab39f15213ecda3104ae8682ba3c0c28069fbcb8c10d/pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d", size = 1994613, upload-time = "2024-12-18T11:28:13.362Z" }, { url = "https://files.pythonhosted.org/packages/94/7a/941e89096d1175d56f59340f3a8ebaf20762fef222c298ea96d36a6328c5/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b", size = 2002355, upload-time = "2024-12-18T11:28:16.587Z" }, { url = "https://files.pythonhosted.org/packages/6e/95/2359937a73d49e336a5a19848713555605d4d8d6940c3ec6c6c0ca4dcf25/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474", size = 2126661, upload-time = "2024-12-18T11:28:18.407Z" }, { url = "https://files.pythonhosted.org/packages/2b/4c/ca02b7bdb6012a1adef21a50625b14f43ed4d11f1fc237f9d7490aa5078c/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6", size = 2153261, upload-time = "2024-12-18T11:28:21.471Z" }, { url = "https://files.pythonhosted.org/packages/72/9d/a241db83f973049a1092a079272ffe2e3e82e98561ef6214ab53fe53b1c7/pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c", size = 1812361, upload-time = "2024-12-18T11:28:23.53Z" }, { url = "https://files.pythonhosted.org/packages/e8/ef/013f07248041b74abd48a385e2110aa3a9bbfef0fbd97d4e6d07d2f5b89a/pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc", size = 1982484, upload-time = "2024-12-18T11:28:25.391Z" }, { url = "https://files.pythonhosted.org/packages/10/1c/16b3a3e3398fd29dca77cea0a1d998d6bde3902fa2706985191e2313cc76/pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4", size = 1867102, upload-time = "2024-12-18T11:28:28.593Z" }, { url = "https://files.pythonhosted.org/packages/d6/74/51c8a5482ca447871c93e142d9d4a92ead74de6c8dc5e66733e22c9bba89/pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0", size = 1893127, upload-time = "2024-12-18T11:28:30.346Z" }, { url = "https://files.pythonhosted.org/packages/d3/f3/c97e80721735868313c58b89d2de85fa80fe8dfeeed84dc51598b92a135e/pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef", size = 1811340, upload-time = "2024-12-18T11:28:32.521Z" }, { url = "https://files.pythonhosted.org/packages/9e/91/840ec1375e686dbae1bd80a9e46c26a1e0083e1186abc610efa3d9a36180/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7", size = 1822900, upload-time = "2024-12-18T11:28:34.507Z" }, { url = "https://files.pythonhosted.org/packages/f6/31/4240bc96025035500c18adc149aa6ffdf1a0062a4b525c932065ceb4d868/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934", size = 1869177, upload-time = "2024-12-18T11:28:36.488Z" }, { url = "https://files.pythonhosted.org/packages/fa/20/02fbaadb7808be578317015c462655c317a77a7c8f0ef274bc016a784c54/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6", size = 2038046, upload-time = "2024-12-18T11:28:39.409Z" }, { url = "https://files.pythonhosted.org/packages/06/86/7f306b904e6c9eccf0668248b3f272090e49c275bc488a7b88b0823444a4/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c", size = 2685386, upload-time = "2024-12-18T11:28:41.221Z" }, { url = "https://files.pythonhosted.org/packages/8d/f0/49129b27c43396581a635d8710dae54a791b17dfc50c70164866bbf865e3/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2", size = 1997060, upload-time = "2024-12-18T11:28:44.709Z" }, { url = "https://files.pythonhosted.org/packages/0d/0f/943b4af7cd416c477fd40b187036c4f89b416a33d3cc0ab7b82708a667aa/pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4", size = 2004870, upload-time = "2024-12-18T11:28:46.839Z" }, { url = "https://files.pythonhosted.org/packages/35/40/aea70b5b1a63911c53a4c8117c0a828d6790483f858041f47bab0b779f44/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3", size = 1999822, upload-time = "2024-12-18T11:28:48.896Z" }, { url = "https://files.pythonhosted.org/packages/f2/b3/807b94fd337d58effc5498fd1a7a4d9d59af4133e83e32ae39a96fddec9d/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4", size = 2130364, upload-time = "2024-12-18T11:28:50.755Z" }, { url = "https://files.pythonhosted.org/packages/fc/df/791c827cd4ee6efd59248dca9369fb35e80a9484462c33c6649a8d02b565/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57", size = 2158303, upload-time = "2024-12-18T11:28:54.122Z" }, { url = "https://files.pythonhosted.org/packages/9b/67/4e197c300976af185b7cef4c02203e175fb127e414125916bf1128b639a9/pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc", size = 1834064, upload-time = "2024-12-18T11:28:56.074Z" }, { url = "https://files.pythonhosted.org/packages/1f/ea/cd7209a889163b8dcca139fe32b9687dd05249161a3edda62860430457a5/pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9", size = 1989046, upload-time = "2024-12-18T11:28:58.107Z" }, { url = "https://files.pythonhosted.org/packages/bc/49/c54baab2f4658c26ac633d798dab66b4c3a9bbf47cff5284e9c182f4137a/pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b", size = 1885092, upload-time = "2024-12-18T11:29:01.335Z" }, { url = "https://files.pythonhosted.org/packages/41/b1/9bc383f48f8002f99104e3acff6cba1231b29ef76cfa45d1506a5cad1f84/pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b", size = 1892709, upload-time = "2024-12-18T11:29:03.193Z" }, { url = "https://files.pythonhosted.org/packages/10/6c/e62b8657b834f3eb2961b49ec8e301eb99946245e70bf42c8817350cbefc/pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154", size = 1811273, upload-time = "2024-12-18T11:29:05.306Z" }, { url = "https://files.pythonhosted.org/packages/ba/15/52cfe49c8c986e081b863b102d6b859d9defc63446b642ccbbb3742bf371/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9", size = 1823027, upload-time = "2024-12-18T11:29:07.294Z" }, { url = "https://files.pythonhosted.org/packages/b1/1c/b6f402cfc18ec0024120602bdbcebc7bdd5b856528c013bd4d13865ca473/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9", size = 1868888, upload-time = "2024-12-18T11:29:09.249Z" }, { url = "https://files.pythonhosted.org/packages/bd/7b/8cb75b66ac37bc2975a3b7de99f3c6f355fcc4d89820b61dffa8f1e81677/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1", size = 2037738, upload-time = "2024-12-18T11:29:11.23Z" }, { url = "https://files.pythonhosted.org/packages/c8/f1/786d8fe78970a06f61df22cba58e365ce304bf9b9f46cc71c8c424e0c334/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a", size = 2685138, upload-time = "2024-12-18T11:29:16.396Z" }, { url = "https://files.pythonhosted.org/packages/a6/74/d12b2cd841d8724dc8ffb13fc5cef86566a53ed358103150209ecd5d1999/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e", size = 1997025, upload-time = "2024-12-18T11:29:20.25Z" }, { url = "https://files.pythonhosted.org/packages/a0/6e/940bcd631bc4d9a06c9539b51f070b66e8f370ed0933f392db6ff350d873/pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4", size = 2004633, upload-time = "2024-12-18T11:29:23.877Z" }, { url = "https://files.pythonhosted.org/packages/50/cc/a46b34f1708d82498c227d5d80ce615b2dd502ddcfd8376fc14a36655af1/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27", size = 1999404, upload-time = "2024-12-18T11:29:25.872Z" }, { url = "https://files.pythonhosted.org/packages/ca/2d/c365cfa930ed23bc58c41463bae347d1005537dc8db79e998af8ba28d35e/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee", size = 2130130, upload-time = "2024-12-18T11:29:29.252Z" }, { url = "https://files.pythonhosted.org/packages/f4/d7/eb64d015c350b7cdb371145b54d96c919d4db516817f31cd1c650cae3b21/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1", size = 2157946, upload-time = "2024-12-18T11:29:31.338Z" }, { url = "https://files.pythonhosted.org/packages/a4/99/bddde3ddde76c03b65dfd5a66ab436c4e58ffc42927d4ff1198ffbf96f5f/pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130", size = 1834387, upload-time = "2024-12-18T11:29:33.481Z" }, { url = "https://files.pythonhosted.org/packages/71/47/82b5e846e01b26ac6f1893d3c5f9f3a2eb6ba79be26eef0b759b4fe72946/pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee", size = 1990453, upload-time = "2024-12-18T11:29:35.533Z" }, { url = "https://files.pythonhosted.org/packages/51/b2/b2b50d5ecf21acf870190ae5d093602d95f66c9c31f9d5de6062eb329ad1/pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", size = 1885186, upload-time = "2024-12-18T11:29:37.649Z" }, { url = "https://files.pythonhosted.org/packages/43/53/13e9917fc69c0a4aea06fd63ed6a8d6cda9cf140ca9584d49c1650b0ef5e/pydantic_core-2.27.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d3e8d504bdd3f10835468f29008d72fc8359d95c9c415ce6e767203db6127506", size = 1899595, upload-time = "2024-12-18T11:29:40.887Z" }, { url = "https://files.pythonhosted.org/packages/f4/20/26c549249769ed84877f862f7bb93f89a6ee08b4bee1ed8781616b7fbb5e/pydantic_core-2.27.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:521eb9b7f036c9b6187f0b47318ab0d7ca14bd87f776240b90b21c1f4f149320", size = 1775010, upload-time = "2024-12-18T11:29:44.823Z" }, { url = "https://files.pythonhosted.org/packages/35/eb/8234e05452d92d2b102ffa1b56d801c3567e628fdc63f02080fdfc68fd5e/pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85210c4d99a0114f5a9481b44560d7d1e35e32cc5634c656bc48e590b669b145", size = 1830727, upload-time = "2024-12-18T11:29:46.904Z" }, { url = "https://files.pythonhosted.org/packages/8f/df/59f915c8b929d5f61e5a46accf748a87110ba145156f9326d1a7d28912b2/pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d716e2e30c6f140d7560ef1538953a5cd1a87264c737643d481f2779fc247fe1", size = 1868393, upload-time = "2024-12-18T11:29:49.098Z" }, { url = "https://files.pythonhosted.org/packages/d5/52/81cf4071dca654d485c277c581db368b0c95b2b883f4d7b736ab54f72ddf/pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f66d89ba397d92f840f8654756196d93804278457b5fbede59598a1f9f90b228", size = 2040300, upload-time = "2024-12-18T11:29:51.43Z" }, { url = "https://files.pythonhosted.org/packages/9c/00/05197ce1614f5c08d7a06e1d39d5d8e704dc81971b2719af134b844e2eaf/pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:669e193c1c576a58f132e3158f9dfa9662969edb1a250c54d8fa52590045f046", size = 2738785, upload-time = "2024-12-18T11:29:55.001Z" }, { url = "https://files.pythonhosted.org/packages/f7/a3/5f19bc495793546825ab160e530330c2afcee2281c02b5ffafd0b32ac05e/pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdbe7629b996647b99c01b37f11170a57ae675375b14b8c13b8518b8320ced5", size = 1996493, upload-time = "2024-12-18T11:29:57.13Z" }, { url = "https://files.pythonhosted.org/packages/ed/e8/e0102c2ec153dc3eed88aea03990e1b06cfbca532916b8a48173245afe60/pydantic_core-2.27.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d262606bf386a5ba0b0af3b97f37c83d7011439e3dc1a9298f21efb292e42f1a", size = 1998544, upload-time = "2024-12-18T11:30:00.681Z" }, { url = "https://files.pythonhosted.org/packages/fb/a3/4be70845b555bd80aaee9f9812a7cf3df81550bce6dadb3cfee9c5d8421d/pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cabb9bcb7e0d97f74df8646f34fc76fbf793b7f6dc2438517d7a9e50eee4f14d", size = 2007449, upload-time = "2024-12-18T11:30:02.985Z" }, { url = "https://files.pythonhosted.org/packages/e3/9f/b779ed2480ba355c054e6d7ea77792467631d674b13d8257085a4bc7dcda/pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:d2d63f1215638d28221f664596b1ccb3944f6e25dd18cd3b86b0a4c408d5ebb9", size = 2129460, upload-time = "2024-12-18T11:30:06.55Z" }, { url = "https://files.pythonhosted.org/packages/a0/f0/a6ab0681f6e95260c7fbf552874af7302f2ea37b459f9b7f00698f875492/pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bca101c00bff0adb45a833f8451b9105d9df18accb8743b08107d7ada14bd7da", size = 2159609, upload-time = "2024-12-18T11:30:09.428Z" }, { url = "https://files.pythonhosted.org/packages/8a/2b/e1059506795104349712fbca647b18b3f4a7fd541c099e6259717441e1e0/pydantic_core-2.27.2-cp38-cp38-win32.whl", hash = "sha256:f6f8e111843bbb0dee4cb6594cdc73e79b3329b526037ec242a3e49012495b3b", size = 1819886, upload-time = "2024-12-18T11:30:11.777Z" }, { url = "https://files.pythonhosted.org/packages/aa/6d/df49c17f024dfc58db0bacc7b03610058018dd2ea2eaf748ccbada4c3d06/pydantic_core-2.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:fd1aea04935a508f62e0d0ef1f5ae968774a32afc306fb8545e06f5ff5cdf3ad", size = 1980773, upload-time = "2024-12-18T11:30:14.828Z" }, { url = "https://files.pythonhosted.org/packages/27/97/3aef1ddb65c5ccd6eda9050036c956ff6ecbfe66cb7eb40f280f121a5bb0/pydantic_core-2.27.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993", size = 1896475, upload-time = "2024-12-18T11:30:18.316Z" }, { url = "https://files.pythonhosted.org/packages/ad/d3/5668da70e373c9904ed2f372cb52c0b996426f302e0dee2e65634c92007d/pydantic_core-2.27.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308", size = 1772279, upload-time = "2024-12-18T11:30:20.547Z" }, { url = "https://files.pythonhosted.org/packages/8a/9e/e44b8cb0edf04a2f0a1f6425a65ee089c1d6f9c4c2dcab0209127b6fdfc2/pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4", size = 1829112, upload-time = "2024-12-18T11:30:23.255Z" }, { url = "https://files.pythonhosted.org/packages/1c/90/1160d7ac700102effe11616e8119e268770f2a2aa5afb935f3ee6832987d/pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf", size = 1866780, upload-time = "2024-12-18T11:30:25.742Z" }, { url = "https://files.pythonhosted.org/packages/ee/33/13983426df09a36d22c15980008f8d9c77674fc319351813b5a2739b70f3/pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76", size = 2037943, upload-time = "2024-12-18T11:30:28.036Z" }, { url = "https://files.pythonhosted.org/packages/01/d7/ced164e376f6747e9158c89988c293cd524ab8d215ae4e185e9929655d5c/pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118", size = 2740492, upload-time = "2024-12-18T11:30:30.412Z" }, { url = "https://files.pythonhosted.org/packages/8b/1f/3dc6e769d5b7461040778816aab2b00422427bcaa4b56cc89e9c653b2605/pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630", size = 1995714, upload-time = "2024-12-18T11:30:34.358Z" }, { url = "https://files.pythonhosted.org/packages/07/d7/a0bd09bc39283530b3f7c27033a814ef254ba3bd0b5cfd040b7abf1fe5da/pydantic_core-2.27.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54", size = 1997163, upload-time = "2024-12-18T11:30:37.979Z" }, { url = "https://files.pythonhosted.org/packages/2d/bb/2db4ad1762e1c5699d9b857eeb41959191980de6feb054e70f93085e1bcd/pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f", size = 2005217, upload-time = "2024-12-18T11:30:40.367Z" }, { url = "https://files.pythonhosted.org/packages/53/5f/23a5a3e7b8403f8dd8fc8a6f8b49f6b55c7d715b77dcf1f8ae919eeb5628/pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362", size = 2127899, upload-time = "2024-12-18T11:30:42.737Z" }, { url = "https://files.pythonhosted.org/packages/c2/ae/aa38bb8dd3d89c2f1d8362dd890ee8f3b967330821d03bbe08fa01ce3766/pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96", size = 2155726, upload-time = "2024-12-18T11:30:45.279Z" }, { url = "https://files.pythonhosted.org/packages/98/61/4f784608cc9e98f70839187117ce840480f768fed5d386f924074bf6213c/pydantic_core-2.27.2-cp39-cp39-win32.whl", hash = "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e", size = 1817219, upload-time = "2024-12-18T11:30:47.718Z" }, { url = "https://files.pythonhosted.org/packages/57/82/bb16a68e4a1a858bb3768c2c8f1ff8d8978014e16598f001ea29a25bf1d1/pydantic_core-2.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67", size = 1985382, upload-time = "2024-12-18T11:30:51.871Z" }, { url = "https://files.pythonhosted.org/packages/46/72/af70981a341500419e67d5cb45abe552a7c74b66326ac8877588488da1ac/pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e", size = 1891159, upload-time = "2024-12-18T11:30:54.382Z" }, { url = "https://files.pythonhosted.org/packages/ad/3d/c5913cccdef93e0a6a95c2d057d2c2cba347815c845cda79ddd3c0f5e17d/pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8", size = 1768331, upload-time = "2024-12-18T11:30:58.178Z" }, { url = "https://files.pythonhosted.org/packages/f6/f0/a3ae8fbee269e4934f14e2e0e00928f9346c5943174f2811193113e58252/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3", size = 1822467, upload-time = "2024-12-18T11:31:00.6Z" }, { url = "https://files.pythonhosted.org/packages/d7/7a/7bbf241a04e9f9ea24cd5874354a83526d639b02674648af3f350554276c/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f", size = 1979797, upload-time = "2024-12-18T11:31:07.243Z" }, { url = "https://files.pythonhosted.org/packages/4f/5f/4784c6107731f89e0005a92ecb8a2efeafdb55eb992b8e9d0a2be5199335/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133", size = 1987839, upload-time = "2024-12-18T11:31:09.775Z" }, { url = "https://files.pythonhosted.org/packages/6d/a7/61246562b651dff00de86a5f01b6e4befb518df314c54dec187a78d81c84/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc", size = 1998861, upload-time = "2024-12-18T11:31:13.469Z" }, { url = "https://files.pythonhosted.org/packages/86/aa/837821ecf0c022bbb74ca132e117c358321e72e7f9702d1b6a03758545e2/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50", size = 2116582, upload-time = "2024-12-18T11:31:17.423Z" }, { url = "https://files.pythonhosted.org/packages/81/b0/5e74656e95623cbaa0a6278d16cf15e10a51f6002e3ec126541e95c29ea3/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9", size = 2151985, upload-time = "2024-12-18T11:31:19.901Z" }, { url = "https://files.pythonhosted.org/packages/63/37/3e32eeb2a451fddaa3898e2163746b0cffbbdbb4740d38372db0490d67f3/pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151", size = 2004715, upload-time = "2024-12-18T11:31:22.821Z" }, { url = "https://files.pythonhosted.org/packages/29/0e/dcaea00c9dbd0348b723cae82b0e0c122e0fa2b43fa933e1622fd237a3ee/pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656", size = 1891733, upload-time = "2024-12-18T11:31:26.876Z" }, { url = "https://files.pythonhosted.org/packages/86/d3/e797bba8860ce650272bda6383a9d8cad1d1c9a75a640c9d0e848076f85e/pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278", size = 1768375, upload-time = "2024-12-18T11:31:29.276Z" }, { url = "https://files.pythonhosted.org/packages/41/f7/f847b15fb14978ca2b30262548f5fc4872b2724e90f116393eb69008299d/pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb", size = 1822307, upload-time = "2024-12-18T11:31:33.123Z" }, { url = "https://files.pythonhosted.org/packages/9c/63/ed80ec8255b587b2f108e514dc03eed1546cd00f0af281e699797f373f38/pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd", size = 1979971, upload-time = "2024-12-18T11:31:35.755Z" }, { url = "https://files.pythonhosted.org/packages/a9/6d/6d18308a45454a0de0e975d70171cadaf454bc7a0bf86b9c7688e313f0bb/pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc", size = 1987616, upload-time = "2024-12-18T11:31:38.534Z" }, { url = "https://files.pythonhosted.org/packages/82/8a/05f8780f2c1081b800a7ca54c1971e291c2d07d1a50fb23c7e4aef4ed403/pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b", size = 1998943, upload-time = "2024-12-18T11:31:41.853Z" }, { url = "https://files.pythonhosted.org/packages/5e/3e/fe5b6613d9e4c0038434396b46c5303f5ade871166900b357ada4766c5b7/pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b", size = 2116654, upload-time = "2024-12-18T11:31:44.756Z" }, { url = "https://files.pythonhosted.org/packages/db/ad/28869f58938fad8cc84739c4e592989730bfb69b7c90a8fff138dff18e1e/pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2", size = 2152292, upload-time = "2024-12-18T11:31:48.613Z" }, { url = "https://files.pythonhosted.org/packages/a1/0c/c5c5cd3689c32ed1fe8c5d234b079c12c281c051759770c05b8bed6412b5/pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35", size = 2004961, upload-time = "2024-12-18T11:31:52.446Z" }, ] [[package]] name = "pydantic-core" version = "2.33.2" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.10'", "python_full_version == '3.9.*'", ] dependencies = [ { name = "typing-extensions", marker = "(python_full_version >= '3.9' and extra != 'group-9-anthropic-pydantic-v1') or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ad/88/5f2260bdfae97aabf98f1778d43f69574390ad787afb646292a638c923d4/pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc", size = 435195, upload-time = "2025-04-23T18:33:52.104Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/e5/92/b31726561b5dae176c2d2c2dc43a9c5bfba5d32f96f8b4c0a600dd492447/pydantic_core-2.33.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2b3d326aaef0c0399d9afffeb6367d5e26ddc24d351dbc9c636840ac355dc5d8", size = 2028817, upload-time = "2025-04-23T18:30:43.919Z" }, { url = "https://files.pythonhosted.org/packages/a3/44/3f0b95fafdaca04a483c4e685fe437c6891001bf3ce8b2fded82b9ea3aa1/pydantic_core-2.33.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e5b2671f05ba48b94cb90ce55d8bdcaaedb8ba00cc5359f6810fc918713983d", size = 1861357, upload-time = "2025-04-23T18:30:46.372Z" }, { url = "https://files.pythonhosted.org/packages/30/97/e8f13b55766234caae05372826e8e4b3b96e7b248be3157f53237682e43c/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0069c9acc3f3981b9ff4cdfaf088e98d83440a4c7ea1bc07460af3d4dc22e72d", size = 1898011, upload-time = "2025-04-23T18:30:47.591Z" }, { url = "https://files.pythonhosted.org/packages/9b/a3/99c48cf7bafc991cc3ee66fd544c0aae8dc907b752f1dad2d79b1b5a471f/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d53b22f2032c42eaaf025f7c40c2e3b94568ae077a606f006d206a463bc69572", size = 1982730, upload-time = "2025-04-23T18:30:49.328Z" }, { url = "https://files.pythonhosted.org/packages/de/8e/a5b882ec4307010a840fb8b58bd9bf65d1840c92eae7534c7441709bf54b/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0405262705a123b7ce9f0b92f123334d67b70fd1f20a9372b907ce1080c7ba02", size = 2136178, upload-time = "2025-04-23T18:30:50.907Z" }, { url = "https://files.pythonhosted.org/packages/e4/bb/71e35fc3ed05af6834e890edb75968e2802fe98778971ab5cba20a162315/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4b25d91e288e2c4e0662b8038a28c6a07eaac3e196cfc4ff69de4ea3db992a1b", size = 2736462, upload-time = "2025-04-23T18:30:52.083Z" }, { url = "https://files.pythonhosted.org/packages/31/0d/c8f7593e6bc7066289bbc366f2235701dcbebcd1ff0ef8e64f6f239fb47d/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bdfe4b3789761f3bcb4b1ddf33355a71079858958e3a552f16d5af19768fef2", size = 2005652, upload-time = "2025-04-23T18:30:53.389Z" }, { url = "https://files.pythonhosted.org/packages/d2/7a/996d8bd75f3eda405e3dd219ff5ff0a283cd8e34add39d8ef9157e722867/pydantic_core-2.33.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:efec8db3266b76ef9607c2c4c419bdb06bf335ae433b80816089ea7585816f6a", size = 2113306, upload-time = "2025-04-23T18:30:54.661Z" }, { url = "https://files.pythonhosted.org/packages/ff/84/daf2a6fb2db40ffda6578a7e8c5a6e9c8affb251a05c233ae37098118788/pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:031c57d67ca86902726e0fae2214ce6770bbe2f710dc33063187a68744a5ecac", size = 2073720, upload-time = "2025-04-23T18:30:56.11Z" }, { url = "https://files.pythonhosted.org/packages/77/fb/2258da019f4825128445ae79456a5499c032b55849dbd5bed78c95ccf163/pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:f8de619080e944347f5f20de29a975c2d815d9ddd8be9b9b7268e2e3ef68605a", size = 2244915, upload-time = "2025-04-23T18:30:57.501Z" }, { url = "https://files.pythonhosted.org/packages/d8/7a/925ff73756031289468326e355b6fa8316960d0d65f8b5d6b3a3e7866de7/pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:73662edf539e72a9440129f231ed3757faab89630d291b784ca99237fb94db2b", size = 2241884, upload-time = "2025-04-23T18:30:58.867Z" }, { url = "https://files.pythonhosted.org/packages/0b/b0/249ee6d2646f1cdadcb813805fe76265745c4010cf20a8eba7b0e639d9b2/pydantic_core-2.33.2-cp310-cp310-win32.whl", hash = "sha256:0a39979dcbb70998b0e505fb1556a1d550a0781463ce84ebf915ba293ccb7e22", size = 1910496, upload-time = "2025-04-23T18:31:00.078Z" }, { url = "https://files.pythonhosted.org/packages/66/ff/172ba8f12a42d4b552917aa65d1f2328990d3ccfc01d5b7c943ec084299f/pydantic_core-2.33.2-cp310-cp310-win_amd64.whl", hash = "sha256:b0379a2b24882fef529ec3b4987cb5d003b9cda32256024e6fe1586ac45fc640", size = 1955019, upload-time = "2025-04-23T18:31:01.335Z" }, { url = "https://files.pythonhosted.org/packages/3f/8d/71db63483d518cbbf290261a1fc2839d17ff89fce7089e08cad07ccfce67/pydantic_core-2.33.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4c5b0a576fb381edd6d27f0a85915c6daf2f8138dc5c267a57c08a62900758c7", size = 2028584, upload-time = "2025-04-23T18:31:03.106Z" }, { url = "https://files.pythonhosted.org/packages/24/2f/3cfa7244ae292dd850989f328722d2aef313f74ffc471184dc509e1e4e5a/pydantic_core-2.33.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e799c050df38a639db758c617ec771fd8fb7a5f8eaaa4b27b101f266b216a246", size = 1855071, upload-time = "2025-04-23T18:31:04.621Z" }, { url = "https://files.pythonhosted.org/packages/b3/d3/4ae42d33f5e3f50dd467761304be2fa0a9417fbf09735bc2cce003480f2a/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc46a01bf8d62f227d5ecee74178ffc448ff4e5197c756331f71efcc66dc980f", size = 1897823, upload-time = "2025-04-23T18:31:06.377Z" }, { url = "https://files.pythonhosted.org/packages/f4/f3/aa5976e8352b7695ff808599794b1fba2a9ae2ee954a3426855935799488/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a144d4f717285c6d9234a66778059f33a89096dfb9b39117663fd8413d582dcc", size = 1983792, upload-time = "2025-04-23T18:31:07.93Z" }, { url = "https://files.pythonhosted.org/packages/d5/7a/cda9b5a23c552037717f2b2a5257e9b2bfe45e687386df9591eff7b46d28/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73cf6373c21bc80b2e0dc88444f41ae60b2f070ed02095754eb5a01df12256de", size = 2136338, upload-time = "2025-04-23T18:31:09.283Z" }, { url = "https://files.pythonhosted.org/packages/2b/9f/b8f9ec8dd1417eb9da784e91e1667d58a2a4a7b7b34cf4af765ef663a7e5/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dc625f4aa79713512d1976fe9f0bc99f706a9dee21dfd1810b4bbbf228d0e8a", size = 2730998, upload-time = "2025-04-23T18:31:11.7Z" }, { url = "https://files.pythonhosted.org/packages/47/bc/cd720e078576bdb8255d5032c5d63ee5c0bf4b7173dd955185a1d658c456/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b21b5549499972441da4758d662aeea93f1923f953e9cbaff14b8b9565aef", size = 2003200, upload-time = "2025-04-23T18:31:13.536Z" }, { url = "https://files.pythonhosted.org/packages/ca/22/3602b895ee2cd29d11a2b349372446ae9727c32e78a94b3d588a40fdf187/pydantic_core-2.33.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bdc25f3681f7b78572699569514036afe3c243bc3059d3942624e936ec93450e", size = 2113890, upload-time = "2025-04-23T18:31:15.011Z" }, { url = "https://files.pythonhosted.org/packages/ff/e6/e3c5908c03cf00d629eb38393a98fccc38ee0ce8ecce32f69fc7d7b558a7/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fe5b32187cbc0c862ee201ad66c30cf218e5ed468ec8dc1cf49dec66e160cc4d", size = 2073359, upload-time = "2025-04-23T18:31:16.393Z" }, { url = "https://files.pythonhosted.org/packages/12/e7/6a36a07c59ebefc8777d1ffdaf5ae71b06b21952582e4b07eba88a421c79/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:bc7aee6f634a6f4a95676fcb5d6559a2c2a390330098dba5e5a5f28a2e4ada30", size = 2245883, upload-time = "2025-04-23T18:31:17.892Z" }, { url = "https://files.pythonhosted.org/packages/16/3f/59b3187aaa6cc0c1e6616e8045b284de2b6a87b027cce2ffcea073adf1d2/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:235f45e5dbcccf6bd99f9f472858849f73d11120d76ea8707115415f8e5ebebf", size = 2241074, upload-time = "2025-04-23T18:31:19.205Z" }, { url = "https://files.pythonhosted.org/packages/e0/ed/55532bb88f674d5d8f67ab121a2a13c385df382de2a1677f30ad385f7438/pydantic_core-2.33.2-cp311-cp311-win32.whl", hash = "sha256:6368900c2d3ef09b69cb0b913f9f8263b03786e5b2a387706c5afb66800efd51", size = 1910538, upload-time = "2025-04-23T18:31:20.541Z" }, { url = "https://files.pythonhosted.org/packages/fe/1b/25b7cccd4519c0b23c2dd636ad39d381abf113085ce4f7bec2b0dc755eb1/pydantic_core-2.33.2-cp311-cp311-win_amd64.whl", hash = "sha256:1e063337ef9e9820c77acc768546325ebe04ee38b08703244c1309cccc4f1bab", size = 1952909, upload-time = "2025-04-23T18:31:22.371Z" }, { url = "https://files.pythonhosted.org/packages/49/a9/d809358e49126438055884c4366a1f6227f0f84f635a9014e2deb9b9de54/pydantic_core-2.33.2-cp311-cp311-win_arm64.whl", hash = "sha256:6b99022f1d19bc32a4c2a0d544fc9a76e3be90f0b3f4af413f87d38749300e65", size = 1897786, upload-time = "2025-04-23T18:31:24.161Z" }, { url = "https://files.pythonhosted.org/packages/18/8a/2b41c97f554ec8c71f2a8a5f85cb56a8b0956addfe8b0efb5b3d77e8bdc3/pydantic_core-2.33.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a7ec89dc587667f22b6a0b6579c249fca9026ce7c333fc142ba42411fa243cdc", size = 2009000, upload-time = "2025-04-23T18:31:25.863Z" }, { url = "https://files.pythonhosted.org/packages/a1/02/6224312aacb3c8ecbaa959897af57181fb6cf3a3d7917fd44d0f2917e6f2/pydantic_core-2.33.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3c6db6e52c6d70aa0d00d45cdb9b40f0433b96380071ea80b09277dba021ddf7", size = 1847996, upload-time = "2025-04-23T18:31:27.341Z" }, { url = "https://files.pythonhosted.org/packages/d6/46/6dcdf084a523dbe0a0be59d054734b86a981726f221f4562aed313dbcb49/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e61206137cbc65e6d5256e1166f88331d3b6238e082d9f74613b9b765fb9025", size = 1880957, upload-time = "2025-04-23T18:31:28.956Z" }, { url = "https://files.pythonhosted.org/packages/ec/6b/1ec2c03837ac00886ba8160ce041ce4e325b41d06a034adbef11339ae422/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb8c529b2819c37140eb51b914153063d27ed88e3bdc31b71198a198e921e011", size = 1964199, upload-time = "2025-04-23T18:31:31.025Z" }, { url = "https://files.pythonhosted.org/packages/2d/1d/6bf34d6adb9debd9136bd197ca72642203ce9aaaa85cfcbfcf20f9696e83/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c52b02ad8b4e2cf14ca7b3d918f3eb0ee91e63b3167c32591e57c4317e134f8f", size = 2120296, upload-time = "2025-04-23T18:31:32.514Z" }, { url = "https://files.pythonhosted.org/packages/e0/94/2bd0aaf5a591e974b32a9f7123f16637776c304471a0ab33cf263cf5591a/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96081f1605125ba0855dfda83f6f3df5ec90c61195421ba72223de35ccfb2f88", size = 2676109, upload-time = "2025-04-23T18:31:33.958Z" }, { url = "https://files.pythonhosted.org/packages/f9/41/4b043778cf9c4285d59742281a769eac371b9e47e35f98ad321349cc5d61/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f57a69461af2a5fa6e6bbd7a5f60d3b7e6cebb687f55106933188e79ad155c1", size = 2002028, upload-time = "2025-04-23T18:31:39.095Z" }, { url = "https://files.pythonhosted.org/packages/cb/d5/7bb781bf2748ce3d03af04d5c969fa1308880e1dca35a9bd94e1a96a922e/pydantic_core-2.33.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:572c7e6c8bb4774d2ac88929e3d1f12bc45714ae5ee6d9a788a9fb35e60bb04b", size = 2100044, upload-time = "2025-04-23T18:31:41.034Z" }, { url = "https://files.pythonhosted.org/packages/fe/36/def5e53e1eb0ad896785702a5bbfd25eed546cdcf4087ad285021a90ed53/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:db4b41f9bd95fbe5acd76d89920336ba96f03e149097365afe1cb092fceb89a1", size = 2058881, upload-time = "2025-04-23T18:31:42.757Z" }, { url = "https://files.pythonhosted.org/packages/01/6c/57f8d70b2ee57fc3dc8b9610315949837fa8c11d86927b9bb044f8705419/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:fa854f5cf7e33842a892e5c73f45327760bc7bc516339fda888c75ae60edaeb6", size = 2227034, upload-time = "2025-04-23T18:31:44.304Z" }, { url = "https://files.pythonhosted.org/packages/27/b9/9c17f0396a82b3d5cbea4c24d742083422639e7bb1d5bf600e12cb176a13/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5f483cfb75ff703095c59e365360cb73e00185e01aaea067cd19acffd2ab20ea", size = 2234187, upload-time = "2025-04-23T18:31:45.891Z" }, { url = "https://files.pythonhosted.org/packages/b0/6a/adf5734ffd52bf86d865093ad70b2ce543415e0e356f6cacabbc0d9ad910/pydantic_core-2.33.2-cp312-cp312-win32.whl", hash = "sha256:9cb1da0f5a471435a7bc7e439b8a728e8b61e59784b2af70d7c169f8dd8ae290", size = 1892628, upload-time = "2025-04-23T18:31:47.819Z" }, { url = "https://files.pythonhosted.org/packages/43/e4/5479fecb3606c1368d496a825d8411e126133c41224c1e7238be58b87d7e/pydantic_core-2.33.2-cp312-cp312-win_amd64.whl", hash = "sha256:f941635f2a3d96b2973e867144fde513665c87f13fe0e193c158ac51bfaaa7b2", size = 1955866, upload-time = "2025-04-23T18:31:49.635Z" }, { url = "https://files.pythonhosted.org/packages/0d/24/8b11e8b3e2be9dd82df4b11408a67c61bb4dc4f8e11b5b0fc888b38118b5/pydantic_core-2.33.2-cp312-cp312-win_arm64.whl", hash = "sha256:cca3868ddfaccfbc4bfb1d608e2ccaaebe0ae628e1416aeb9c4d88c001bb45ab", size = 1888894, upload-time = "2025-04-23T18:31:51.609Z" }, { url = "https://files.pythonhosted.org/packages/46/8c/99040727b41f56616573a28771b1bfa08a3d3fe74d3d513f01251f79f172/pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f", size = 2015688, upload-time = "2025-04-23T18:31:53.175Z" }, { url = "https://files.pythonhosted.org/packages/3a/cc/5999d1eb705a6cefc31f0b4a90e9f7fc400539b1a1030529700cc1b51838/pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6", size = 1844808, upload-time = "2025-04-23T18:31:54.79Z" }, { url = "https://files.pythonhosted.org/packages/6f/5e/a0a7b8885c98889a18b6e376f344da1ef323d270b44edf8174d6bce4d622/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef", size = 1885580, upload-time = "2025-04-23T18:31:57.393Z" }, { url = "https://files.pythonhosted.org/packages/3b/2a/953581f343c7d11a304581156618c3f592435523dd9d79865903272c256a/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a", size = 1973859, upload-time = "2025-04-23T18:31:59.065Z" }, { url = "https://files.pythonhosted.org/packages/e6/55/f1a813904771c03a3f97f676c62cca0c0a4138654107c1b61f19c644868b/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916", size = 2120810, upload-time = "2025-04-23T18:32:00.78Z" }, { url = "https://files.pythonhosted.org/packages/aa/c3/053389835a996e18853ba107a63caae0b9deb4a276c6b472931ea9ae6e48/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a", size = 2676498, upload-time = "2025-04-23T18:32:02.418Z" }, { url = "https://files.pythonhosted.org/packages/eb/3c/f4abd740877a35abade05e437245b192f9d0ffb48bbbbd708df33d3cda37/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d", size = 2000611, upload-time = "2025-04-23T18:32:04.152Z" }, { url = "https://files.pythonhosted.org/packages/59/a7/63ef2fed1837d1121a894d0ce88439fe3e3b3e48c7543b2a4479eb99c2bd/pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56", size = 2107924, upload-time = "2025-04-23T18:32:06.129Z" }, { url = "https://files.pythonhosted.org/packages/04/8f/2551964ef045669801675f1cfc3b0d74147f4901c3ffa42be2ddb1f0efc4/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5", size = 2063196, upload-time = "2025-04-23T18:32:08.178Z" }, { url = "https://files.pythonhosted.org/packages/26/bd/d9602777e77fc6dbb0c7db9ad356e9a985825547dce5ad1d30ee04903918/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e", size = 2236389, upload-time = "2025-04-23T18:32:10.242Z" }, { url = "https://files.pythonhosted.org/packages/42/db/0e950daa7e2230423ab342ae918a794964b053bec24ba8af013fc7c94846/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162", size = 2239223, upload-time = "2025-04-23T18:32:12.382Z" }, { url = "https://files.pythonhosted.org/packages/58/4d/4f937099c545a8a17eb52cb67fe0447fd9a373b348ccfa9a87f141eeb00f/pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849", size = 1900473, upload-time = "2025-04-23T18:32:14.034Z" }, { url = "https://files.pythonhosted.org/packages/a0/75/4a0a9bac998d78d889def5e4ef2b065acba8cae8c93696906c3a91f310ca/pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9", size = 1955269, upload-time = "2025-04-23T18:32:15.783Z" }, { url = "https://files.pythonhosted.org/packages/f9/86/1beda0576969592f1497b4ce8e7bc8cbdf614c352426271b1b10d5f0aa64/pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9", size = 1893921, upload-time = "2025-04-23T18:32:18.473Z" }, { url = "https://files.pythonhosted.org/packages/a4/7d/e09391c2eebeab681df2b74bfe6c43422fffede8dc74187b2b0bf6fd7571/pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac", size = 1806162, upload-time = "2025-04-23T18:32:20.188Z" }, { url = "https://files.pythonhosted.org/packages/f1/3d/847b6b1fed9f8ed3bb95a9ad04fbd0b212e832d4f0f50ff4d9ee5a9f15cf/pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5", size = 1981560, upload-time = "2025-04-23T18:32:22.354Z" }, { url = "https://files.pythonhosted.org/packages/6f/9a/e73262f6c6656262b5fdd723ad90f518f579b7bc8622e43a942eec53c938/pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9", size = 1935777, upload-time = "2025-04-23T18:32:25.088Z" }, { url = "https://files.pythonhosted.org/packages/53/ea/bbe9095cdd771987d13c82d104a9c8559ae9aec1e29f139e286fd2e9256e/pydantic_core-2.33.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a2b911a5b90e0374d03813674bf0a5fbbb7741570dcd4b4e85a2e48d17def29d", size = 2028677, upload-time = "2025-04-23T18:32:27.227Z" }, { url = "https://files.pythonhosted.org/packages/49/1d/4ac5ed228078737d457a609013e8f7edc64adc37b91d619ea965758369e5/pydantic_core-2.33.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6fa6dfc3e4d1f734a34710f391ae822e0a8eb8559a85c6979e14e65ee6ba2954", size = 1864735, upload-time = "2025-04-23T18:32:29.019Z" }, { url = "https://files.pythonhosted.org/packages/23/9a/2e70d6388d7cda488ae38f57bc2f7b03ee442fbcf0d75d848304ac7e405b/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c54c939ee22dc8e2d545da79fc5381f1c020d6d3141d3bd747eab59164dc89fb", size = 1898467, upload-time = "2025-04-23T18:32:31.119Z" }, { url = "https://files.pythonhosted.org/packages/ff/2e/1568934feb43370c1ffb78a77f0baaa5a8b6897513e7a91051af707ffdc4/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53a57d2ed685940a504248187d5685e49eb5eef0f696853647bf37c418c538f7", size = 1983041, upload-time = "2025-04-23T18:32:33.655Z" }, { url = "https://files.pythonhosted.org/packages/01/1a/1a1118f38ab64eac2f6269eb8c120ab915be30e387bb561e3af904b12499/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09fb9dd6571aacd023fe6aaca316bd01cf60ab27240d7eb39ebd66a3a15293b4", size = 2136503, upload-time = "2025-04-23T18:32:35.519Z" }, { url = "https://files.pythonhosted.org/packages/5c/da/44754d1d7ae0f22d6d3ce6c6b1486fc07ac2c524ed8f6eca636e2e1ee49b/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0e6116757f7959a712db11f3e9c0a99ade00a5bbedae83cb801985aa154f071b", size = 2736079, upload-time = "2025-04-23T18:32:37.659Z" }, { url = "https://files.pythonhosted.org/packages/4d/98/f43cd89172220ec5aa86654967b22d862146bc4d736b1350b4c41e7c9c03/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d55ab81c57b8ff8548c3e4947f119551253f4e3787a7bbc0b6b3ca47498a9d3", size = 2006508, upload-time = "2025-04-23T18:32:39.637Z" }, { url = "https://files.pythonhosted.org/packages/2b/cc/f77e8e242171d2158309f830f7d5d07e0531b756106f36bc18712dc439df/pydantic_core-2.33.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c20c462aa4434b33a2661701b861604913f912254e441ab8d78d30485736115a", size = 2113693, upload-time = "2025-04-23T18:32:41.818Z" }, { url = "https://files.pythonhosted.org/packages/54/7a/7be6a7bd43e0a47c147ba7fbf124fe8aaf1200bc587da925509641113b2d/pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:44857c3227d3fb5e753d5fe4a3420d6376fa594b07b621e220cd93703fe21782", size = 2074224, upload-time = "2025-04-23T18:32:44.033Z" }, { url = "https://files.pythonhosted.org/packages/2a/07/31cf8fadffbb03be1cb520850e00a8490c0927ec456e8293cafda0726184/pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:eb9b459ca4df0e5c87deb59d37377461a538852765293f9e6ee834f0435a93b9", size = 2245403, upload-time = "2025-04-23T18:32:45.836Z" }, { url = "https://files.pythonhosted.org/packages/b6/8d/bbaf4c6721b668d44f01861f297eb01c9b35f612f6b8e14173cb204e6240/pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9fcd347d2cc5c23b06de6d3b7b8275be558a0c90549495c699e379a80bf8379e", size = 2242331, upload-time = "2025-04-23T18:32:47.618Z" }, { url = "https://files.pythonhosted.org/packages/bb/93/3cc157026bca8f5006250e74515119fcaa6d6858aceee8f67ab6dc548c16/pydantic_core-2.33.2-cp39-cp39-win32.whl", hash = "sha256:83aa99b1285bc8f038941ddf598501a86f1536789740991d7d8756e34f1e74d9", size = 1910571, upload-time = "2025-04-23T18:32:49.401Z" }, { url = "https://files.pythonhosted.org/packages/5b/90/7edc3b2a0d9f0dda8806c04e511a67b0b7a41d2187e2003673a996fb4310/pydantic_core-2.33.2-cp39-cp39-win_amd64.whl", hash = "sha256:f481959862f57f29601ccced557cc2e817bce7533ab8e01a797a48b49c9692b3", size = 1956504, upload-time = "2025-04-23T18:32:51.287Z" }, { url = "https://files.pythonhosted.org/packages/30/68/373d55e58b7e83ce371691f6eaa7175e3a24b956c44628eb25d7da007917/pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5c4aa4e82353f65e548c476b37e64189783aa5384903bfea4f41580f255fddfa", size = 2023982, upload-time = "2025-04-23T18:32:53.14Z" }, { url = "https://files.pythonhosted.org/packages/a4/16/145f54ac08c96a63d8ed6442f9dec17b2773d19920b627b18d4f10a061ea/pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d946c8bf0d5c24bf4fe333af284c59a19358aa3ec18cb3dc4370080da1e8ad29", size = 1858412, upload-time = "2025-04-23T18:32:55.52Z" }, { url = "https://files.pythonhosted.org/packages/41/b1/c6dc6c3e2de4516c0bb2c46f6a373b91b5660312342a0cf5826e38ad82fa/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87b31b6846e361ef83fedb187bb5b4372d0da3f7e28d85415efa92d6125d6e6d", size = 1892749, upload-time = "2025-04-23T18:32:57.546Z" }, { url = "https://files.pythonhosted.org/packages/12/73/8cd57e20afba760b21b742106f9dbdfa6697f1570b189c7457a1af4cd8a0/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa9d91b338f2df0508606f7009fde642391425189bba6d8c653afd80fd6bb64e", size = 2067527, upload-time = "2025-04-23T18:32:59.771Z" }, { url = "https://files.pythonhosted.org/packages/e3/d5/0bb5d988cc019b3cba4a78f2d4b3854427fc47ee8ec8e9eaabf787da239c/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2058a32994f1fde4ca0480ab9d1e75a0e8c87c22b53a3ae66554f9af78f2fe8c", size = 2108225, upload-time = "2025-04-23T18:33:04.51Z" }, { url = "https://files.pythonhosted.org/packages/f1/c5/00c02d1571913d496aabf146106ad8239dc132485ee22efe08085084ff7c/pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:0e03262ab796d986f978f79c943fc5f620381be7287148b8010b4097f79a39ec", size = 2069490, upload-time = "2025-04-23T18:33:06.391Z" }, { url = "https://files.pythonhosted.org/packages/22/a8/dccc38768274d3ed3a59b5d06f59ccb845778687652daa71df0cab4040d7/pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1a8695a8d00c73e50bff9dfda4d540b7dee29ff9b8053e38380426a85ef10052", size = 2237525, upload-time = "2025-04-23T18:33:08.44Z" }, { url = "https://files.pythonhosted.org/packages/d4/e7/4f98c0b125dda7cf7ccd14ba936218397b44f50a56dd8c16a3091df116c3/pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:fa754d1850735a0b0e03bcffd9d4b4343eb417e47196e4485d9cca326073a42c", size = 2238446, upload-time = "2025-04-23T18:33:10.313Z" }, { url = "https://files.pythonhosted.org/packages/ce/91/2ec36480fdb0b783cd9ef6795753c1dea13882f2e68e73bce76ae8c21e6a/pydantic_core-2.33.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a11c8d26a50bfab49002947d3d237abe4d9e4b5bdc8846a63537b6488e197808", size = 2066678, upload-time = "2025-04-23T18:33:12.224Z" }, { url = "https://files.pythonhosted.org/packages/7b/27/d4ae6487d73948d6f20dddcd94be4ea43e74349b56eba82e9bdee2d7494c/pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:dd14041875d09cc0f9308e37a6f8b65f5585cf2598a53aa0123df8b129d481f8", size = 2025200, upload-time = "2025-04-23T18:33:14.199Z" }, { url = "https://files.pythonhosted.org/packages/f1/b8/b3cb95375f05d33801024079b9392a5ab45267a63400bf1866e7ce0f0de4/pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d87c561733f66531dced0da6e864f44ebf89a8fba55f31407b00c2f7f9449593", size = 1859123, upload-time = "2025-04-23T18:33:16.555Z" }, { url = "https://files.pythonhosted.org/packages/05/bc/0d0b5adeda59a261cd30a1235a445bf55c7e46ae44aea28f7bd6ed46e091/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f82865531efd18d6e07a04a17331af02cb7a651583c418df8266f17a63c6612", size = 1892852, upload-time = "2025-04-23T18:33:18.513Z" }, { url = "https://files.pythonhosted.org/packages/3e/11/d37bdebbda2e449cb3f519f6ce950927b56d62f0b84fd9cb9e372a26a3d5/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bfb5112df54209d820d7bf9317c7a6c9025ea52e49f46b6a2060104bba37de7", size = 2067484, upload-time = "2025-04-23T18:33:20.475Z" }, { url = "https://files.pythonhosted.org/packages/8c/55/1f95f0a05ce72ecb02a8a8a1c3be0579bbc29b1d5ab68f1378b7bebc5057/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:64632ff9d614e5eecfb495796ad51b0ed98c453e447a76bcbeeb69615079fc7e", size = 2108896, upload-time = "2025-04-23T18:33:22.501Z" }, { url = "https://files.pythonhosted.org/packages/53/89/2b2de6c81fa131f423246a9109d7b2a375e83968ad0800d6e57d0574629b/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f889f7a40498cc077332c7ab6b4608d296d852182211787d4f3ee377aaae66e8", size = 2069475, upload-time = "2025-04-23T18:33:24.528Z" }, { url = "https://files.pythonhosted.org/packages/b8/e9/1f7efbe20d0b2b10f6718944b5d8ece9152390904f29a78e68d4e7961159/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:de4b83bb311557e439b9e186f733f6c645b9417c84e2eb8203f3f820a4b988bf", size = 2239013, upload-time = "2025-04-23T18:33:26.621Z" }, { url = "https://files.pythonhosted.org/packages/3c/b2/5309c905a93811524a49b4e031e9851a6b00ff0fb668794472ea7746b448/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82f68293f055f51b51ea42fafc74b6aad03e70e191799430b90c13d643059ebb", size = 2238715, upload-time = "2025-04-23T18:33:28.656Z" }, { url = "https://files.pythonhosted.org/packages/32/56/8a7ca5d2cd2cda1d245d34b1c9a942920a718082ae8e54e5f3e5a58b7add/pydantic_core-2.33.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:329467cecfb529c925cf2bbd4d60d2c509bc2fb52a20c1045bf09bb70971a9c1", size = 2066757, upload-time = "2025-04-23T18:33:30.645Z" }, { url = "https://files.pythonhosted.org/packages/08/98/dbf3fdfabaf81cda5622154fda78ea9965ac467e3239078e0dcd6df159e7/pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:87acbfcf8e90ca885206e98359d7dca4bcbb35abdc0ff66672a293e1d7a19101", size = 2024034, upload-time = "2025-04-23T18:33:32.843Z" }, { url = "https://files.pythonhosted.org/packages/8d/99/7810aa9256e7f2ccd492590f86b79d370df1e9292f1f80b000b6a75bd2fb/pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7f92c15cd1e97d4b12acd1cc9004fa092578acfa57b67ad5e43a197175d01a64", size = 1858578, upload-time = "2025-04-23T18:33:34.912Z" }, { url = "https://files.pythonhosted.org/packages/d8/60/bc06fa9027c7006cc6dd21e48dbf39076dc39d9abbaf718a1604973a9670/pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3f26877a748dc4251cfcfda9dfb5f13fcb034f5308388066bcfe9031b63ae7d", size = 1892858, upload-time = "2025-04-23T18:33:36.933Z" }, { url = "https://files.pythonhosted.org/packages/f2/40/9d03997d9518816c68b4dfccb88969756b9146031b61cd37f781c74c9b6a/pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac89aea9af8cd672fa7b510e7b8c33b0bba9a43186680550ccf23020f32d535", size = 2068498, upload-time = "2025-04-23T18:33:38.997Z" }, { url = "https://files.pythonhosted.org/packages/d8/62/d490198d05d2d86672dc269f52579cad7261ced64c2df213d5c16e0aecb1/pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:970919794d126ba8645f3837ab6046fb4e72bbc057b3709144066204c19a455d", size = 2108428, upload-time = "2025-04-23T18:33:41.18Z" }, { url = "https://files.pythonhosted.org/packages/9a/ec/4cd215534fd10b8549015f12ea650a1a973da20ce46430b68fc3185573e8/pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3eb3fe62804e8f859c49ed20a8451342de53ed764150cb14ca71357c765dc2a6", size = 2069854, upload-time = "2025-04-23T18:33:43.446Z" }, { url = "https://files.pythonhosted.org/packages/1a/1a/abbd63d47e1d9b0d632fee6bb15785d0889c8a6e0a6c3b5a8e28ac1ec5d2/pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:3abcd9392a36025e3bd55f9bd38d908bd17962cc49bc6da8e7e96285336e2bca", size = 2237859, upload-time = "2025-04-23T18:33:45.56Z" }, { url = "https://files.pythonhosted.org/packages/80/1c/fa883643429908b1c90598fd2642af8839efd1d835b65af1f75fba4d94fe/pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:3a1c81334778f9e3af2f8aeb7a960736e5cab1dfebfb26aabca09afd2906c039", size = 2239059, upload-time = "2025-04-23T18:33:47.735Z" }, { url = "https://files.pythonhosted.org/packages/d4/29/3cade8a924a61f60ccfa10842f75eb12787e1440e2b8660ceffeb26685e7/pydantic_core-2.33.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2807668ba86cb38c6817ad9bc66215ab8584d1d304030ce4f0887336f28a5e27", size = 2066661, upload-time = "2025-04-23T18:33:49.995Z" }, ] [[package]] name = "pygments" version = "2.19.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581, upload-time = "2025-01-06T17:26:30.443Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293, upload-time = "2025-01-06T17:26:25.553Z" }, ] [[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.3.5" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] dependencies = [ { name = "colorama", marker = "(python_full_version < '3.9' and sys_platform == 'win32') or (python_full_version >= '3.9' and extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2') or (sys_platform != 'win32' and extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "exceptiongroup", marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "iniconfig", marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "packaging", marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "pluggy", marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "tomli", marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ae/3c/c9d525a414d506893f0cd8a8d0de7706446213181570cdbd766691164e40/pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845", size = 1450891, upload-time = "2025-03-02T12:54:54.503Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/30/3d/64ad57c803f1fa1e963a7946b6e0fea4a70df53c1a7fed304586539c2bac/pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", size = 343634, upload-time = "2025-03-02T12:54:52.069Z" }, ] [[package]] name = "pytest" version = "8.4.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.10'", "python_full_version == '3.9.*'", ] dependencies = [ { name = "colorama", marker = "(python_full_version >= '3.9' and sys_platform == 'win32') or (python_full_version < '3.9' and extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2') or (sys_platform != 'win32' and extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "exceptiongroup", marker = "(python_full_version >= '3.9' and python_full_version < '3.11') or (python_full_version < '3.9' and extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2') or (python_full_version >= '3.11' and extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "iniconfig", marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "packaging", marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "pluggy", marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "pygments", marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "tomli", marker = "(python_full_version >= '3.9' and python_full_version < '3.11') or (python_full_version < '3.9' and extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2') or (python_full_version >= '3.11' and extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714, upload-time = "2025-06-18T05:48:06.109Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474, upload-time = "2025-06-18T05:48:03.955Z" }, ] [[package]] name = "pytest-asyncio" version = "0.24.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest", version = "8.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "pytest", version = "8.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/52/6d/c6cf50ce320cf8611df7a1254d86233b3df7cc07f9b5f5cbcb82e08aa534/pytest_asyncio-0.24.0.tar.gz", hash = "sha256:d081d828e576d85f875399194281e92bf8a68d60d72d1a2faf2feddb6c46b276", size = 49855, upload-time = "2024-08-22T08:03:18.145Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/96/31/6607dab48616902f76885dfcf62c08d929796fc3b2d2318faf9fd54dbed9/pytest_asyncio-0.24.0-py3-none-any.whl", hash = "sha256:a811296ed596b69bf0b6f3dc40f83bcaf341b155a269052d82efa2b25ac7037b", size = 18024, upload-time = "2024-08-22T08:03:15.536Z" }, ] [[package]] name = "pytest-xdist" version = "3.6.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] dependencies = [ { name = "execnet", marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "pytest", version = "8.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/41/c4/3c310a19bc1f1e9ef50075582652673ef2bfc8cd62afef9585683821902f/pytest_xdist-3.6.1.tar.gz", hash = "sha256:ead156a4db231eec769737f57668ef58a2084a34b2e55c4a8fa20d861107300d", size = 84060, upload-time = "2024-04-28T19:29:54.414Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/6d/82/1d96bf03ee4c0fdc3c0cbe61470070e659ca78dc0086fb88b66c185e2449/pytest_xdist-3.6.1-py3-none-any.whl", hash = "sha256:9ed4adfb68a016610848639bb7e02c9352d5d9f03d04809919e2dafc3be4cca7", size = 46108, upload-time = "2024-04-28T19:29:52.813Z" }, ] [[package]] name = "pytest-xdist" version = "3.7.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.10'", "python_full_version == '3.9.*'", ] dependencies = [ { name = "execnet", marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "pytest", version = "8.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/49/dc/865845cfe987b21658e871d16e0a24e871e00884c545f246dd8f6f69edda/pytest_xdist-3.7.0.tar.gz", hash = "sha256:f9248c99a7c15b7d2f90715df93610353a485827bc06eefb6566d23f6400f126", size = 87550, upload-time = "2025-05-26T21:18:20.251Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/0d/b2/0e802fde6f1c5b2f7ae7e9ad42b83fd4ecebac18a8a8c2f2f14e39dce6e1/pytest_xdist-3.7.0-py3-none-any.whl", hash = "sha256:7d3fbd255998265052435eb9daa4e99b62e6fb9cfb6efd1f858d4d8c0c7f0ca0", size = 46142, upload-time = "2025-05-26T21:18:18.759Z" }, ] [[package]] name = "python-dateutil" version = "2.9.0.post0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "six" }, ] sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, ] [[package]] name = "pytz" version = "2024.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/3a/31/3c70bf7603cc2dca0f19bdc53b4537a797747a58875b552c8c413d963a3f/pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a", size = 319692, upload-time = "2024-09-11T02:24:47.91Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/11/c3/005fcca25ce078d2cc29fd559379817424e94885510568bc1bc53d7d5846/pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725", size = 508002, upload-time = "2024-09-11T02:24:45.8Z" }, ] [[package]] name = "requests" version = "2.32.4" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] dependencies = [ { name = "certifi", marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "charset-normalizer", marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "idna", marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "urllib3", version = "1.26.20", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e1/0a/929373653770d8a0d7ea76c37de6e41f11eb07559b103b1c02cafb3f7cf8/requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422", size = 135258, upload-time = "2025-06-09T16:43:07.34Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/7c/e4/56027c4a6b4ae70ca9de302488c5ca95ad4a39e190093d6c1a8ace08341b/requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c", size = 64847, upload-time = "2025-06-09T16:43:05.728Z" }, ] [[package]] name = "requests" version = "2.32.5" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.10'", "python_full_version == '3.9.*'", ] dependencies = [ { name = "certifi", marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "charset-normalizer", marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "idna", marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "urllib3", version = "1.26.20", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.9.*' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "urllib3", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, ] [[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 = "13.9.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown-it-py" }, { name = "pygments" }, { name = "typing-extensions", marker = "python_full_version < '3.11' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ab/3a/0316b28d0761c6734d6bc14e770d85506c986c85ffb239e688eeaab2c2bc/rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098", size = 223149, upload-time = "2024-11-01T16:43:57.873Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/19/71/39c7c0d87f8d4e6c020a393182060eaefeeae6c01dab6a84ec346f2567df/rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90", size = 242424, upload-time = "2024-11-01T16:43:55.817Z" }, ] [[package]] name = "rsa" version = "4.9.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyasn1" }, ] sdist = { url = "https://files.pythonhosted.org/packages/da/8a/22b7beea3ee0d44b1916c0c1cb0ee3af23b700b6da9f04991899d0c555d4/rsa-4.9.1.tar.gz", hash = "sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75", size = 29034, upload-time = "2025-04-16T09:51:18.218Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/64/8d/0133e4eb4beed9e425d9a98ed6e081a55d195481b7632472be1af08d2f6b/rsa-4.9.1-py3-none-any.whl", hash = "sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762", size = 34696, upload-time = "2025-04-16T09:51:17.142Z" }, ] [[package]] name = "ruff" version = "0.9.4" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/c0/17/529e78f49fc6f8076f50d985edd9a2cf011d1dbadb1cdeacc1d12afc1d26/ruff-0.9.4.tar.gz", hash = "sha256:6907ee3529244bb0ed066683e075f09285b38dd5b4039370df6ff06041ca19e7", size = 3599458, upload-time = "2025-01-30T18:09:51.03Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b6/f8/3fafb7804d82e0699a122101b5bee5f0d6e17c3a806dcbc527bb7d3f5b7a/ruff-0.9.4-py3-none-linux_armv6l.whl", hash = "sha256:64e73d25b954f71ff100bb70f39f1ee09e880728efb4250c632ceed4e4cdf706", size = 11668400, upload-time = "2025-01-30T18:08:46.508Z" }, { url = "https://files.pythonhosted.org/packages/2e/a6/2efa772d335da48a70ab2c6bb41a096c8517ca43c086ea672d51079e3d1f/ruff-0.9.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6ce6743ed64d9afab4fafeaea70d3631b4d4b28b592db21a5c2d1f0ef52934bf", size = 11628395, upload-time = "2025-01-30T18:08:50.87Z" }, { url = "https://files.pythonhosted.org/packages/dc/d7/cd822437561082f1c9d7225cc0d0fbb4bad117ad7ac3c41cd5d7f0fa948c/ruff-0.9.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:54499fb08408e32b57360f6f9de7157a5fec24ad79cb3f42ef2c3f3f728dfe2b", size = 11090052, upload-time = "2025-01-30T18:08:54.498Z" }, { url = "https://files.pythonhosted.org/packages/9e/67/3660d58e893d470abb9a13f679223368ff1684a4ef40f254a0157f51b448/ruff-0.9.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37c892540108314a6f01f105040b5106aeb829fa5fb0561d2dcaf71485021137", size = 11882221, upload-time = "2025-01-30T18:08:57.784Z" }, { url = "https://files.pythonhosted.org/packages/79/d1/757559995c8ba5f14dfec4459ef2dd3fcea82ac43bc4e7c7bf47484180c0/ruff-0.9.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:de9edf2ce4b9ddf43fd93e20ef635a900e25f622f87ed6e3047a664d0e8f810e", size = 11424862, upload-time = "2025-01-30T18:09:01.167Z" }, { url = "https://files.pythonhosted.org/packages/c0/96/7915a7c6877bb734caa6a2af424045baf6419f685632469643dbd8eb2958/ruff-0.9.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87c90c32357c74f11deb7fbb065126d91771b207bf9bfaaee01277ca59b574ec", size = 12626735, upload-time = "2025-01-30T18:09:05.312Z" }, { url = "https://files.pythonhosted.org/packages/0e/cc/dadb9b35473d7cb17c7ffe4737b4377aeec519a446ee8514123ff4a26091/ruff-0.9.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:56acd6c694da3695a7461cc55775f3a409c3815ac467279dfa126061d84b314b", size = 13255976, upload-time = "2025-01-30T18:09:09.425Z" }, { url = "https://files.pythonhosted.org/packages/5f/c3/ad2dd59d3cabbc12df308cced780f9c14367f0321e7800ca0fe52849da4c/ruff-0.9.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0c93e7d47ed951b9394cf352d6695b31498e68fd5782d6cbc282425655f687a", size = 12752262, upload-time = "2025-01-30T18:09:13.112Z" }, { url = "https://files.pythonhosted.org/packages/c7/17/5f1971e54bd71604da6788efd84d66d789362b1105e17e5ccc53bba0289b/ruff-0.9.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d4c8772670aecf037d1bf7a07c39106574d143b26cfe5ed1787d2f31e800214", size = 14401648, upload-time = "2025-01-30T18:09:17.086Z" }, { url = "https://files.pythonhosted.org/packages/30/24/6200b13ea611b83260501b6955b764bb320e23b2b75884c60ee7d3f0b68e/ruff-0.9.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfc5f1d7afeda8d5d37660eeca6d389b142d7f2b5a1ab659d9214ebd0e025231", size = 12414702, upload-time = "2025-01-30T18:09:21.672Z" }, { url = "https://files.pythonhosted.org/packages/34/cb/f5d50d0c4ecdcc7670e348bd0b11878154bc4617f3fdd1e8ad5297c0d0ba/ruff-0.9.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:faa935fc00ae854d8b638c16a5f1ce881bc3f67446957dd6f2af440a5fc8526b", size = 11859608, upload-time = "2025-01-30T18:09:25.663Z" }, { url = "https://files.pythonhosted.org/packages/d6/f4/9c8499ae8426da48363bbb78d081b817b0f64a9305f9b7f87eab2a8fb2c1/ruff-0.9.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a6c634fc6f5a0ceae1ab3e13c58183978185d131a29c425e4eaa9f40afe1e6d6", size = 11485702, upload-time = "2025-01-30T18:09:28.903Z" }, { url = "https://files.pythonhosted.org/packages/18/59/30490e483e804ccaa8147dd78c52e44ff96e1c30b5a95d69a63163cdb15b/ruff-0.9.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:433dedf6ddfdec7f1ac7575ec1eb9844fa60c4c8c2f8887a070672b8d353d34c", size = 12067782, upload-time = "2025-01-30T18:09:32.371Z" }, { url = "https://files.pythonhosted.org/packages/3d/8c/893fa9551760b2f8eb2a351b603e96f15af167ceaf27e27ad873570bc04c/ruff-0.9.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d612dbd0f3a919a8cc1d12037168bfa536862066808960e0cc901404b77968f0", size = 12483087, upload-time = "2025-01-30T18:09:36.124Z" }, { url = "https://files.pythonhosted.org/packages/23/15/f6751c07c21ca10e3f4a51ea495ca975ad936d780c347d9808bcedbd7182/ruff-0.9.4-py3-none-win32.whl", hash = "sha256:db1192ddda2200671f9ef61d9597fcef89d934f5d1705e571a93a67fb13a4402", size = 9852302, upload-time = "2025-01-30T18:09:40.013Z" }, { url = "https://files.pythonhosted.org/packages/12/41/2d2d2c6a72e62566f730e49254f602dfed23019c33b5b21ea8f8917315a1/ruff-0.9.4-py3-none-win_amd64.whl", hash = "sha256:05bebf4cdbe3ef75430d26c375773978950bbf4ee3c95ccb5448940dc092408e", size = 10850051, upload-time = "2025-01-30T18:09:43.42Z" }, { url = "https://files.pythonhosted.org/packages/c6/e6/3d6ec3bc3d254e7f005c543a661a41c3e788976d0e52a1ada195bd664344/ruff-0.9.4-py3-none-win_arm64.whl", hash = "sha256:585792f1e81509e38ac5123492f8875fbc36f3ede8185af0a26df348e5154f41", size = 10078251, upload-time = "2025-01-30T18:09:48.01Z" }, ] [[package]] name = "s3transfer" version = "0.11.5" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] dependencies = [ { name = "botocore", version = "1.37.38", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c4/2b/5c9562795c2eb2b5f63536961754760c25bf0f34af93d36aa28dea2fb303/s3transfer-0.11.5.tar.gz", hash = "sha256:8c8aad92784779ab8688a61aefff3e28e9ebdce43142808eaa3f0b0f402f68b7", size = 149107, upload-time = "2025-04-17T19:23:19.051Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/45/39/13402e323666d17850eca87e4cd6ecfcf9fd7809cac9efdcce10272fc29d/s3transfer-0.11.5-py3-none-any.whl", hash = "sha256:757af0f2ac150d3c75bc4177a32355c3862a98d20447b69a0161812992fe0bd4", size = 84782, upload-time = "2025-04-17T19:23:17.516Z" }, ] [[package]] name = "s3transfer" version = "0.14.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.10'", "python_full_version == '3.9.*'", ] dependencies = [ { name = "botocore", version = "1.40.31", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/62/74/8d69dcb7a9efe8baa2046891735e5dfe433ad558ae23d9e3c14c633d1d58/s3transfer-0.14.0.tar.gz", hash = "sha256:eff12264e7c8b4985074ccce27a3b38a485bb7f7422cc8046fee9be4983e4125", size = 151547, upload-time = "2025-09-09T19:23:31.089Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/48/f0/ae7ca09223a81a1d890b2557186ea015f6e0502e9b8cb8e1813f1d8cfa4e/s3transfer-0.14.0-py3-none-any.whl", hash = "sha256:ea3b790c7077558ed1f02a3072fb3cb992bbbd253392f4b6e9e8976941c7d456", size = 85712, upload-time = "2025-09-09T19:23:30.041Z" }, ] [[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.15.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] dependencies = [ { name = "python-dateutil", marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b2/e8/82d358c4d53555f031c2343d1c235b56b9f3b0a60ac3adc555778fe87506/time_machine-2.15.0.tar.gz", hash = "sha256:ebd2e63baa117ded04b978813fcd1279d3fc6be2149c9cac75c716b6f1db774c", size = 25067, upload-time = "2024-08-06T11:12:18.578Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/67/47/35413db37da55865fdbf60649bcb948cc2559f420ef4e91e77e4e24c71b8/time_machine-2.15.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:892d016789b59950989b2db188dcd46cf16d34e8daf2343e33b679b0c5fd1001", size = 20779, upload-time = "2024-08-06T13:42:39.043Z" }, { url = "https://files.pythonhosted.org/packages/e0/c3/fda6d2336737d0331eb55357db1dc916af14c4fda77c69ad8b3733b003c4/time_machine-2.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4428bdae507996aa3fdeb4727bca09e26306fa64a502e7335207252684516cbf", size = 17040, upload-time = "2024-08-06T13:42:40.273Z" }, { url = "https://files.pythonhosted.org/packages/36/e1/71200f24d668e5183e875a08ba5e557b6107c1b7d57fa6d54ac24ad10234/time_machine-2.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0302568338c8bd333ed0698231dbb781b70ead1a5579b4ac734b9bf88313229f", size = 34811, upload-time = "2024-08-06T13:42:43.632Z" }, { url = "https://files.pythonhosted.org/packages/9e/2f/4b9289ea07978ad5c3469c872c7eeadf5f5b3a1dcebe2fb274c2486fc220/time_machine-2.15.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18fc4740073e67071472c48355775ec6d1b93af5c675524b7de2474e0dcd8741", size = 32820, upload-time = "2024-08-06T13:42:41.347Z" }, { url = "https://files.pythonhosted.org/packages/5f/9e/9f838c91d2248d716281af60dfea4131438c6ad6d7405ebc6e47f8c25c3b/time_machine-2.15.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:768d33b484a35da93731cc99bdc926b539240a78673216cdc6306833d9072350", size = 34635, upload-time = "2024-08-06T13:42:42.427Z" }, { url = "https://files.pythonhosted.org/packages/f3/10/1048b5ba6de55779563f005de5fbfb764727bf9678ad7701cea480b3816c/time_machine-2.15.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:73a8c8160d2a170dadcad5b82fb5ee53236a19cec0996651cf4d21da0a2574d5", size = 34326, upload-time = "2024-08-06T13:42:45.683Z" }, { url = "https://files.pythonhosted.org/packages/13/82/6b4df8e5abf754b0ccceeb59fa32486d28c65f67d4ada37ff8b1e9f52006/time_machine-2.15.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:09fd839a321a92aa8183206c383b9725eaf4e0a28a70e4cb87db292b352eeefb", size = 32639, upload-time = "2024-08-06T13:42:46.902Z" }, { url = "https://files.pythonhosted.org/packages/cf/07/95e380c46136252401d97f613782a10061b3c11b61edaeb78e83aedc1a88/time_machine-2.15.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:838a6d117739f1ae6ecc45ec630fa694f41a85c0d07b1f3b1db2a6cc52c1808b", size = 34021, upload-time = "2024-08-06T13:42:48.294Z" }, { url = "https://files.pythonhosted.org/packages/b6/0c/6595fa82bd70bc7e8065bfc6534e51a27c18978f7c158d6392c979cace2c/time_machine-2.15.0-cp310-cp310-win32.whl", hash = "sha256:d24d2ec74923b49bce7618e3e7762baa6be74e624d9829d5632321de102bf386", size = 19413, upload-time = "2024-08-06T13:42:49.579Z" }, { url = "https://files.pythonhosted.org/packages/2f/3d/cb3c1cecfeb4b6423302ee1b2863617390500f67526f0fc1fb5641db05f6/time_machine-2.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:95c8e7036cf442480d0bf6f5fde371e1eb6dbbf5391d7bdb8db73bd8a732b538", size = 20280, upload-time = "2024-08-06T13:42:52.548Z" }, { url = "https://files.pythonhosted.org/packages/22/aa/96aaac88738369fba43d5cb076bb09290b1a2cbd84210bcc0a9a519c7970/time_machine-2.15.0-cp310-cp310-win_arm64.whl", hash = "sha256:660810cd27a8a94cb5e845e8f28a95e70b01ff0c45466d394c4a0cba5a0ae279", size = 18392, upload-time = "2024-08-06T13:42:53.945Z" }, { url = "https://files.pythonhosted.org/packages/ce/54/829ab196c3306eb4cee95e3c8e7d004e15877b36479de5d2ecc72fc1d3d4/time_machine-2.15.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:674097dd54a0bbd555e7927092c74428c4c07268ad52bca38cfccc3214707e50", size = 20448, upload-time = "2024-08-06T13:42:58.809Z" }, { url = "https://files.pythonhosted.org/packages/e1/48/a06f8c7db768db501a60210a48f3d37b7b3d65ca85aa8dc08147eb204b4a/time_machine-2.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4e83fd6112808d1d14d1a57397c6fa3bd71bb2f3b8800036e12366e3680819b9", size = 16897, upload-time = "2024-08-06T13:43:00.751Z" }, { url = "https://files.pythonhosted.org/packages/e7/f8/73265927e3da54a417536dc3d8c9aad806b62b8133099a7ee12661aba1a3/time_machine-2.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b095a1de40ca1afaeae8df3f45e26b645094a1912e6e6871e725fcf06ecdb74a", size = 32789, upload-time = "2024-08-06T13:43:06.312Z" }, { url = "https://files.pythonhosted.org/packages/8a/a4/bcf8ad40a4c6973a67aba5df7ed704dc34256835fb074cfb4d4caa0f93a5/time_machine-2.15.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4601fe7a6b74c6fd9207e614d9db2a20dd4befd4d314677a0feac13a67189707", size = 30911, upload-time = "2024-08-06T13:43:02.579Z" }, { url = "https://files.pythonhosted.org/packages/13/87/a6de1b187f5468781e0e722c877323625227151cc8ffff363a7391b01149/time_machine-2.15.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:245ef73f9927b7d4909d554a6a0284dbc5dee9730adea599e430b37c9e9fa203", size = 32644, upload-time = "2024-08-06T13:43:04.457Z" }, { url = "https://files.pythonhosted.org/packages/33/1f/7378d5a032467891a1005e546532223b97c53440c6359b1133696a5cb1ef/time_machine-2.15.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:704abc7f3403584cca9c01c5809812e0bd70632ea4251389fae4f45e11aad94f", size = 32472, upload-time = "2024-08-06T13:43:07.699Z" }, { url = "https://files.pythonhosted.org/packages/68/14/2fab61ad2c9a831925bce3d5e341fa2108ba062c2de0c190569e1ee6a1c9/time_machine-2.15.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:6425001e50a0c82108caed438233066cea04d42a8fc9c49bfcf081a5b96e5b4e", size = 30882, upload-time = "2024-08-06T13:43:08.83Z" }, { url = "https://files.pythonhosted.org/packages/8a/01/f5146b9956b548072000a87f3eb8dbb2591ada1516a5d889aa12b373948f/time_machine-2.15.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5d4073b754f90b19f28d036ec5143d3fca3a75e4d4241d78790a6178b00bb373", size = 32176, upload-time = "2024-08-06T13:43:10.689Z" }, { url = "https://files.pythonhosted.org/packages/ca/09/8a8488e6d3faf3cb68d078f27ca94aa3ba1bc08d5f804265c590208a70f5/time_machine-2.15.0-cp311-cp311-win32.whl", hash = "sha256:8817b0f7d7830215261b18db83c9c3ef1da6bb64da5c292d7c70b9a46e5a6745", size = 19305, upload-time = "2024-08-06T13:43:12.568Z" }, { url = "https://files.pythonhosted.org/packages/75/33/d8411b197a08eedb3ce086022cdf4faf1f15738607a2d943fd5286f57fdd/time_machine-2.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:ddad27a62df2ea47b7b483009fbfcf167a71d702cbd8e2eefd9ddc1c93146658", size = 20210, upload-time = "2024-08-06T13:43:13.731Z" }, { url = "https://files.pythonhosted.org/packages/8c/f5/e9b5d7be612403e570a42af5c2823506877e726f77f2d6ff272d72d0aed3/time_machine-2.15.0-cp311-cp311-win_arm64.whl", hash = "sha256:6f021aa2dbd8fbfe54d3fa2258518129108b7496922b3bcff2cf5991078eec67", size = 18278, upload-time = "2024-08-06T13:43:17.612Z" }, { url = "https://files.pythonhosted.org/packages/49/47/46bf332f4ecd7f35e197131b9c23daa39423cf71b814e36e9d5df3cf2380/time_machine-2.15.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:a22f47c34ee1fcf7d93a8c5c93135499aac879d9d5d8f820bd28571a30fdabcd", size = 20436, upload-time = "2024-08-06T15:42:15.185Z" }, { url = "https://files.pythonhosted.org/packages/f1/36/9990f16868ffdefe6b5aecfdfbcb11718230e414ca61a887fbee884f70e5/time_machine-2.15.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b684f8ecdeacd6baabc17b15ac1b054ca62029193e6c5367ef00b3516671de80", size = 16926, upload-time = "2024-08-06T15:42:17.284Z" }, { url = "https://files.pythonhosted.org/packages/ca/2d/007955a0899cd079a400bc204c03edc76274de2471d94ca235ff587a6eba/time_machine-2.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f7add997684bc6141e1c80f6ba0c38ffe316ba277a4074e61b1b7b4f5a172bf", size = 17157, upload-time = "2024-08-06T11:12:16.25Z" }, { url = "https://files.pythonhosted.org/packages/7a/e2/66d26450f9bfd1b019abdefbf0c62e760efc8992c7bf88d6c18f7ea6b94a/time_machine-2.15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:31af56399bf7c9ef76a3f7b6d9471dffa8f06ee373c194a374b69523f9061de9", size = 34005, upload-time = "2024-08-06T15:42:22.266Z" }, { url = "https://files.pythonhosted.org/packages/46/2c/dc2c42200aee6b47a55274d984736f7507ecfbfd0345114ec511ec444bef/time_machine-2.15.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5b94cba3edfc54bcb3ab5be616a2f50fa48be438e5af970824efdf882d1bc31", size = 31926, upload-time = "2024-08-06T15:42:19.044Z" }, { url = "https://files.pythonhosted.org/packages/87/59/10d8faecbd233b0da831eb9973c3e650c83fb3d443edb607b6b26c9688ac/time_machine-2.15.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3862dda89bdb05f9d521b08fdcb24b19a7dd9f559ae324f4301ba7a07b6eea64", size = 33685, upload-time = "2024-08-06T15:42:20.565Z" }, { url = "https://files.pythonhosted.org/packages/2e/a4/702ad9e328cbc7b3f1833dee4886d0994e52bc2d9640effa64bccc7740fa/time_machine-2.15.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e1790481a6b9ce38888f22ce30710244067898c3ac4805a0e061e381f3db3506", size = 33609, upload-time = "2024-08-06T15:42:23.817Z" }, { url = "https://files.pythonhosted.org/packages/a0/9d/6009d28ad395a45b5bb91af31616494b4e61d6d9df252d0e5933cd3aa8f1/time_machine-2.15.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a731c03bc00552ee6cc685a59616d36003124e7e04c6ddf65c2c47f1c3d85480", size = 31737, upload-time = "2024-08-06T15:42:25.175Z" }, { url = "https://files.pythonhosted.org/packages/36/22/b55df08cf48d46af93ee2f4310dd88c8519bc5f98afd24af57a81a5d5272/time_machine-2.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e6776840aea3ff5ab6924b50117957da62db51b109b3b491c0d5817a804b1a8e", size = 33253, upload-time = "2024-08-06T15:42:26.511Z" }, { url = "https://files.pythonhosted.org/packages/52/d7/bb5e92f0b0268cd13baad874d82b0e964a847cf52740464abeec48dc1642/time_machine-2.15.0-cp312-cp312-win32.whl", hash = "sha256:9479530e3fce65f6149058071fa4df8150025f15b43b103445f619842981a87c", size = 19369, upload-time = "2024-08-06T15:42:27.682Z" }, { url = "https://files.pythonhosted.org/packages/f4/33/276537ba292fc7ee67e6aef7566b2a6b313dbc4d479e5e80eed43094ef48/time_machine-2.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:b5f3ab4185c1f72010846ca9fccb08349e23a2b52982a18d9870e848ce9f1c86", size = 20219, upload-time = "2024-08-06T15:42:29.475Z" }, { url = "https://files.pythonhosted.org/packages/e0/0e/e8b75032248f59a2bc5c125d3a41242b1e577caa07585c42b22373d6466d/time_machine-2.15.0-cp312-cp312-win_arm64.whl", hash = "sha256:c0473dfa8f17c6a9a250b2bd6a5b62af3aa7d22518f701649115f1085d5e35ab", size = 18297, upload-time = "2024-08-06T15:42:31.116Z" }, { url = "https://files.pythonhosted.org/packages/7c/a1/ebe212530628aa29a86a771ca77cb2d1ead667382cfa89a3fb849e3f0108/time_machine-2.15.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f50f10058b884d45cd8a50423bf561b1f9f9df7058abeb8b318700c8bcf4bb54", size = 20492, upload-time = "2024-08-06T13:43:20.546Z" }, { url = "https://files.pythonhosted.org/packages/29/0d/2a19951729e50d8809e161e533585c0be5ae39c0cf40140877353847b9b5/time_machine-2.15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:df6f618b98f0848fd8d07039541e10f23db679d8283f8719e870a98e1ef8e639", size = 16961, upload-time = "2024-08-06T13:43:23.227Z" }, { url = "https://files.pythonhosted.org/packages/85/eb/33cf2173758b128f55c880c492e17b70f6c325e7bee879f9b0171cfe02a0/time_machine-2.15.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52468a0784544eba708c0ae6bc5e8c5dcfd685495a60f7f74028662c984bd9cd", size = 34051, upload-time = "2024-08-06T13:43:26.529Z" }, { url = "https://files.pythonhosted.org/packages/e1/23/da9a7935a7be952ab6163caf976b6bad049f6e117f3a396ecc381b077cb6/time_machine-2.15.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c08800c28160f4d32ca510128b4e201a43c813e7a2dd53178fa79ebe050eba13", size = 31966, upload-time = "2024-08-06T13:43:24.344Z" }, { url = "https://files.pythonhosted.org/packages/0b/0d/a8e3cbd91ffa98b0fa50b6e29d03151f37aa04cca4dd658e33cdf2b4731e/time_machine-2.15.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65d395211736d9844537a530287a7c64b9fda1d353e899a0e1723986a0859154", size = 33727, upload-time = "2024-08-06T13:43:25.407Z" }, { url = "https://files.pythonhosted.org/packages/07/53/c084031980706517cfbae9f462e455d61c7cbf9b66a8a83bcc5b79d00836/time_machine-2.15.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3b177d334a35bf2ce103bfe4e0e416e4ee824dd33386ea73fa7491c17cc61897", size = 33690, upload-time = "2024-08-06T13:43:28.145Z" }, { url = "https://files.pythonhosted.org/packages/a0/30/5c87e8709ba00c893faf8a9bddf06abf317fdc6103fe78bdf99c53ab444f/time_machine-2.15.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9a6a9342fae113b12aab42c790880c549d9ba695b8deff27ee08096eedd67569", size = 31809, upload-time = "2024-08-06T13:43:29.645Z" }, { url = "https://files.pythonhosted.org/packages/04/7b/92ac7c556cd123bf8b23dbae3cf4a273c276110b87d0c4b5600c2cec8e70/time_machine-2.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bcbb25029ee8756f10c6473cea5ef21707a1d9a8752cdf29fad3a5f34aa4a313", size = 33325, upload-time = "2024-08-06T13:43:30.832Z" }, { url = "https://files.pythonhosted.org/packages/e9/71/36c74bab3d4e4385d31610b367da1535a36d17358df058e0920a7510e17c/time_machine-2.15.0-cp313-cp313-win32.whl", hash = "sha256:29b988b1f09f2a083b12b6b054787b799ae91ee15bb0e9de3e48f880e4d68674", size = 19397, upload-time = "2024-08-06T13:43:31.996Z" }, { url = "https://files.pythonhosted.org/packages/a4/69/ea5976c43a673894f2fa85a05b28a610b474472f393e59722a6946f7070b/time_machine-2.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:d828721dcbcb94b904a6b25df67c2513ecd24cd9e36694f38b9f0fa71c7c6103", size = 20242, upload-time = "2024-08-06T13:43:33.11Z" }, { url = "https://files.pythonhosted.org/packages/cc/c8/26367d0b8dfaf7445576fe0051bff61b8f5be752e7bf3e8807ed7fa3a343/time_machine-2.15.0-cp313-cp313-win_arm64.whl", hash = "sha256:008bd668d933b1a029c81805bcdc0132390c2545b103cf8e6709e3adbc37989d", size = 18337, upload-time = "2024-08-06T13:43:34.227Z" }, { url = "https://files.pythonhosted.org/packages/97/54/eeac8568cad4f3eb255cc78f1fa2c36147afd3fcba770283bf2b2a188b33/time_machine-2.15.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e99689f6c6b9ca6e2fc7a75d140e38c5a7985dab61fe1f4e506268f7e9844e05", size = 20674, upload-time = "2024-08-06T13:42:05.072Z" }, { url = "https://files.pythonhosted.org/packages/5c/82/488341de4c03c0856aaf5db74f2a8fe18dcc7657401334c54c4aa6cb0fc6/time_machine-2.15.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:671e88a6209a1cf415dc0f8c67d2b2d3b55b436cc63801a518f9800ebd752959", size = 16990, upload-time = "2024-08-06T13:42:07.508Z" }, { url = "https://files.pythonhosted.org/packages/9c/cc/0ca559e71be4eb05917d02364f4d356351b31dd0d6ff3c4c86fa4de0a03e/time_machine-2.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b2d28daf4cabc698aafb12135525d87dc1f2f893cbd29a8a6fe0d8d36d1342c", size = 35501, upload-time = "2024-08-06T13:42:12.348Z" }, { url = "https://files.pythonhosted.org/packages/92/a0/14905a5feecc6d2e87ebe6dd2b044358422836ed173071cdc1245aa5ec88/time_machine-2.15.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4cd9f057457d12604be18b623bcd5ae7d0b917ad66cb510ee1135d5f123666e2", size = 33430, upload-time = "2024-08-06T13:42:09.625Z" }, { url = "https://files.pythonhosted.org/packages/19/a4/282b65b4d835dfd7b863777cc4206bec375285bda884dc22bd1264716f6a/time_machine-2.15.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97dc6793e512a62ba9eab250134a2e67372c16ae9948e73d27c2ef355356e2e1", size = 35366, upload-time = "2024-08-06T13:42:10.957Z" }, { url = "https://files.pythonhosted.org/packages/93/8e/f7db3f641f1ff86b98594c9cf8d71c8d292cc2bde06c1369ce4745494cc5/time_machine-2.15.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:0630a32e9ebcf2fac3704365b31e271fef6eabd6fedfa404cd8dbd244f7fc84d", size = 34373, upload-time = "2024-08-06T13:42:13.419Z" }, { url = "https://files.pythonhosted.org/packages/3d/9f/8c8ac57ccb29e692e0940e58515a9afb844d2d11b7f057a0fe153bfe4877/time_machine-2.15.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:617c9a92d8d8f60d5ef39e76596620503752a09f834a218e5b83be352fdd6c91", size = 32667, upload-time = "2024-08-06T13:42:15.293Z" }, { url = "https://files.pythonhosted.org/packages/ec/e7/f0c6f9507b0bbfdec54d256b6efc9417ae1a01ce6320c2a42235b807cf86/time_machine-2.15.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:3f7eadd820e792de33a9ec91f8178a2b9088e4e8b9a166953419ddc4ec5f7cfe", size = 34070, upload-time = "2024-08-06T13:42:17.147Z" }, { url = "https://files.pythonhosted.org/packages/20/82/ac2d8343db8dade1372457d7a5694f069882d9eac110ddce2643ef0501aa/time_machine-2.15.0-cp38-cp38-win32.whl", hash = "sha256:b7b647684eb2e1fd1e5e6b101249d5fe9d6117c117b5e336ad8dd75af48d2d1f", size = 19396, upload-time = "2024-08-06T13:42:18.256Z" }, { url = "https://files.pythonhosted.org/packages/3a/12/ac7bb1e932536fce359e021a62c2a5a30c4e470293d6f8b2fb47077562dc/time_machine-2.15.0-cp38-cp38-win_amd64.whl", hash = "sha256:b48abd7745caec1a78a16a048966cde14ff6ccb04d471a7201532648d3f77d14", size = 20266, upload-time = "2024-08-06T13:42:20.304Z" }, { url = "https://files.pythonhosted.org/packages/ec/bf/d9689e1fa669e575c3ed57bf4f9205a9b5fbe703dc7ef89ba5ce9aa39a38/time_machine-2.15.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8c2b1c91b437133c672e374857eccb1dd2c2d9f8477ae3b35138382d5ef19846", size = 20775, upload-time = "2024-08-06T13:42:22.424Z" }, { url = "https://files.pythonhosted.org/packages/d8/4b/4314a7882b470c52cd527601107b1163e19d37fb1eb31eea0f8d73d0b178/time_machine-2.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:79bf1ef6850182e09d86e61fa31717da56014a3b2234afb025fca1f2a43ac07b", size = 17037, upload-time = "2024-08-06T13:42:23.539Z" }, { url = "https://files.pythonhosted.org/packages/f1/b8/adf2f8b8e10f6f5e498b0cddd103f6520144af53fb27b5a01eca50812a92/time_machine-2.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:658ea8477fa020f08435fb7277635eb0b50cd5206b9d4cbe10e9a5466b01f855", size = 34511, upload-time = "2024-08-06T13:42:28.63Z" }, { url = "https://files.pythonhosted.org/packages/e3/86/fda41a9e8115fd377f2d4d15c91a414f75cb8f2cd7f8bde974855a0f381f/time_machine-2.15.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c947135750d20f35acac290c34f1acf5771fc166a3fbc0e3816a97c756aaa5f5", size = 32533, upload-time = "2024-08-06T13:42:25.709Z" }, { url = "https://files.pythonhosted.org/packages/cb/7e/1e2e69fee659f00715f12392cabea1920245504862eab2caac6e3f30de5b/time_machine-2.15.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1dee3a0dd1866988c49a5d00564404db9bcdf49ca92f9c4e8b6c99609d64e698", size = 34348, upload-time = "2024-08-06T13:42:27.478Z" }, { url = "https://files.pythonhosted.org/packages/41/da/8db2df73ebe9f23af25b05f1720b108a145805a8c83d5ff8248e2d3cbcfa/time_machine-2.15.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c596920d6017702a36e3a43fd8110a84e87d6229f30b84bd5640cbae9b5145da", size = 34081, upload-time = "2024-08-06T13:42:29.742Z" }, { url = "https://files.pythonhosted.org/packages/a7/c7/9202404f8885257c09c98d3e5186b989b6b482a2983dc24c81bd0333e668/time_machine-2.15.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:014589d0edd4aa14f8d63985745565e8cbbe48461d6c004a96000b47f6b44e78", size = 32357, upload-time = "2024-08-06T13:42:30.884Z" }, { url = "https://files.pythonhosted.org/packages/4d/79/482a69c31259c3c2efcd9e73ea4a0a4d315103836c1667875612288bca28/time_machine-2.15.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5ff655716cd13a242eef8cf5d368074e8b396ff86508a5933e7cff4f2b3eb3c2", size = 33742, upload-time = "2024-08-06T13:42:33.213Z" }, { url = "https://files.pythonhosted.org/packages/f0/39/89725d12a3552bb9113528d8f9aa7188e1660b377b74e7d72e8ab5eeff06/time_machine-2.15.0-cp39-cp39-win32.whl", hash = "sha256:1168eebd7af7e6e3e2fd378c16ca917b97dd81c89a1f1f9e1daa985c81699d90", size = 19410, upload-time = "2024-08-06T13:42:34.333Z" }, { url = "https://files.pythonhosted.org/packages/89/0c/50e86c4a7b72d2bdc658492b13e804f933814f86f34c4350758d1ab87586/time_machine-2.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:c344eb09fcfbf71e5b5847d4f188fec98e1c3a976125ef571eac5f1c39e7a5e5", size = 20281, upload-time = "2024-08-06T13:42:36.174Z" }, { url = "https://files.pythonhosted.org/packages/f6/4d/f8ad3b0c50a268a9ea766c9533866bba6a7717a5324c84e356abb7347fa4/time_machine-2.15.0-cp39-cp39-win_arm64.whl", hash = "sha256:899f1a856b3bebb82b6cbc3c0014834b583b83f246b28e462a031ec1b766130b", size = 18387, upload-time = "2024-08-06T13:42:37.271Z" }, ] [[package]] name = "time-machine" version = "2.16.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.10'", "python_full_version == '3.9.*'", ] dependencies = [ { name = "python-dateutil", marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/fb/dd/5022939b9cadefe3af04f4012186c29b8afbe858b1ec2cfa38baeec94dab/time_machine-2.16.0.tar.gz", hash = "sha256:4a99acc273d2f98add23a89b94d4dd9e14969c01214c8514bfa78e4e9364c7e2", size = 24626, upload-time = "2024-10-08T14:21:59.734Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/79/47/32fdb8e70122edbc8be9db1f032d22b38e3d9ef0bf52c64470d0815cdb62/time_machine-2.16.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:09531af59fdfb39bfd24d28bd1e837eff5a5d98318509a31b6cfd57d27801e52", size = 20493, upload-time = "2024-10-08T14:20:51.241Z" }, { url = "https://files.pythonhosted.org/packages/b1/e6/f3bc391d5642e69299f2d1f0a46e7f98d1669e82b1e16c8cf3c6e4615059/time_machine-2.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:92d0b0f3c49f34dd76eb462f0afdc61ed1cb318c06c46d03e99b44ebb489bdad", size = 16757, upload-time = "2024-10-08T14:20:52.614Z" }, { url = "https://files.pythonhosted.org/packages/d4/7f/3a78d50fec64edd9964bf42b66a2e659a9846669ac8f705acc363ee79d3a/time_machine-2.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7c29616e18e2349a8766d5b6817920fc74e39c00fa375d202231e9d525a1b882", size = 34527, upload-time = "2024-10-08T14:20:53.714Z" }, { url = "https://files.pythonhosted.org/packages/61/00/7cf1324d8f8db8f5dab71c44ed1e9c11c4f1cecca9d4363abf44154aa13b/time_machine-2.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c1ceb6035a64cb00650e3ab203cf3faffac18576a3f3125c24df468b784077c7", size = 32537, upload-time = "2024-10-08T14:20:54.834Z" }, { url = "https://files.pythonhosted.org/packages/8e/c2/edf5ccb2fa529251eb7f1cfb34098c0ef236dbb88f0a6564d06f6f8378f5/time_machine-2.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64c205ea37b8c4ba232645335fc3b75bc2d03ce30f0a34649e36cae85652ee96", size = 34353, upload-time = "2024-10-08T14:20:56.414Z" }, { url = "https://files.pythonhosted.org/packages/a9/1e/178b9e3d0054300a4dd0485747c89359e5f719f090ae5165c88618793700/time_machine-2.16.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:dfe92412bd11104c4f0fb2da68653e6c45b41f7217319a83a8b66ed4f20148b3", size = 34045, upload-time = "2024-10-08T14:20:58.117Z" }, { url = "https://files.pythonhosted.org/packages/e5/4d/068ad9660f00f88a54f3ff7e9d423ed5c08a5f8147518f6c66fd0393dde7/time_machine-2.16.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:d5fe7a6284e3dce87ae13a25029c53542dd27a28d151f3ef362ec4dd9c3e45fd", size = 32356, upload-time = "2024-10-08T14:20:59.8Z" }, { url = "https://files.pythonhosted.org/packages/a5/25/c0f26294808946ec5b665f17a0072049a3f9e2468abc18aa8fe22580b4cf/time_machine-2.16.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c0fca3025266d88d1b48be162a43b7c2d91c81cc5b3bee9f01194678ffb9969a", size = 33737, upload-time = "2024-10-08T14:21:00.868Z" }, { url = "https://files.pythonhosted.org/packages/8b/d4/ae909a269828eaa7672e1201403976e794ea679ae7ba04fe0c0c0c65c2b6/time_machine-2.16.0-cp310-cp310-win32.whl", hash = "sha256:4149e17018af07a5756a1df84aea71e6e178598c358c860c6bfec42170fa7970", size = 19133, upload-time = "2024-10-08T14:21:01.975Z" }, { url = "https://files.pythonhosted.org/packages/7e/e7/5946d62d49e79b97c6772fe2918eccbd069d74effa8d50bdca4056502aeb/time_machine-2.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:01bc257e9418980a4922de94775be42a966e1a082fb01a1635917f9afc7b84ca", size = 19995, upload-time = "2024-10-08T14:21:03.001Z" }, { url = "https://files.pythonhosted.org/packages/54/cb/6507c6594f086bc955ff200cc4fd415d2ab229371ca3ba8fc3d27429a9cc/time_machine-2.16.0-cp310-cp310-win_arm64.whl", hash = "sha256:6895e3e84119594ab12847c928f619d40ae9cedd0755515dc154a5b5dc6edd9f", size = 18109, upload-time = "2024-10-08T14:21:04.712Z" }, { url = "https://files.pythonhosted.org/packages/38/7b/34aad93f75f86503dd1fa53bc120d8129fe4de83aef58ffa78c62b044ef9/time_machine-2.16.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8f936566ef9f09136a3d5db305961ef6d897b76b240c9ff4199144aed6dd4fe5", size = 20169, upload-time = "2024-10-08T14:21:06.288Z" }, { url = "https://files.pythonhosted.org/packages/68/cb/7d020d5c05d0460a4a96232b0777882ef989c1e6144d11ba984c4b0b4d1a/time_machine-2.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5886e23ede3478ca2a3e0a641f5d09dd784dfa9e48c96e8e5e31fc4fe77b6dc0", size = 16614, upload-time = "2024-10-08T14:21:07.253Z" }, { url = "https://files.pythonhosted.org/packages/0d/24/ce1ff76c9a4f3be88c2b947f2411a5a8019390734597d3106a151f8a9416/time_machine-2.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c76caf539fa4941e1817b7c482c87c65c52a1903fea761e84525955c6106fafb", size = 32507, upload-time = "2024-10-08T14:21:08.289Z" }, { url = "https://files.pythonhosted.org/packages/08/d7/ba1135587bd2ed105e59ed7e05969c913277d110fecc0ed871006ea3f763/time_machine-2.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:298aa423e07c8b21b991782f01d7749c871c792319c2af3e9755f9ab49033212", size = 30627, upload-time = "2024-10-08T14:21:09.246Z" }, { url = "https://files.pythonhosted.org/packages/da/c6/f490aaddc80c54238f4b8fe97870bbfe0d2c70fe4a57269badc94f5f38a6/time_machine-2.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3391ae9c484736850bb44ef125cbad52fe2d1b69e42c95dc88c43af8ead2cc7", size = 32362, upload-time = "2024-10-08T14:21:10.178Z" }, { url = "https://files.pythonhosted.org/packages/b1/f7/2522ae1c1995a39d6d8b7ee7efed47ec8bd7ff3240fdb2662a8b7e11b84a/time_machine-2.16.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:503e7ff507c2089699d91885fc5b9c8ff16774a7b6aff48b4dcee0c0a0685b61", size = 32188, upload-time = "2024-10-08T14:21:11.743Z" }, { url = "https://files.pythonhosted.org/packages/e9/53/b1ccb55f39e7e62660f852d7aedef438d2872ea9c73f64be46d0d3b3f3d7/time_machine-2.16.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:eee7b0fc4fbab2c6585ea17606c6548be83919c70deea0865409fe9fc2d8cdce", size = 30600, upload-time = "2024-10-08T14:21:12.728Z" }, { url = "https://files.pythonhosted.org/packages/19/1f/37a5a9333a2da35b0fc43e8ac693b82dd5492892131bc3cc0c8f5835af94/time_machine-2.16.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9db5e5b3ccdadaafa5730c2f9db44c38b013234c9ad01f87738907e19bdba268", size = 31896, upload-time = "2024-10-08T14:21:14.451Z" }, { url = "https://files.pythonhosted.org/packages/fc/97/e1a8bd64e5432adf47859cb63847b4472efc644b508602141c60ccf52112/time_machine-2.16.0-cp311-cp311-win32.whl", hash = "sha256:2552f0767bc10c9d668f108fef9b487809cdeb772439ce932e74136365c69baf", size = 19030, upload-time = "2024-10-08T14:21:15.662Z" }, { url = "https://files.pythonhosted.org/packages/34/c9/f4764e447aa9da4031c89da60fa69f4f73fd45571415788c298cbd4620e9/time_machine-2.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:12474fcdbc475aa6fe5275fe7224e685c5b9777f5939647f35980e9614ae7558", size = 19924, upload-time = "2024-10-08T14:21:17.324Z" }, { url = "https://files.pythonhosted.org/packages/8a/c0/788500d33656a044e3289b814106c2277209ac73316c00b9668012ce6027/time_machine-2.16.0-cp311-cp311-win_arm64.whl", hash = "sha256:ac2df0fa564356384515ed62cb6679f33f1f529435b16b0ec0f88414635dbe39", size = 17993, upload-time = "2024-10-08T14:21:18.346Z" }, { url = "https://files.pythonhosted.org/packages/4a/f4/603a84e7ae6427a53953db9f61b689dc6adf233e03c5f5ca907a901452fd/time_machine-2.16.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:84788f4d62a8b1bf5e499bb9b0e23ceceea21c415ad6030be6267ce3d639842f", size = 20155, upload-time = "2024-10-08T14:21:20.055Z" }, { url = "https://files.pythonhosted.org/packages/d8/94/dbe69aecb4b84be52d34814e63176c5ca61f38ee9e6ecda11104653405b5/time_machine-2.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:15ec236b6571730236a193d9d6c11d472432fc6ab54e85eac1c16d98ddcd71bf", size = 16640, upload-time = "2024-10-08T14:21:22.005Z" }, { url = "https://files.pythonhosted.org/packages/da/13/27f11be25d7bd298e033b9da93217e5b68309bf724b6e494cdadb471d00d/time_machine-2.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cedc989717c8b44a3881ac3d68ab5a95820448796c550de6a2149ed1525157f0", size = 33721, upload-time = "2024-10-08T14:21:23.059Z" }, { url = "https://files.pythonhosted.org/packages/e6/9d/70e4640fed1fd8122204ae825c688d0ef8c04f515ec6bf3c5f3086d6510e/time_machine-2.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d26d79de1c63a8c6586c75967e09b0ff306aa7e944a1eaddb74595c9b1839ca", size = 31646, upload-time = "2024-10-08T14:21:24.037Z" }, { url = "https://files.pythonhosted.org/packages/a1/cb/93bc0e51bea4e171a85151dbba3c3b3f612b50b953cd3076f5b4f0db9e14/time_machine-2.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:317b68b56a9c3731e0cf8886e0f94230727159e375988b36c60edce0ddbcb44a", size = 33403, upload-time = "2024-10-08T14:21:24.975Z" }, { url = "https://files.pythonhosted.org/packages/89/71/2c6a63ad4fbce3d62d46bbd9ac4433f30bade7f25978ce00815b905bcfcf/time_machine-2.16.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:43e1e18279759897be3293a255d53e6b1cb0364b69d9591d0b80c51e461c94b0", size = 33327, upload-time = "2024-10-08T14:21:25.958Z" }, { url = "https://files.pythonhosted.org/packages/68/4e/205c2b26763b8817cd6b8868242843800a1fbf275f2af35f5ba35ff2b01a/time_machine-2.16.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e43adb22def972a29d2b147999b56897116085777a0fea182fd93ee45730611e", size = 31454, upload-time = "2024-10-08T14:21:27.367Z" }, { url = "https://files.pythonhosted.org/packages/d7/95/44c1aa3994919f93534244c40cfd2fb9416d7686dc0c8b9b262c751b5118/time_machine-2.16.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0c766bea27a0600e36806d628ebc4b47178b12fcdfb6c24dc0a566a9c06bfe7f", size = 32972, upload-time = "2024-10-08T14:21:28.351Z" }, { url = "https://files.pythonhosted.org/packages/d4/ee/75243df9c7cf30f108758e887141a58e6544baaa46e2e647b9ccc56db819/time_machine-2.16.0-cp312-cp312-win32.whl", hash = "sha256:6dae82ab647d107817e013db82223e20a9853fa88543fec853ae326382d03c2e", size = 19078, upload-time = "2024-10-08T14:21:29.425Z" }, { url = "https://files.pythonhosted.org/packages/d4/7c/d4e67cc031f9653c92167ccf87d241e3208653d191c96ac79281c273ab92/time_machine-2.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:265462c77dc9576267c3c7f20707780a171a9fdbac93ac22e608c309efd68c33", size = 19923, upload-time = "2024-10-08T14:21:30.759Z" }, { url = "https://files.pythonhosted.org/packages/aa/b6/7047226fcb9afefe47fc80f605530535bf71ad99b6797f057abbfa4cd9a5/time_machine-2.16.0-cp312-cp312-win_arm64.whl", hash = "sha256:ef768e14768eebe3bb1196c0dece8e14c1c6991605721214a0c3c68cf77eb216", size = 18003, upload-time = "2024-10-08T14:21:32.662Z" }, { url = "https://files.pythonhosted.org/packages/a6/18/3087d0eb185cedbc82385f46bf16032ec7102a0e070205a2c88c4ecf9952/time_machine-2.16.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7751bf745d54e9e8b358c0afa332815da9b8a6194b26d0fd62876ab6c4d5c9c0", size = 20209, upload-time = "2024-10-08T14:21:34.222Z" }, { url = "https://files.pythonhosted.org/packages/03/a3/fcc3eaf69390402ecf491d718e533b6d0e06d944d77fc8d87be3a2839102/time_machine-2.16.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1784edf173ca840ba154de6eed000b5727f65ab92972c2f88cec5c4d6349c5f2", size = 16681, upload-time = "2024-10-08T14:21:35.14Z" }, { url = "https://files.pythonhosted.org/packages/a2/96/8b76d264014bf9dc21873218de50d67223c71736f87fe6c65e582f7c29ac/time_machine-2.16.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f5876a5682ce1f517e55d7ace2383432627889f6f7e338b961f99d684fd9e8d", size = 33768, upload-time = "2024-10-08T14:21:36.942Z" }, { url = "https://files.pythonhosted.org/packages/5c/13/59ae8259be02b6c657ef6e3b6952bf274b43849f6f35cc61a576c68ce301/time_machine-2.16.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:806672529a2e255cd901f244c9033767dc1fa53466d0d3e3e49565a1572a64fe", size = 31685, upload-time = "2024-10-08T14:21:37.881Z" }, { url = "https://files.pythonhosted.org/packages/3e/c1/9f142beb4d373a2a01ebb58d5117289315baa5131d880ec804db49e94bf7/time_machine-2.16.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:667b150fedb54acdca2a4bea5bf6da837b43e6dd12857301b48191f8803ba93f", size = 33447, upload-time = "2024-10-08T14:21:38.809Z" }, { url = "https://files.pythonhosted.org/packages/95/f7/ed9ecd93c2d38dca77d0a28e070020f3ce0fb23e0d4a6edb14bcfffa5526/time_machine-2.16.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:da3ae1028af240c0c46c79adf9c1acffecc6ed1701f2863b8132f5ceae6ae4b5", size = 33408, upload-time = "2024-10-08T14:21:39.785Z" }, { url = "https://files.pythonhosted.org/packages/91/40/d0d274d70fa2c4cad531745deb8c81346365beb0a2736be05a3acde8b94a/time_machine-2.16.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:520a814ea1b2706c89ab260a54023033d3015abef25c77873b83e3d7c1fafbb2", size = 31526, upload-time = "2024-10-08T14:21:40.769Z" }, { url = "https://files.pythonhosted.org/packages/1d/ba/a27cdbb324d9a6d779cde0d514d47b696b5a6a653705d4b511fd65ef1514/time_machine-2.16.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8243664438bb468408b29c6865958662d75e51f79c91842d2794fa22629eb697", size = 33042, upload-time = "2024-10-08T14:21:41.722Z" }, { url = "https://files.pythonhosted.org/packages/72/63/64e9156c9e38c18720d0cc41378168635241de44013ffe3dd5b099447eb0/time_machine-2.16.0-cp313-cp313-win32.whl", hash = "sha256:32d445ce20d25c60ab92153c073942b0bac9815bfbfd152ce3dcc225d15ce988", size = 19108, upload-time = "2024-10-08T14:21:43.596Z" }, { url = "https://files.pythonhosted.org/packages/3d/40/27f5738fbd50b78dcc0682c14417eac5a49ccf430525dd0c5a058be125a2/time_machine-2.16.0-cp313-cp313-win_amd64.whl", hash = "sha256:f6927dda86425f97ffda36131f297b1a601c64a6ee6838bfa0e6d3149c2f0d9f", size = 19935, upload-time = "2024-10-08T14:21:45.277Z" }, { url = "https://files.pythonhosted.org/packages/35/75/c4d8b2f0fe7dac22854d88a9c509d428e78ac4bf284bc54cfe83f75cc13b/time_machine-2.16.0-cp313-cp313-win_arm64.whl", hash = "sha256:4d3843143c46dddca6491a954bbd0abfd435681512ac343169560e9bab504129", size = 18047, upload-time = "2024-10-08T14:21:46.261Z" }, { url = "https://files.pythonhosted.org/packages/df/aa/6d4925b22f3f5f53e2bcb12923f2463cac8c7c2360ac55196d51546787a5/time_machine-2.16.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:23c5283c01b4f80b7dfbc88f3d8088c06c301b94b7c35366be498c2d7b308549", size = 20490, upload-time = "2024-10-08T14:21:47.248Z" }, { url = "https://files.pythonhosted.org/packages/b9/58/2bd28329c3c47de58c9234d177e809bed29d9e54729da79b5d0d8bc47e5e/time_machine-2.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ac95ae4529d7d85b251f9cf0f961a8a408ba285875811268f469d824a3b0b15a", size = 16753, upload-time = "2024-10-08T14:21:48.197Z" }, { url = "https://files.pythonhosted.org/packages/c3/47/c8d388d6e061be146cf357bce727221f1d1d60dff2a36b880cb26e1a3199/time_machine-2.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfb76674db946a74f0ca6e3b81caa8265e35dafe9b7005c7d2b8dd5bbd3825cf", size = 34228, upload-time = "2024-10-08T14:21:49.171Z" }, { url = "https://files.pythonhosted.org/packages/d2/be/b0fb8693f2e9dfb5b50c5a89bb1d6ff8d4705075722b7987c0f1e18c6694/time_machine-2.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0b6ff3ccde9b16bbc694a2b5facf2d8890554f3135ff626ed1429e270e3cc4f", size = 32250, upload-time = "2024-10-08T14:21:50.842Z" }, { url = "https://files.pythonhosted.org/packages/6a/bc/e827239b0020195f4e2fa4e7fdf248838bb49230be2bf374181fac892a92/time_machine-2.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1906ec6e26e6b803cd6aab28d420c87285b9c209ff2a69f82d12f82278f78bb", size = 34066, upload-time = "2024-10-08T14:21:51.815Z" }, { url = "https://files.pythonhosted.org/packages/39/a9/c962c702b94ca4c7fd8264bc9baed431bd92d4ee2aa698dd92ff6e864164/time_machine-2.16.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e46bd09c944ec7a20868abd2b83d7d7abdaf427775e9df3089b9226a122b340f", size = 33799, upload-time = "2024-10-08T14:21:52.813Z" }, { url = "https://files.pythonhosted.org/packages/34/5f/91df8e8465a2d5a168c25eebf5a62d813f30e01909c32749dbbd442b66db/time_machine-2.16.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:cac3e2b4101db296b150cb665e5461c03621e6ede6117fc9d5048c0ec96d6e7c", size = 32076, upload-time = "2024-10-08T14:21:53.79Z" }, { url = "https://files.pythonhosted.org/packages/04/45/bcc3304b545a15f614ecb12b277ec8d93fe0f67fa74e9e4b856e4ecba4c6/time_machine-2.16.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1e0dcc97cfec12ae306e3036746e7631cc7ef65c31889f7264c25217d4938367", size = 33460, upload-time = "2024-10-08T14:21:54.797Z" }, { url = "https://files.pythonhosted.org/packages/96/2c/9f14cd6fb912995e9984e67b8160071e8950cd7b0a787796d58b45324269/time_machine-2.16.0-cp39-cp39-win32.whl", hash = "sha256:c761d32d0c5d1fe5b71ac502e1bd5edec4598a7fc6f607b9b906b98e911148ce", size = 19133, upload-time = "2024-10-08T14:21:55.816Z" }, { url = "https://files.pythonhosted.org/packages/63/0b/95bfa4a2b3a893d91de8304d98edbeb4e29b864977ef36929aa6eda1357f/time_machine-2.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:ddfab1c622342f2945942c5c2d6be327656980e8f2d2b2ce0c022d0aa3711361", size = 19989, upload-time = "2024-10-08T14:21:57.59Z" }, { url = "https://files.pythonhosted.org/packages/30/36/470c7d77d3a5c7e6a5e29ac40495b8dd3b66f3058ab8bdc823706fec1353/time_machine-2.16.0-cp39-cp39-win_arm64.whl", hash = "sha256:2e08a4015d5d1aab2cb46c780e85b33efcd5cbe880bb363b282a6972e617b8bb", size = 18106, upload-time = "2024-10-08T14:21:58.6Z" }, ] [[package]] name = "tomli" version = "2.2.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175, upload-time = "2024-11-27T22:38:36.873Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077, upload-time = "2024-11-27T22:37:54.956Z" }, { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429, upload-time = "2024-11-27T22:37:56.698Z" }, { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067, upload-time = "2024-11-27T22:37:57.63Z" }, { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030, upload-time = "2024-11-27T22:37:59.344Z" }, { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898, upload-time = "2024-11-27T22:38:00.429Z" }, { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894, upload-time = "2024-11-27T22:38:02.094Z" }, { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319, upload-time = "2024-11-27T22:38:03.206Z" }, { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273, upload-time = "2024-11-27T22:38:04.217Z" }, { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310, upload-time = "2024-11-27T22:38:05.908Z" }, { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309, upload-time = "2024-11-27T22:38:06.812Z" }, { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762, upload-time = "2024-11-27T22:38:07.731Z" }, { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453, upload-time = "2024-11-27T22:38:09.384Z" }, { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486, upload-time = "2024-11-27T22:38:10.329Z" }, { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349, upload-time = "2024-11-27T22:38:11.443Z" }, { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159, upload-time = "2024-11-27T22:38:13.099Z" }, { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243, upload-time = "2024-11-27T22:38:14.766Z" }, { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645, upload-time = "2024-11-27T22:38:15.843Z" }, { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584, upload-time = "2024-11-27T22:38:17.645Z" }, { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875, upload-time = "2024-11-27T22:38:19.159Z" }, { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418, upload-time = "2024-11-27T22:38:20.064Z" }, { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708, upload-time = "2024-11-27T22:38:21.659Z" }, { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582, upload-time = "2024-11-27T22:38:22.693Z" }, { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543, upload-time = "2024-11-27T22:38:24.367Z" }, { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691, upload-time = "2024-11-27T22:38:26.081Z" }, { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170, upload-time = "2024-11-27T22:38:27.921Z" }, { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530, upload-time = "2024-11-27T22:38:29.591Z" }, { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666, upload-time = "2024-11-27T22:38:30.639Z" }, { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954, upload-time = "2024-11-27T22:38:31.702Z" }, { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724, upload-time = "2024-11-27T22:38:32.837Z" }, { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383, upload-time = "2024-11-27T22:38:34.455Z" }, { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257, upload-time = "2024-11-27T22:38:35.385Z" }, ] [[package]] name = "types-awscrt" version = "0.27.6" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/56/ce/5d84526a39f44c420ce61b16654193f8437d74b54f21597ea2ac65d89954/types_awscrt-0.27.6.tar.gz", hash = "sha256:9d3f1865a93b8b2c32f137514ac88cb048b5bc438739945ba19d972698995bfb", size = 16937, upload-time = "2025-08-13T01:54:54.659Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ac/af/e3d20e3e81d235b3964846adf46a334645a8a9b25a0d3d472743eb079552/types_awscrt-0.27.6-py3-none-any.whl", hash = "sha256:18aced46da00a57f02eb97637a32e5894dc5aa3dc6a905ba3e5ed85b9f3c526b", size = 39626, upload-time = "2025-08-13T01:54:53.454Z" }, ] [[package]] name = "types-s3transfer" version = "0.13.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/a5/c5/23946fac96c9dd5815ec97afd1c8ad6d22efa76c04a79a4823f2f67692a5/types_s3transfer-0.13.1.tar.gz", hash = "sha256:ce488d79fdd7d3b9d39071939121eca814ec65de3aa36bdce1f9189c0a61cc80", size = 14181, upload-time = "2025-08-31T16:57:06.93Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/8e/dc/b3f9b5c93eed6ffe768f4972661250584d5e4f248b548029026964373bcd/types_s3transfer-0.13.1-py3-none-any.whl", hash = "sha256:4ff730e464a3fd3785b5541f0f555c1bd02ad408cf82b6b7a95429f6b0d26b4a", size = 19617, upload-time = "2025-08-31T16:57:05.73Z" }, ] [[package]] name = "typing-extensions" version = "4.12.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321, upload-time = "2024-06-07T18:52:15.995Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438, upload-time = "2024-06-07T18:52:13.582Z" }, ] [[package]] name = "typing-inspection" version = "0.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions", marker = "(python_full_version >= '3.9' and extra != 'group-9-anthropic-pydantic-v1') or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/f8/b1/0c11f5058406b3af7609f121aaa6b609744687f1d158b3c3a5bf4cc94238/typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28", size = 75726, upload-time = "2025-05-21T18:55:23.885Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/17/69/cd203477f944c353c31bade965f880aa1061fd6bf05ded0726ca845b6ff7/typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51", size = 14552, upload-time = "2025-05-21T18:55:22.152Z" }, ] [[package]] name = "urllib3" version = "1.26.20" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version == '3.9.*'", "python_full_version < '3.9'", ] sdist = { url = "https://files.pythonhosted.org/packages/e4/e8/6ff5e6bc22095cfc59b6ea711b687e2b7ed4bdb373f7eeec370a97d7392f/urllib3-1.26.20.tar.gz", hash = "sha256:40c2dc0c681e47eb8f90e7e27bf6ff7df2e677421fd46756da1161c39ca70d32", size = 307380, upload-time = "2024-08-29T15:43:11.37Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/33/cf/8435d5a7159e2a9c83a95896ed596f68cf798005fe107cc655b5c5c14704/urllib3-1.26.20-py2.py3-none-any.whl", hash = "sha256:0ed14ccfbf1c30a9072c7ca157e4319b70d65f623e91e7b32fadb2853431016e", size = 144225, upload-time = "2024-08-29T15:43:08.921Z" }, ] [[package]] name = "urllib3" version = "2.5.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.10'", ] sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, ] [[package]] name = "wheel" version = "0.45.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/8a/98/2d9906746cdc6a6ef809ae6338005b3f21bb568bea3165cfc6a243fdc25c/wheel-0.45.1.tar.gz", hash = "sha256:661e1abd9198507b1409a20c02106d9670b2576e916d58f520316666abca6729", size = 107545, upload-time = "2024-11-23T00:18:23.513Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/0b/2c/87f3254fd8ffd29e4c02732eee68a83a1d3c346ae39bc6822dcbcb697f2b/wheel-0.45.1-py3-none-any.whl", hash = "sha256:708e7481cc80179af0e556bbf0cc00b8444c7321e2700b8d8580231d13017248", size = 72494, upload-time = "2024-11-23T00:18:21.207Z" }, ] [[package]] name = "yarl" version = "1.15.2" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] dependencies = [ { name = "idna", marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "multidict", version = "6.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "propcache", version = "0.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/06/e1/d5427a061819c9f885f58bb0467d02a523f1aec19f9e5f9c82ce950d90d3/yarl-1.15.2.tar.gz", hash = "sha256:a39c36f4218a5bb668b4f06874d676d35a035ee668e6e7e3538835c703634b84", size = 169318, upload-time = "2024-10-13T18:48:04.311Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/61/f8/6b1bbc6f597d8937ad8661c042aa6bdbbe46a3a6e38e2c04214b9c82e804/yarl-1.15.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e4ee8b8639070ff246ad3649294336b06db37a94bdea0d09ea491603e0be73b8", size = 136479, upload-time = "2024-10-13T18:44:32.077Z" }, { url = "https://files.pythonhosted.org/packages/61/e0/973c0d16b1cb710d318b55bd5d019a1ecd161d28670b07d8d9df9a83f51f/yarl-1.15.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a7cf963a357c5f00cb55b1955df8bbe68d2f2f65de065160a1c26b85a1e44172", size = 88671, upload-time = "2024-10-13T18:44:35.334Z" }, { url = "https://files.pythonhosted.org/packages/16/df/241cfa1cf33b96da2c8773b76fe3ee58e04cb09ecfe794986ec436ae97dc/yarl-1.15.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:43ebdcc120e2ca679dba01a779333a8ea76b50547b55e812b8b92818d604662c", size = 86578, upload-time = "2024-10-13T18:44:37.58Z" }, { url = "https://files.pythonhosted.org/packages/02/a4/ee2941d1f93600d921954a0850e20581159772304e7de49f60588e9128a2/yarl-1.15.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3433da95b51a75692dcf6cc8117a31410447c75a9a8187888f02ad45c0a86c50", size = 307212, upload-time = "2024-10-13T18:44:39.932Z" }, { url = "https://files.pythonhosted.org/packages/08/64/2e6561af430b092b21c7a867ae3079f62e1532d3e51fee765fd7a74cef6c/yarl-1.15.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38d0124fa992dbacd0c48b1b755d3ee0a9f924f427f95b0ef376556a24debf01", size = 321589, upload-time = "2024-10-13T18:44:42.527Z" }, { url = "https://files.pythonhosted.org/packages/f8/af/056ab318a7117fa70f6ab502ff880e47af973948d1d123aff397cd68499c/yarl-1.15.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ded1b1803151dd0f20a8945508786d57c2f97a50289b16f2629f85433e546d47", size = 319443, upload-time = "2024-10-13T18:44:45.03Z" }, { url = "https://files.pythonhosted.org/packages/99/d1/051b0bc2c90c9a2618bab10a9a9a61a96ddb28c7c54161a5c97f9e625205/yarl-1.15.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ace4cad790f3bf872c082366c9edd7f8f8f77afe3992b134cfc810332206884f", size = 310324, upload-time = "2024-10-13T18:44:47.675Z" }, { url = "https://files.pythonhosted.org/packages/23/1b/16df55016f9ac18457afda165031086bce240d8bcf494501fb1164368617/yarl-1.15.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c77494a2f2282d9bbbbcab7c227a4d1b4bb829875c96251f66fb5f3bae4fb053", size = 300428, upload-time = "2024-10-13T18:44:49.431Z" }, { url = "https://files.pythonhosted.org/packages/83/a5/5188d1c575139a8dfd90d463d56f831a018f41f833cdf39da6bd8a72ee08/yarl-1.15.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b7f227ca6db5a9fda0a2b935a2ea34a7267589ffc63c8045f0e4edb8d8dcf956", size = 307079, upload-time = "2024-10-13T18:44:51.96Z" }, { url = "https://files.pythonhosted.org/packages/ba/4e/2497f8f2b34d1a261bebdbe00066242eacc9a7dccd4f02ddf0995014290a/yarl-1.15.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:31561a5b4d8dbef1559b3600b045607cf804bae040f64b5f5bca77da38084a8a", size = 305835, upload-time = "2024-10-13T18:44:53.83Z" }, { url = "https://files.pythonhosted.org/packages/91/db/40a347e1f8086e287a53c72dc333198816885bc770e3ecafcf5eaeb59311/yarl-1.15.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3e52474256a7db9dcf3c5f4ca0b300fdea6c21cca0148c8891d03a025649d935", size = 311033, upload-time = "2024-10-13T18:44:56.464Z" }, { url = "https://files.pythonhosted.org/packages/2f/a6/1500e1e694616c25eed6bf8c1aacc0943f124696d2421a07ae5e9ee101a5/yarl-1.15.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:0e1af74a9529a1137c67c887ed9cde62cff53aa4d84a3adbec329f9ec47a3936", size = 326317, upload-time = "2024-10-13T18:44:59.015Z" }, { url = "https://files.pythonhosted.org/packages/37/db/868d4b59cc76932ce880cc9946cd0ae4ab111a718494a94cb50dd5b67d82/yarl-1.15.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:15c87339490100c63472a76d87fe7097a0835c705eb5ae79fd96e343473629ed", size = 324196, upload-time = "2024-10-13T18:45:00.772Z" }, { url = "https://files.pythonhosted.org/packages/bd/41/b6c917c2fde2601ee0b45c82a0c502dc93e746dea469d3a6d1d0a24749e8/yarl-1.15.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:74abb8709ea54cc483c4fb57fb17bb66f8e0f04438cff6ded322074dbd17c7ec", size = 317023, upload-time = "2024-10-13T18:45:03.427Z" }, { url = "https://files.pythonhosted.org/packages/b0/85/2cde6b656fd83c474f19606af3f7a3e94add8988760c87a101ee603e7b8f/yarl-1.15.2-cp310-cp310-win32.whl", hash = "sha256:ffd591e22b22f9cb48e472529db6a47203c41c2c5911ff0a52e85723196c0d75", size = 78136, upload-time = "2024-10-13T18:45:05.173Z" }, { url = "https://files.pythonhosted.org/packages/ef/3c/4414901b0588427870002b21d790bd1fad142a9a992a22e5037506d0ed9d/yarl-1.15.2-cp310-cp310-win_amd64.whl", hash = "sha256:1695497bb2a02a6de60064c9f077a4ae9c25c73624e0d43e3aa9d16d983073c2", size = 84231, upload-time = "2024-10-13T18:45:07.622Z" }, { url = "https://files.pythonhosted.org/packages/4a/59/3ae125c97a2a8571ea16fdf59fcbd288bc169e0005d1af9946a90ea831d9/yarl-1.15.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9fcda20b2de7042cc35cf911702fa3d8311bd40055a14446c1e62403684afdc5", size = 136492, upload-time = "2024-10-13T18:45:09.962Z" }, { url = "https://files.pythonhosted.org/packages/f9/2b/efa58f36b582db45b94c15e87803b775eb8a4ca0db558121a272e67f3564/yarl-1.15.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0545de8c688fbbf3088f9e8b801157923be4bf8e7b03e97c2ecd4dfa39e48e0e", size = 88614, upload-time = "2024-10-13T18:45:12.329Z" }, { url = "https://files.pythonhosted.org/packages/82/69/eb73c0453a2ff53194df485dc7427d54e6cb8d1180fcef53251a8e24d069/yarl-1.15.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fbda058a9a68bec347962595f50546a8a4a34fd7b0654a7b9697917dc2bf810d", size = 86607, upload-time = "2024-10-13T18:45:13.88Z" }, { url = "https://files.pythonhosted.org/packages/48/4e/89beaee3a4da0d1c6af1176d738cff415ff2ad3737785ee25382409fe3e3/yarl-1.15.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1ac2bc069f4a458634c26b101c2341b18da85cb96afe0015990507efec2e417", size = 334077, upload-time = "2024-10-13T18:45:16.217Z" }, { url = "https://files.pythonhosted.org/packages/da/e8/8fcaa7552093f94c3f327783e2171da0eaa71db0c267510898a575066b0f/yarl-1.15.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cd126498171f752dd85737ab1544329a4520c53eed3997f9b08aefbafb1cc53b", size = 347365, upload-time = "2024-10-13T18:45:18.812Z" }, { url = "https://files.pythonhosted.org/packages/be/fa/dc2002f82a89feab13a783d3e6b915a3a2e0e83314d9e3f6d845ee31bfcc/yarl-1.15.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3db817b4e95eb05c362e3b45dafe7144b18603e1211f4a5b36eb9522ecc62bcf", size = 344823, upload-time = "2024-10-13T18:45:20.644Z" }, { url = "https://files.pythonhosted.org/packages/ae/c8/c4a00fe7f2aa6970c2651df332a14c88f8baaedb2e32d6c3b8c8a003ea74/yarl-1.15.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:076b1ed2ac819933895b1a000904f62d615fe4533a5cf3e052ff9a1da560575c", size = 337132, upload-time = "2024-10-13T18:45:22.487Z" }, { url = "https://files.pythonhosted.org/packages/07/bf/84125f85f44bf2af03f3cf64e87214b42cd59dcc8a04960d610a9825f4d4/yarl-1.15.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f8cfd847e6b9ecf9f2f2531c8427035f291ec286c0a4944b0a9fce58c6446046", size = 326258, upload-time = "2024-10-13T18:45:25.049Z" }, { url = "https://files.pythonhosted.org/packages/00/19/73ad8122b2fa73fe22e32c24b82a6c053cf6c73e2f649b73f7ef97bee8d0/yarl-1.15.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:32b66be100ac5739065496c74c4b7f3015cef792c3174982809274d7e51b3e04", size = 336212, upload-time = "2024-10-13T18:45:26.808Z" }, { url = "https://files.pythonhosted.org/packages/39/1d/2fa4337d11f6587e9b7565f84eba549f2921494bc8b10bfe811079acaa70/yarl-1.15.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:34a2d76a1984cac04ff8b1bfc939ec9dc0914821264d4a9c8fd0ed6aa8d4cfd2", size = 330397, upload-time = "2024-10-13T18:45:29.112Z" }, { url = "https://files.pythonhosted.org/packages/39/ab/dce75e06806bcb4305966471ead03ce639d8230f4f52c32bd614d820c044/yarl-1.15.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0afad2cd484908f472c8fe2e8ef499facee54a0a6978be0e0cff67b1254fd747", size = 334985, upload-time = "2024-10-13T18:45:31.709Z" }, { url = "https://files.pythonhosted.org/packages/c1/98/3f679149347a5e34c952bf8f71a387bc96b3488fae81399a49f8b1a01134/yarl-1.15.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c68e820879ff39992c7f148113b46efcd6ec765a4865581f2902b3c43a5f4bbb", size = 356033, upload-time = "2024-10-13T18:45:34.325Z" }, { url = "https://files.pythonhosted.org/packages/f7/8c/96546061c19852d0a4b1b07084a58c2e8911db6bcf7838972cff542e09fb/yarl-1.15.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:98f68df80ec6ca3015186b2677c208c096d646ef37bbf8b49764ab4a38183931", size = 357710, upload-time = "2024-10-13T18:45:36.216Z" }, { url = "https://files.pythonhosted.org/packages/01/45/ade6fb3daf689816ebaddb3175c962731edf300425c3254c559b6d0dcc27/yarl-1.15.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3c56ec1eacd0a5d35b8a29f468659c47f4fe61b2cab948ca756c39b7617f0aa5", size = 345532, upload-time = "2024-10-13T18:45:38.123Z" }, { url = "https://files.pythonhosted.org/packages/e7/d7/8de800d3aecda0e64c43e8fc844f7effc8731a6099fa0c055738a2247504/yarl-1.15.2-cp311-cp311-win32.whl", hash = "sha256:eedc3f247ee7b3808ea07205f3e7d7879bc19ad3e6222195cd5fbf9988853e4d", size = 78250, upload-time = "2024-10-13T18:45:39.908Z" }, { url = "https://files.pythonhosted.org/packages/3a/6c/69058bbcfb0164f221aa30e0cd1a250f6babb01221e27c95058c51c498ca/yarl-1.15.2-cp311-cp311-win_amd64.whl", hash = "sha256:0ccaa1bc98751fbfcf53dc8dfdb90d96e98838010fc254180dd6707a6e8bb179", size = 84492, upload-time = "2024-10-13T18:45:42.286Z" }, { url = "https://files.pythonhosted.org/packages/e0/d1/17ff90e7e5b1a0b4ddad847f9ec6a214b87905e3a59d01bff9207ce2253b/yarl-1.15.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:82d5161e8cb8f36ec778fd7ac4d740415d84030f5b9ef8fe4da54784a1f46c94", size = 136721, upload-time = "2024-10-13T18:45:43.876Z" }, { url = "https://files.pythonhosted.org/packages/44/50/a64ca0577aeb9507f4b672f9c833d46cf8f1e042ce2e80c11753b936457d/yarl-1.15.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fa2bea05ff0a8fb4d8124498e00e02398f06d23cdadd0fe027d84a3f7afde31e", size = 88954, upload-time = "2024-10-13T18:45:46.305Z" }, { url = "https://files.pythonhosted.org/packages/c9/0a/a30d0b02046d4088c1fd32d85d025bd70ceb55f441213dee14d503694f41/yarl-1.15.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:99e12d2bf587b44deb74e0d6170fec37adb489964dbca656ec41a7cd8f2ff178", size = 86692, upload-time = "2024-10-13T18:45:47.992Z" }, { url = "https://files.pythonhosted.org/packages/06/0b/7613decb8baa26cba840d7ea2074bd3c5e27684cbcb6d06e7840d6c5226c/yarl-1.15.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:243fbbbf003754fe41b5bdf10ce1e7f80bcc70732b5b54222c124d6b4c2ab31c", size = 325762, upload-time = "2024-10-13T18:45:49.69Z" }, { url = "https://files.pythonhosted.org/packages/97/f5/b8c389a58d1eb08f89341fc1bbcc23a0341f7372185a0a0704dbdadba53a/yarl-1.15.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:856b7f1a7b98a8c31823285786bd566cf06226ac4f38b3ef462f593c608a9bd6", size = 335037, upload-time = "2024-10-13T18:45:51.932Z" }, { url = "https://files.pythonhosted.org/packages/cb/f9/d89b93a7bb8b66e01bf722dcc6fec15e11946e649e71414fd532b05c4d5d/yarl-1.15.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:553dad9af802a9ad1a6525e7528152a015b85fb8dbf764ebfc755c695f488367", size = 334221, upload-time = "2024-10-13T18:45:54.548Z" }, { url = "https://files.pythonhosted.org/packages/10/77/1db077601998e0831a540a690dcb0f450c31f64c492e993e2eaadfbc7d31/yarl-1.15.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:30c3ff305f6e06650a761c4393666f77384f1cc6c5c0251965d6bfa5fbc88f7f", size = 330167, upload-time = "2024-10-13T18:45:56.675Z" }, { url = "https://files.pythonhosted.org/packages/3b/c2/e5b7121662fd758656784fffcff2e411c593ec46dc9ec68e0859a2ffaee3/yarl-1.15.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:353665775be69bbfc6d54c8d134bfc533e332149faeddd631b0bc79df0897f46", size = 317472, upload-time = "2024-10-13T18:45:58.815Z" }, { url = "https://files.pythonhosted.org/packages/c6/f3/41e366c17e50782651b192ba06a71d53500cc351547816bf1928fb043c4f/yarl-1.15.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f4fe99ce44128c71233d0d72152db31ca119711dfc5f2c82385ad611d8d7f897", size = 330896, upload-time = "2024-10-13T18:46:01.126Z" }, { url = "https://files.pythonhosted.org/packages/79/a2/d72e501bc1e33e68a5a31f584fe4556ab71a50a27bfd607d023f097cc9bb/yarl-1.15.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:9c1e3ff4b89cdd2e1a24c214f141e848b9e0451f08d7d4963cb4108d4d798f1f", size = 328787, upload-time = "2024-10-13T18:46:02.991Z" }, { url = "https://files.pythonhosted.org/packages/9d/ba/890f7e1ea17f3c247748548eee876528ceb939e44566fa7d53baee57e5aa/yarl-1.15.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:711bdfae4e699a6d4f371137cbe9e740dc958530cb920eb6f43ff9551e17cfbc", size = 332631, upload-time = "2024-10-13T18:46:04.939Z" }, { url = "https://files.pythonhosted.org/packages/48/c7/27b34206fd5dfe76b2caa08bf22f9212b2d665d5bb2df8a6dd3af498dcf4/yarl-1.15.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4388c72174868884f76affcdd3656544c426407e0043c89b684d22fb265e04a5", size = 344023, upload-time = "2024-10-13T18:46:06.809Z" }, { url = "https://files.pythonhosted.org/packages/88/e7/730b130f4f02bd8b00479baf9a57fdea1dc927436ed1d6ba08fa5c36c68e/yarl-1.15.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:f0e1844ad47c7bd5d6fa784f1d4accc5f4168b48999303a868fe0f8597bde715", size = 352290, upload-time = "2024-10-13T18:46:08.676Z" }, { url = "https://files.pythonhosted.org/packages/84/9b/e8dda28f91a0af67098cddd455e6b540d3f682dda4c0de224215a57dee4a/yarl-1.15.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a5cafb02cf097a82d74403f7e0b6b9df3ffbfe8edf9415ea816314711764a27b", size = 343742, upload-time = "2024-10-13T18:46:10.583Z" }, { url = "https://files.pythonhosted.org/packages/66/47/b1c6bb85f2b66decbe189e27fcc956ab74670a068655df30ef9a2e15c379/yarl-1.15.2-cp312-cp312-win32.whl", hash = "sha256:156ececdf636143f508770bf8a3a0498de64da5abd890c7dbb42ca9e3b6c05b8", size = 78051, upload-time = "2024-10-13T18:46:12.671Z" }, { url = "https://files.pythonhosted.org/packages/7d/9e/1a897e5248ec53e96e9f15b3e6928efd5e75d322c6cf666f55c1c063e5c9/yarl-1.15.2-cp312-cp312-win_amd64.whl", hash = "sha256:435aca062444a7f0c884861d2e3ea79883bd1cd19d0a381928b69ae1b85bc51d", size = 84313, upload-time = "2024-10-13T18:46:15.237Z" }, { url = "https://files.pythonhosted.org/packages/46/ab/be3229898d7eb1149e6ba7fe44f873cf054d275a00b326f2a858c9ff7175/yarl-1.15.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:416f2e3beaeae81e2f7a45dc711258be5bdc79c940a9a270b266c0bec038fb84", size = 135006, upload-time = "2024-10-13T18:46:16.909Z" }, { url = "https://files.pythonhosted.org/packages/10/10/b91c186b1b0e63951f80481b3e6879bb9f7179d471fe7c4440c9e900e2a3/yarl-1.15.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:173563f3696124372831007e3d4b9821746964a95968628f7075d9231ac6bb33", size = 88121, upload-time = "2024-10-13T18:46:18.702Z" }, { url = "https://files.pythonhosted.org/packages/bf/1d/4ceaccf836b9591abfde775e84249b847ac4c6c14ee2dd8d15b5b3cede44/yarl-1.15.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9ce2e0f6123a60bd1a7f5ae3b2c49b240c12c132847f17aa990b841a417598a2", size = 85967, upload-time = "2024-10-13T18:46:20.354Z" }, { url = "https://files.pythonhosted.org/packages/93/bd/c924f22bdb2c5d0ca03a9e64ecc5e041aace138c2a91afff7e2f01edc3a1/yarl-1.15.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eaea112aed589131f73d50d570a6864728bd7c0c66ef6c9154ed7b59f24da611", size = 325615, upload-time = "2024-10-13T18:46:22.057Z" }, { url = "https://files.pythonhosted.org/packages/59/a5/6226accd5c01cafd57af0d249c7cf9dd12569cd9c78fbd93e8198e7a9d84/yarl-1.15.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4ca3b9f370f218cc2a0309542cab8d0acdfd66667e7c37d04d617012485f904", size = 334945, upload-time = "2024-10-13T18:46:24.184Z" }, { url = "https://files.pythonhosted.org/packages/4c/c1/cc6ccdd2bcd0ff7291602d5831754595260f8d2754642dfd34fef1791059/yarl-1.15.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23ec1d3c31882b2a8a69c801ef58ebf7bae2553211ebbddf04235be275a38548", size = 336701, upload-time = "2024-10-13T18:46:27.038Z" }, { url = "https://files.pythonhosted.org/packages/ef/ff/39a767ee249444e4b26ea998a526838238f8994c8f274befc1f94dacfb43/yarl-1.15.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75119badf45f7183e10e348edff5a76a94dc19ba9287d94001ff05e81475967b", size = 330977, upload-time = "2024-10-13T18:46:28.921Z" }, { url = "https://files.pythonhosted.org/packages/dd/ba/b1fed73f9d39e3e7be8f6786be5a2ab4399c21504c9168c3cadf6e441c2e/yarl-1.15.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78e6fdc976ec966b99e4daa3812fac0274cc28cd2b24b0d92462e2e5ef90d368", size = 317402, upload-time = "2024-10-13T18:46:30.86Z" }, { url = "https://files.pythonhosted.org/packages/82/e8/03e3ebb7f558374f29c04868b20ca484d7997f80a0a191490790a8c28058/yarl-1.15.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:8657d3f37f781d987037f9cc20bbc8b40425fa14380c87da0cb8dfce7c92d0fb", size = 331776, upload-time = "2024-10-13T18:46:33.037Z" }, { url = "https://files.pythonhosted.org/packages/1f/83/90b0f4fd1ecf2602ba4ac50ad0bbc463122208f52dd13f152bbc0d8417dd/yarl-1.15.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:93bed8a8084544c6efe8856c362af08a23e959340c87a95687fdbe9c9f280c8b", size = 331585, upload-time = "2024-10-13T18:46:35.275Z" }, { url = "https://files.pythonhosted.org/packages/c7/f6/1ed7e7f270ae5f9f1174c1f8597b29658f552fee101c26de8b2eb4ca147a/yarl-1.15.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:69d5856d526802cbda768d3e6246cd0d77450fa2a4bc2ea0ea14f0d972c2894b", size = 336395, upload-time = "2024-10-13T18:46:38.003Z" }, { url = "https://files.pythonhosted.org/packages/e0/3a/4354ed8812909d9ec54a92716a53259b09e6b664209231f2ec5e75f4820d/yarl-1.15.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:ccad2800dfdff34392448c4bf834be124f10a5bc102f254521d931c1c53c455a", size = 342810, upload-time = "2024-10-13T18:46:39.952Z" }, { url = "https://files.pythonhosted.org/packages/de/cc/39e55e16b1415a87f6d300064965d6cfb2ac8571e11339ccb7dada2444d9/yarl-1.15.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:a880372e2e5dbb9258a4e8ff43f13888039abb9dd6d515f28611c54361bc5644", size = 351441, upload-time = "2024-10-13T18:46:41.867Z" }, { url = "https://files.pythonhosted.org/packages/fb/19/5cd4757079dc9d9f3de3e3831719b695f709a8ce029e70b33350c9d082a7/yarl-1.15.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c998d0558805860503bc3a595994895ca0f7835e00668dadc673bbf7f5fbfcbe", size = 345875, upload-time = "2024-10-13T18:46:43.824Z" }, { url = "https://files.pythonhosted.org/packages/83/a0/ef09b54634f73417f1ea4a746456a4372c1b044f07b26e16fa241bd2d94e/yarl-1.15.2-cp313-cp313-win32.whl", hash = "sha256:533a28754e7f7439f217550a497bb026c54072dbe16402b183fdbca2431935a9", size = 302609, upload-time = "2024-10-13T18:46:45.828Z" }, { url = "https://files.pythonhosted.org/packages/20/9f/f39c37c17929d3975da84c737b96b606b68c495cc4ee86408f10523a1635/yarl-1.15.2-cp313-cp313-win_amd64.whl", hash = "sha256:5838f2b79dc8f96fdc44077c9e4e2e33d7089b10788464609df788eb97d03aad", size = 308252, upload-time = "2024-10-13T18:46:48.042Z" }, { url = "https://files.pythonhosted.org/packages/7b/1f/544439ce6b7a498327d57ff40f0cd4f24bf4b1c1daf76c8c962dca022e71/yarl-1.15.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fbbb63bed5fcd70cd3dd23a087cd78e4675fb5a2963b8af53f945cbbca79ae16", size = 138555, upload-time = "2024-10-13T18:46:50.448Z" }, { url = "https://files.pythonhosted.org/packages/e8/b7/d6f33e7a42832f1e8476d0aabe089be0586a9110b5dfc2cef93444dc7c21/yarl-1.15.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e2e93b88ecc8f74074012e18d679fb2e9c746f2a56f79cd5e2b1afcf2a8a786b", size = 89844, upload-time = "2024-10-13T18:46:52.297Z" }, { url = "https://files.pythonhosted.org/packages/93/34/ede8d8ed7350b4b21e33fc4eff71e08de31da697034969b41190132d421f/yarl-1.15.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:af8ff8d7dc07ce873f643de6dfbcd45dc3db2c87462e5c387267197f59e6d776", size = 87671, upload-time = "2024-10-13T18:46:54.104Z" }, { url = "https://files.pythonhosted.org/packages/fa/51/6d71e92bc54b5788b18f3dc29806f9ce37e12b7c610e8073357717f34b78/yarl-1.15.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:66f629632220a4e7858b58e4857927dd01a850a4cef2fb4044c8662787165cf7", size = 314558, upload-time = "2024-10-13T18:46:55.885Z" }, { url = "https://files.pythonhosted.org/packages/76/0a/f9ffe503b4ef77cd77c9eefd37717c092e26f2c2dbbdd45700f864831292/yarl-1.15.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:833547179c31f9bec39b49601d282d6f0ea1633620701288934c5f66d88c3e50", size = 327622, upload-time = "2024-10-13T18:46:58.173Z" }, { url = "https://files.pythonhosted.org/packages/8b/38/8eb602eeb153de0189d572dce4ed81b9b14f71de7c027d330b601b4fdcdc/yarl-1.15.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2aa738e0282be54eede1e3f36b81f1e46aee7ec7602aa563e81e0e8d7b67963f", size = 324447, upload-time = "2024-10-13T18:47:00.263Z" }, { url = "https://files.pythonhosted.org/packages/c2/1e/1c78c695a4c7b957b5665e46a89ea35df48511dbed301a05c0a8beed0cc3/yarl-1.15.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a13a07532e8e1c4a5a3afff0ca4553da23409fad65def1b71186fb867eeae8d", size = 319009, upload-time = "2024-10-13T18:47:02.417Z" }, { url = "https://files.pythonhosted.org/packages/06/a0/7ea93de4ca1991e7f92a8901dcd1585165f547d342f7c6f36f1ea58b75de/yarl-1.15.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c45817e3e6972109d1a2c65091504a537e257bc3c885b4e78a95baa96df6a3f8", size = 307760, upload-time = "2024-10-13T18:47:04.553Z" }, { url = "https://files.pythonhosted.org/packages/f4/b4/ceaa1f35cfb37fe06af3f7404438abf9a1262dc5df74dba37c90b0615e06/yarl-1.15.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:670eb11325ed3a6209339974b276811867defe52f4188fe18dc49855774fa9cf", size = 315038, upload-time = "2024-10-13T18:47:06.482Z" }, { url = "https://files.pythonhosted.org/packages/da/45/a2ca2b547c56550eefc39e45d61e4b42ae6dbb3e913810b5a0eb53e86412/yarl-1.15.2-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:d417a4f6943112fae3924bae2af7112562285848d9bcee737fc4ff7cbd450e6c", size = 312898, upload-time = "2024-10-13T18:47:09.291Z" }, { url = "https://files.pythonhosted.org/packages/ea/e0/f692ba36dedc5b0b22084bba558a7ede053841e247b7dd2adbb9d40450be/yarl-1.15.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:bc8936d06cd53fddd4892677d65e98af514c8d78c79864f418bbf78a4a2edde4", size = 319370, upload-time = "2024-10-13T18:47:11.647Z" }, { url = "https://files.pythonhosted.org/packages/b1/3f/0e382caf39958be6ae61d4bb0c82a68a3c45a494fc8cdc6f55c29757970e/yarl-1.15.2-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:954dde77c404084c2544e572f342aef384240b3e434e06cecc71597e95fd1ce7", size = 332429, upload-time = "2024-10-13T18:47:13.88Z" }, { url = "https://files.pythonhosted.org/packages/21/6b/c824a4a1c45d67b15b431d4ab83b63462bfcbc710065902e10fa5c2ffd9e/yarl-1.15.2-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:5bc0df728e4def5e15a754521e8882ba5a5121bd6b5a3a0ff7efda5d6558ab3d", size = 333143, upload-time = "2024-10-13T18:47:16.141Z" }, { url = "https://files.pythonhosted.org/packages/20/76/8af2a1d93fe95b04e284b5d55daaad33aae6e2f6254a1bcdb40e2752af6c/yarl-1.15.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:b71862a652f50babab4a43a487f157d26b464b1dedbcc0afda02fd64f3809d04", size = 326687, upload-time = "2024-10-13T18:47:18.179Z" }, { url = "https://files.pythonhosted.org/packages/1c/53/490830773f907ef8a311cc5d82e5830f75f7692c1adacbdb731d3f1246fd/yarl-1.15.2-cp38-cp38-win32.whl", hash = "sha256:63eab904f8630aed5a68f2d0aeab565dcfc595dc1bf0b91b71d9ddd43dea3aea", size = 78705, upload-time = "2024-10-13T18:47:20.876Z" }, { url = "https://files.pythonhosted.org/packages/9c/9d/d944e897abf37f50f4fa2d8d6f5fd0ed9413bc8327d3b4cc25ba9694e1ba/yarl-1.15.2-cp38-cp38-win_amd64.whl", hash = "sha256:2cf441c4b6e538ba0d2591574f95d3fdd33f1efafa864faa077d9636ecc0c4e9", size = 84998, upload-time = "2024-10-13T18:47:23.301Z" }, { url = "https://files.pythonhosted.org/packages/91/1c/1c9d08c29b10499348eedc038cf61b6d96d5ba0e0d69438975845939ed3c/yarl-1.15.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a32d58f4b521bb98b2c0aa9da407f8bd57ca81f34362bcb090e4a79e9924fefc", size = 138011, upload-time = "2024-10-13T18:47:25.002Z" }, { url = "https://files.pythonhosted.org/packages/d4/33/2d4a1418bae6d7883c1fcc493be7b6d6fe015919835adc9e8eeba472e9f7/yarl-1.15.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:766dcc00b943c089349d4060b935c76281f6be225e39994c2ccec3a2a36ad627", size = 89618, upload-time = "2024-10-13T18:47:27.587Z" }, { url = "https://files.pythonhosted.org/packages/78/2e/0024c674a376cfdc722a167a8f308f5779aca615cb7a28d67fbeabf3f697/yarl-1.15.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:bed1b5dbf90bad3bfc19439258c97873eab453c71d8b6869c136346acfe497e7", size = 87347, upload-time = "2024-10-13T18:47:29.671Z" }, { url = "https://files.pythonhosted.org/packages/c5/08/a01874dabd4ddf475c5c2adc86f7ac329f83a361ee513a97841720ab7b24/yarl-1.15.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed20a4bdc635f36cb19e630bfc644181dd075839b6fc84cac51c0f381ac472e2", size = 310438, upload-time = "2024-10-13T18:47:31.577Z" }, { url = "https://files.pythonhosted.org/packages/09/95/691bc6de2c1b0e9c8bbaa5f8f38118d16896ba1a069a09d1fb073d41a093/yarl-1.15.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d538df442c0d9665664ab6dd5fccd0110fa3b364914f9c85b3ef9b7b2e157980", size = 325384, upload-time = "2024-10-13T18:47:33.587Z" }, { url = "https://files.pythonhosted.org/packages/95/fd/fee11eb3337f48c62d39c5676e6a0e4e318e318900a901b609a3c45394df/yarl-1.15.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c6cf1d92edf936ceedc7afa61b07e9d78a27b15244aa46bbcd534c7458ee1b", size = 321820, upload-time = "2024-10-13T18:47:35.633Z" }, { url = "https://files.pythonhosted.org/packages/7a/ad/4a2c9bbebaefdce4a69899132f4bf086abbddb738dc6e794a31193bc0854/yarl-1.15.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce44217ad99ffad8027d2fde0269ae368c86db66ea0571c62a000798d69401fb", size = 314150, upload-time = "2024-10-13T18:47:37.693Z" }, { url = "https://files.pythonhosted.org/packages/38/7d/552c37bc6c4ae8ea900e44b6c05cb16d50dca72d3782ccd66f53e27e353f/yarl-1.15.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47a6000a7e833ebfe5886b56a31cb2ff12120b1efd4578a6fcc38df16cc77bd", size = 304202, upload-time = "2024-10-13T18:47:40.411Z" }, { url = "https://files.pythonhosted.org/packages/2e/f8/c22a158f3337f49775775ecef43fc097a98b20cdce37425b68b9c45a6f94/yarl-1.15.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e52f77a0cd246086afde8815039f3e16f8d2be51786c0a39b57104c563c5cbb0", size = 310311, upload-time = "2024-10-13T18:47:43.236Z" }, { url = "https://files.pythonhosted.org/packages/ce/e4/ebce06afa25c2a6c8e6c9a5915cbbc7940a37f3ec38e950e8f346ca908da/yarl-1.15.2-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:f9ca0e6ce7774dc7830dc0cc4bb6b3eec769db667f230e7c770a628c1aa5681b", size = 310645, upload-time = "2024-10-13T18:47:45.24Z" }, { url = "https://files.pythonhosted.org/packages/0a/34/5504cc8fbd1be959ec0a1e9e9f471fd438c37cb877b0178ce09085b36b51/yarl-1.15.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:136f9db0f53c0206db38b8cd0c985c78ded5fd596c9a86ce5c0b92afb91c3a19", size = 313328, upload-time = "2024-10-13T18:47:47.546Z" }, { url = "https://files.pythonhosted.org/packages/cf/e4/fb3f91a539c6505e347d7d75bc675d291228960ffd6481ced76a15412924/yarl-1.15.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:173866d9f7409c0fb514cf6e78952e65816600cb888c68b37b41147349fe0057", size = 330135, upload-time = "2024-10-13T18:47:50.279Z" }, { url = "https://files.pythonhosted.org/packages/e1/08/a0b27db813f0159e1c8a45f48852afded501de2f527e7613c4dcf436ecf7/yarl-1.15.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:6e840553c9c494a35e449a987ca2c4f8372668ee954a03a9a9685075228e5036", size = 327155, upload-time = "2024-10-13T18:47:52.337Z" }, { url = "https://files.pythonhosted.org/packages/97/4e/b3414dded12d0e2b52eb1964c21a8d8b68495b320004807de770f7b6b53a/yarl-1.15.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:458c0c65802d816a6b955cf3603186de79e8fdb46d4f19abaec4ef0a906f50a7", size = 320810, upload-time = "2024-10-13T18:47:55.067Z" }, { url = "https://files.pythonhosted.org/packages/bb/ca/e5149c55d1c9dcf3d5b48acd7c71ca8622fd2f61322d0386fe63ba106774/yarl-1.15.2-cp39-cp39-win32.whl", hash = "sha256:5b48388ded01f6f2429a8c55012bdbd1c2a0c3735b3e73e221649e524c34a58d", size = 78686, upload-time = "2024-10-13T18:47:57Z" }, { url = "https://files.pythonhosted.org/packages/b1/87/f56a80a1abaf65dbf138b821357b51b6cc061756bb7d93f08797950b3881/yarl-1.15.2-cp39-cp39-win_amd64.whl", hash = "sha256:81dadafb3aa124f86dc267a2168f71bbd2bfb163663661ab0038f6e4b8edb810", size = 84818, upload-time = "2024-10-13T18:47:58.76Z" }, { url = "https://files.pythonhosted.org/packages/46/cf/a28c494decc9c8776b0d7b729c68d26fdafefcedd8d2eab5d9cd767376b2/yarl-1.15.2-py3-none-any.whl", hash = "sha256:0d3105efab7c5c091609abacad33afff33bdff0035bece164c98bcf5a85ef90a", size = 38891, upload-time = "2024-10-13T18:48:00.883Z" }, ] [[package]] name = "yarl" version = "1.20.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.10'", "python_full_version == '3.9.*'", ] dependencies = [ { name = "idna", marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "multidict", version = "6.6.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, { name = "propcache", version = "0.3.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/3c/fb/efaa23fa4e45537b827620f04cf8f3cd658b76642205162e072703a5b963/yarl-1.20.1.tar.gz", hash = "sha256:d017a4997ee50c91fd5466cef416231bb82177b93b029906cefc542ce14c35ac", size = 186428, upload-time = "2025-06-10T00:46:09.923Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/cb/65/7fed0d774abf47487c64be14e9223749468922817b5e8792b8a64792a1bb/yarl-1.20.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6032e6da6abd41e4acda34d75a816012717000fa6839f37124a47fcefc49bec4", size = 132910, upload-time = "2025-06-10T00:42:31.108Z" }, { url = "https://files.pythonhosted.org/packages/8a/7b/988f55a52da99df9e56dc733b8e4e5a6ae2090081dc2754fc8fd34e60aa0/yarl-1.20.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2c7b34d804b8cf9b214f05015c4fee2ebe7ed05cf581e7192c06555c71f4446a", size = 90644, upload-time = "2025-06-10T00:42:33.851Z" }, { url = "https://files.pythonhosted.org/packages/f7/de/30d98f03e95d30c7e3cc093759982d038c8833ec2451001d45ef4854edc1/yarl-1.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0c869f2651cc77465f6cd01d938d91a11d9ea5d798738c1dc077f3de0b5e5fed", size = 89322, upload-time = "2025-06-10T00:42:35.688Z" }, { url = "https://files.pythonhosted.org/packages/e0/7a/f2f314f5ebfe9200724b0b748de2186b927acb334cf964fd312eb86fc286/yarl-1.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62915e6688eb4d180d93840cda4110995ad50c459bf931b8b3775b37c264af1e", size = 323786, upload-time = "2025-06-10T00:42:37.817Z" }, { url = "https://files.pythonhosted.org/packages/15/3f/718d26f189db96d993d14b984ce91de52e76309d0fd1d4296f34039856aa/yarl-1.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:41ebd28167bc6af8abb97fec1a399f412eec5fd61a3ccbe2305a18b84fb4ca73", size = 319627, upload-time = "2025-06-10T00:42:39.937Z" }, { url = "https://files.pythonhosted.org/packages/a5/76/8fcfbf5fa2369157b9898962a4a7d96764b287b085b5b3d9ffae69cdefd1/yarl-1.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:21242b4288a6d56f04ea193adde174b7e347ac46ce6bc84989ff7c1b1ecea84e", size = 339149, upload-time = "2025-06-10T00:42:42.627Z" }, { url = "https://files.pythonhosted.org/packages/3c/95/d7fc301cc4661785967acc04f54a4a42d5124905e27db27bb578aac49b5c/yarl-1.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bea21cdae6c7eb02ba02a475f37463abfe0a01f5d7200121b03e605d6a0439f8", size = 333327, upload-time = "2025-06-10T00:42:44.842Z" }, { url = "https://files.pythonhosted.org/packages/65/94/e21269718349582eee81efc5c1c08ee71c816bfc1585b77d0ec3f58089eb/yarl-1.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f8a891e4a22a89f5dde7862994485e19db246b70bb288d3ce73a34422e55b23", size = 326054, upload-time = "2025-06-10T00:42:47.149Z" }, { url = "https://files.pythonhosted.org/packages/32/ae/8616d1f07853704523519f6131d21f092e567c5af93de7e3e94b38d7f065/yarl-1.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dd803820d44c8853a109a34e3660e5a61beae12970da479cf44aa2954019bf70", size = 315035, upload-time = "2025-06-10T00:42:48.852Z" }, { url = "https://files.pythonhosted.org/packages/48/aa/0ace06280861ef055855333707db5e49c6e3a08840a7ce62682259d0a6c0/yarl-1.20.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b982fa7f74c80d5c0c7b5b38f908971e513380a10fecea528091405f519b9ebb", size = 338962, upload-time = "2025-06-10T00:42:51.024Z" }, { url = "https://files.pythonhosted.org/packages/20/52/1e9d0e6916f45a8fb50e6844f01cb34692455f1acd548606cbda8134cd1e/yarl-1.20.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:33f29ecfe0330c570d997bcf1afd304377f2e48f61447f37e846a6058a4d33b2", size = 335399, upload-time = "2025-06-10T00:42:53.007Z" }, { url = "https://files.pythonhosted.org/packages/f2/65/60452df742952c630e82f394cd409de10610481d9043aa14c61bf846b7b1/yarl-1.20.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:835ab2cfc74d5eb4a6a528c57f05688099da41cf4957cf08cad38647e4a83b30", size = 338649, upload-time = "2025-06-10T00:42:54.964Z" }, { url = "https://files.pythonhosted.org/packages/7b/f5/6cd4ff38dcde57a70f23719a838665ee17079640c77087404c3d34da6727/yarl-1.20.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:46b5e0ccf1943a9a6e766b2c2b8c732c55b34e28be57d8daa2b3c1d1d4009309", size = 358563, upload-time = "2025-06-10T00:42:57.28Z" }, { url = "https://files.pythonhosted.org/packages/d1/90/c42eefd79d0d8222cb3227bdd51b640c0c1d0aa33fe4cc86c36eccba77d3/yarl-1.20.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:df47c55f7d74127d1b11251fe6397d84afdde0d53b90bedb46a23c0e534f9d24", size = 357609, upload-time = "2025-06-10T00:42:59.055Z" }, { url = "https://files.pythonhosted.org/packages/03/c8/cea6b232cb4617514232e0f8a718153a95b5d82b5290711b201545825532/yarl-1.20.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:76d12524d05841276b0e22573f28d5fbcb67589836772ae9244d90dd7d66aa13", size = 350224, upload-time = "2025-06-10T00:43:01.248Z" }, { url = "https://files.pythonhosted.org/packages/ce/a3/eaa0ab9712f1f3d01faf43cf6f1f7210ce4ea4a7e9b28b489a2261ca8db9/yarl-1.20.1-cp310-cp310-win32.whl", hash = "sha256:6c4fbf6b02d70e512d7ade4b1f998f237137f1417ab07ec06358ea04f69134f8", size = 81753, upload-time = "2025-06-10T00:43:03.486Z" }, { url = "https://files.pythonhosted.org/packages/8f/34/e4abde70a9256465fe31c88ed02c3f8502b7b5dead693a4f350a06413f28/yarl-1.20.1-cp310-cp310-win_amd64.whl", hash = "sha256:aef6c4d69554d44b7f9d923245f8ad9a707d971e6209d51279196d8e8fe1ae16", size = 86817, upload-time = "2025-06-10T00:43:05.231Z" }, { url = "https://files.pythonhosted.org/packages/b1/18/893b50efc2350e47a874c5c2d67e55a0ea5df91186b2a6f5ac52eff887cd/yarl-1.20.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:47ee6188fea634bdfaeb2cc420f5b3b17332e6225ce88149a17c413c77ff269e", size = 133833, upload-time = "2025-06-10T00:43:07.393Z" }, { url = "https://files.pythonhosted.org/packages/89/ed/b8773448030e6fc47fa797f099ab9eab151a43a25717f9ac043844ad5ea3/yarl-1.20.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d0f6500f69e8402d513e5eedb77a4e1818691e8f45e6b687147963514d84b44b", size = 91070, upload-time = "2025-06-10T00:43:09.538Z" }, { url = "https://files.pythonhosted.org/packages/e3/e3/409bd17b1e42619bf69f60e4f031ce1ccb29bd7380117a55529e76933464/yarl-1.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7a8900a42fcdaad568de58887c7b2f602962356908eedb7628eaf6021a6e435b", size = 89818, upload-time = "2025-06-10T00:43:11.575Z" }, { url = "https://files.pythonhosted.org/packages/f8/77/64d8431a4d77c856eb2d82aa3de2ad6741365245a29b3a9543cd598ed8c5/yarl-1.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bad6d131fda8ef508b36be3ece16d0902e80b88ea7200f030a0f6c11d9e508d4", size = 347003, upload-time = "2025-06-10T00:43:14.088Z" }, { url = "https://files.pythonhosted.org/packages/8d/d2/0c7e4def093dcef0bd9fa22d4d24b023788b0a33b8d0088b51aa51e21e99/yarl-1.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:df018d92fe22aaebb679a7f89fe0c0f368ec497e3dda6cb81a567610f04501f1", size = 336537, upload-time = "2025-06-10T00:43:16.431Z" }, { url = "https://files.pythonhosted.org/packages/f0/f3/fc514f4b2cf02cb59d10cbfe228691d25929ce8f72a38db07d3febc3f706/yarl-1.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f969afbb0a9b63c18d0feecf0db09d164b7a44a053e78a7d05f5df163e43833", size = 362358, upload-time = "2025-06-10T00:43:18.704Z" }, { url = "https://files.pythonhosted.org/packages/ea/6d/a313ac8d8391381ff9006ac05f1d4331cee3b1efaa833a53d12253733255/yarl-1.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:812303eb4aa98e302886ccda58d6b099e3576b1b9276161469c25803a8db277d", size = 357362, upload-time = "2025-06-10T00:43:20.888Z" }, { url = "https://files.pythonhosted.org/packages/00/70/8f78a95d6935a70263d46caa3dd18e1f223cf2f2ff2037baa01a22bc5b22/yarl-1.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98c4a7d166635147924aa0bf9bfe8d8abad6fffa6102de9c99ea04a1376f91e8", size = 348979, upload-time = "2025-06-10T00:43:23.169Z" }, { url = "https://files.pythonhosted.org/packages/cb/05/42773027968968f4f15143553970ee36ead27038d627f457cc44bbbeecf3/yarl-1.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12e768f966538e81e6e7550f9086a6236b16e26cd964cf4df35349970f3551cf", size = 337274, upload-time = "2025-06-10T00:43:27.111Z" }, { url = "https://files.pythonhosted.org/packages/05/be/665634aa196954156741ea591d2f946f1b78ceee8bb8f28488bf28c0dd62/yarl-1.20.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fe41919b9d899661c5c28a8b4b0acf704510b88f27f0934ac7a7bebdd8938d5e", size = 363294, upload-time = "2025-06-10T00:43:28.96Z" }, { url = "https://files.pythonhosted.org/packages/eb/90/73448401d36fa4e210ece5579895731f190d5119c4b66b43b52182e88cd5/yarl-1.20.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:8601bc010d1d7780592f3fc1bdc6c72e2b6466ea34569778422943e1a1f3c389", size = 358169, upload-time = "2025-06-10T00:43:30.701Z" }, { url = "https://files.pythonhosted.org/packages/c3/b0/fce922d46dc1eb43c811f1889f7daa6001b27a4005587e94878570300881/yarl-1.20.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:daadbdc1f2a9033a2399c42646fbd46da7992e868a5fe9513860122d7fe7a73f", size = 362776, upload-time = "2025-06-10T00:43:32.51Z" }, { url = "https://files.pythonhosted.org/packages/f1/0d/b172628fce039dae8977fd22caeff3eeebffd52e86060413f5673767c427/yarl-1.20.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:03aa1e041727cb438ca762628109ef1333498b122e4c76dd858d186a37cec845", size = 381341, upload-time = "2025-06-10T00:43:34.543Z" }, { url = "https://files.pythonhosted.org/packages/6b/9b/5b886d7671f4580209e855974fe1cecec409aa4a89ea58b8f0560dc529b1/yarl-1.20.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:642980ef5e0fa1de5fa96d905c7e00cb2c47cb468bfcac5a18c58e27dbf8d8d1", size = 379988, upload-time = "2025-06-10T00:43:36.489Z" }, { url = "https://files.pythonhosted.org/packages/73/be/75ef5fd0fcd8f083a5d13f78fd3f009528132a1f2a1d7c925c39fa20aa79/yarl-1.20.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:86971e2795584fe8c002356d3b97ef6c61862720eeff03db2a7c86b678d85b3e", size = 371113, upload-time = "2025-06-10T00:43:38.592Z" }, { url = "https://files.pythonhosted.org/packages/50/4f/62faab3b479dfdcb741fe9e3f0323e2a7d5cd1ab2edc73221d57ad4834b2/yarl-1.20.1-cp311-cp311-win32.whl", hash = "sha256:597f40615b8d25812f14562699e287f0dcc035d25eb74da72cae043bb884d773", size = 81485, upload-time = "2025-06-10T00:43:41.038Z" }, { url = "https://files.pythonhosted.org/packages/f0/09/d9c7942f8f05c32ec72cd5c8e041c8b29b5807328b68b4801ff2511d4d5e/yarl-1.20.1-cp311-cp311-win_amd64.whl", hash = "sha256:26ef53a9e726e61e9cd1cda6b478f17e350fb5800b4bd1cd9fe81c4d91cfeb2e", size = 86686, upload-time = "2025-06-10T00:43:42.692Z" }, { url = "https://files.pythonhosted.org/packages/5f/9a/cb7fad7d73c69f296eda6815e4a2c7ed53fc70c2f136479a91c8e5fbdb6d/yarl-1.20.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdcc4cd244e58593a4379fe60fdee5ac0331f8eb70320a24d591a3be197b94a9", size = 133667, upload-time = "2025-06-10T00:43:44.369Z" }, { url = "https://files.pythonhosted.org/packages/67/38/688577a1cb1e656e3971fb66a3492501c5a5df56d99722e57c98249e5b8a/yarl-1.20.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b29a2c385a5f5b9c7d9347e5812b6f7ab267193c62d282a540b4fc528c8a9d2a", size = 91025, upload-time = "2025-06-10T00:43:46.295Z" }, { url = "https://files.pythonhosted.org/packages/50/ec/72991ae51febeb11a42813fc259f0d4c8e0507f2b74b5514618d8b640365/yarl-1.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1112ae8154186dfe2de4732197f59c05a83dc814849a5ced892b708033f40dc2", size = 89709, upload-time = "2025-06-10T00:43:48.22Z" }, { url = "https://files.pythonhosted.org/packages/99/da/4d798025490e89426e9f976702e5f9482005c548c579bdae792a4c37769e/yarl-1.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90bbd29c4fe234233f7fa2b9b121fb63c321830e5d05b45153a2ca68f7d310ee", size = 352287, upload-time = "2025-06-10T00:43:49.924Z" }, { url = "https://files.pythonhosted.org/packages/1a/26/54a15c6a567aac1c61b18aa0f4b8aa2e285a52d547d1be8bf48abe2b3991/yarl-1.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:680e19c7ce3710ac4cd964e90dad99bf9b5029372ba0c7cbfcd55e54d90ea819", size = 345429, upload-time = "2025-06-10T00:43:51.7Z" }, { url = "https://files.pythonhosted.org/packages/d6/95/9dcf2386cb875b234353b93ec43e40219e14900e046bf6ac118f94b1e353/yarl-1.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a979218c1fdb4246a05efc2cc23859d47c89af463a90b99b7c56094daf25a16", size = 365429, upload-time = "2025-06-10T00:43:53.494Z" }, { url = "https://files.pythonhosted.org/packages/91/b2/33a8750f6a4bc224242a635f5f2cff6d6ad5ba651f6edcccf721992c21a0/yarl-1.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255b468adf57b4a7b65d8aad5b5138dce6a0752c139965711bdcb81bc370e1b6", size = 363862, upload-time = "2025-06-10T00:43:55.766Z" }, { url = "https://files.pythonhosted.org/packages/98/28/3ab7acc5b51f4434b181b0cee8f1f4b77a65919700a355fb3617f9488874/yarl-1.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a97d67108e79cfe22e2b430d80d7571ae57d19f17cda8bb967057ca8a7bf5bfd", size = 355616, upload-time = "2025-06-10T00:43:58.056Z" }, { url = "https://files.pythonhosted.org/packages/36/a3/f666894aa947a371724ec7cd2e5daa78ee8a777b21509b4252dd7bd15e29/yarl-1.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8570d998db4ddbfb9a590b185a0a33dbf8aafb831d07a5257b4ec9948df9cb0a", size = 339954, upload-time = "2025-06-10T00:43:59.773Z" }, { url = "https://files.pythonhosted.org/packages/f1/81/5f466427e09773c04219d3450d7a1256138a010b6c9f0af2d48565e9ad13/yarl-1.20.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:97c75596019baae7c71ccf1d8cc4738bc08134060d0adfcbe5642f778d1dca38", size = 365575, upload-time = "2025-06-10T00:44:02.051Z" }, { url = "https://files.pythonhosted.org/packages/2e/e3/e4b0ad8403e97e6c9972dd587388940a032f030ebec196ab81a3b8e94d31/yarl-1.20.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1c48912653e63aef91ff988c5432832692ac5a1d8f0fb8a33091520b5bbe19ef", size = 365061, upload-time = "2025-06-10T00:44:04.196Z" }, { url = "https://files.pythonhosted.org/packages/ac/99/b8a142e79eb86c926f9f06452eb13ecb1bb5713bd01dc0038faf5452e544/yarl-1.20.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4c3ae28f3ae1563c50f3d37f064ddb1511ecc1d5584e88c6b7c63cf7702a6d5f", size = 364142, upload-time = "2025-06-10T00:44:06.527Z" }, { url = "https://files.pythonhosted.org/packages/34/f2/08ed34a4a506d82a1a3e5bab99ccd930a040f9b6449e9fd050320e45845c/yarl-1.20.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c5e9642f27036283550f5f57dc6156c51084b458570b9d0d96100c8bebb186a8", size = 381894, upload-time = "2025-06-10T00:44:08.379Z" }, { url = "https://files.pythonhosted.org/packages/92/f8/9a3fbf0968eac704f681726eff595dce9b49c8a25cd92bf83df209668285/yarl-1.20.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:2c26b0c49220d5799f7b22c6838409ee9bc58ee5c95361a4d7831f03cc225b5a", size = 383378, upload-time = "2025-06-10T00:44:10.51Z" }, { url = "https://files.pythonhosted.org/packages/af/85/9363f77bdfa1e4d690957cd39d192c4cacd1c58965df0470a4905253b54f/yarl-1.20.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:564ab3d517e3d01c408c67f2e5247aad4019dcf1969982aba3974b4093279004", size = 374069, upload-time = "2025-06-10T00:44:12.834Z" }, { url = "https://files.pythonhosted.org/packages/35/99/9918c8739ba271dcd935400cff8b32e3cd319eaf02fcd023d5dcd487a7c8/yarl-1.20.1-cp312-cp312-win32.whl", hash = "sha256:daea0d313868da1cf2fac6b2d3a25c6e3a9e879483244be38c8e6a41f1d876a5", size = 81249, upload-time = "2025-06-10T00:44:14.731Z" }, { url = "https://files.pythonhosted.org/packages/eb/83/5d9092950565481b413b31a23e75dd3418ff0a277d6e0abf3729d4d1ce25/yarl-1.20.1-cp312-cp312-win_amd64.whl", hash = "sha256:48ea7d7f9be0487339828a4de0360d7ce0efc06524a48e1810f945c45b813698", size = 86710, upload-time = "2025-06-10T00:44:16.716Z" }, { url = "https://files.pythonhosted.org/packages/8a/e1/2411b6d7f769a07687acee88a062af5833cf1966b7266f3d8dfb3d3dc7d3/yarl-1.20.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:0b5ff0fbb7c9f1b1b5ab53330acbfc5247893069e7716840c8e7d5bb7355038a", size = 131811, upload-time = "2025-06-10T00:44:18.933Z" }, { url = "https://files.pythonhosted.org/packages/b2/27/584394e1cb76fb771371770eccad35de400e7b434ce3142c2dd27392c968/yarl-1.20.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:14f326acd845c2b2e2eb38fb1346c94f7f3b01a4f5c788f8144f9b630bfff9a3", size = 90078, upload-time = "2025-06-10T00:44:20.635Z" }, { url = "https://files.pythonhosted.org/packages/bf/9a/3246ae92d4049099f52d9b0fe3486e3b500e29b7ea872d0f152966fc209d/yarl-1.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f60e4ad5db23f0b96e49c018596707c3ae89f5d0bd97f0ad3684bcbad899f1e7", size = 88748, upload-time = "2025-06-10T00:44:22.34Z" }, { url = "https://files.pythonhosted.org/packages/a3/25/35afe384e31115a1a801fbcf84012d7a066d89035befae7c5d4284df1e03/yarl-1.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:49bdd1b8e00ce57e68ba51916e4bb04461746e794e7c4d4bbc42ba2f18297691", size = 349595, upload-time = "2025-06-10T00:44:24.314Z" }, { url = "https://files.pythonhosted.org/packages/28/2d/8aca6cb2cabc8f12efcb82749b9cefecbccfc7b0384e56cd71058ccee433/yarl-1.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:66252d780b45189975abfed839616e8fd2dbacbdc262105ad7742c6ae58f3e31", size = 342616, upload-time = "2025-06-10T00:44:26.167Z" }, { url = "https://files.pythonhosted.org/packages/0b/e9/1312633d16b31acf0098d30440ca855e3492d66623dafb8e25b03d00c3da/yarl-1.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59174e7332f5d153d8f7452a102b103e2e74035ad085f404df2e40e663a22b28", size = 361324, upload-time = "2025-06-10T00:44:27.915Z" }, { url = "https://files.pythonhosted.org/packages/bc/a0/688cc99463f12f7669eec7c8acc71ef56a1521b99eab7cd3abb75af887b0/yarl-1.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e3968ec7d92a0c0f9ac34d5ecfd03869ec0cab0697c91a45db3fbbd95fe1b653", size = 359676, upload-time = "2025-06-10T00:44:30.041Z" }, { url = "https://files.pythonhosted.org/packages/af/44/46407d7f7a56e9a85a4c207724c9f2c545c060380718eea9088f222ba697/yarl-1.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1a4fbb50e14396ba3d375f68bfe02215d8e7bc3ec49da8341fe3157f59d2ff5", size = 352614, upload-time = "2025-06-10T00:44:32.171Z" }, { url = "https://files.pythonhosted.org/packages/b1/91/31163295e82b8d5485d31d9cf7754d973d41915cadce070491778d9c9825/yarl-1.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11a62c839c3a8eac2410e951301309426f368388ff2f33799052787035793b02", size = 336766, upload-time = "2025-06-10T00:44:34.494Z" }, { url = "https://files.pythonhosted.org/packages/b4/8e/c41a5bc482121f51c083c4c2bcd16b9e01e1cf8729e380273a952513a21f/yarl-1.20.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:041eaa14f73ff5a8986b4388ac6bb43a77f2ea09bf1913df7a35d4646db69e53", size = 364615, upload-time = "2025-06-10T00:44:36.856Z" }, { url = "https://files.pythonhosted.org/packages/e3/5b/61a3b054238d33d70ea06ebba7e58597891b71c699e247df35cc984ab393/yarl-1.20.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:377fae2fef158e8fd9d60b4c8751387b8d1fb121d3d0b8e9b0be07d1b41e83dc", size = 360982, upload-time = "2025-06-10T00:44:39.141Z" }, { url = "https://files.pythonhosted.org/packages/df/a3/6a72fb83f8d478cb201d14927bc8040af901811a88e0ff2da7842dd0ed19/yarl-1.20.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1c92f4390e407513f619d49319023664643d3339bd5e5a56a3bebe01bc67ec04", size = 369792, upload-time = "2025-06-10T00:44:40.934Z" }, { url = "https://files.pythonhosted.org/packages/7c/af/4cc3c36dfc7c077f8dedb561eb21f69e1e9f2456b91b593882b0b18c19dc/yarl-1.20.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d25ddcf954df1754ab0f86bb696af765c5bfaba39b74095f27eececa049ef9a4", size = 382049, upload-time = "2025-06-10T00:44:42.854Z" }, { url = "https://files.pythonhosted.org/packages/19/3a/e54e2c4752160115183a66dc9ee75a153f81f3ab2ba4bf79c3c53b33de34/yarl-1.20.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:909313577e9619dcff8c31a0ea2aa0a2a828341d92673015456b3ae492e7317b", size = 384774, upload-time = "2025-06-10T00:44:45.275Z" }, { url = "https://files.pythonhosted.org/packages/9c/20/200ae86dabfca89060ec6447649f219b4cbd94531e425e50d57e5f5ac330/yarl-1.20.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:793fd0580cb9664548c6b83c63b43c477212c0260891ddf86809e1c06c8b08f1", size = 374252, upload-time = "2025-06-10T00:44:47.31Z" }, { url = "https://files.pythonhosted.org/packages/83/75/11ee332f2f516b3d094e89448da73d557687f7d137d5a0f48c40ff211487/yarl-1.20.1-cp313-cp313-win32.whl", hash = "sha256:468f6e40285de5a5b3c44981ca3a319a4b208ccc07d526b20b12aeedcfa654b7", size = 81198, upload-time = "2025-06-10T00:44:49.164Z" }, { url = "https://files.pythonhosted.org/packages/ba/ba/39b1ecbf51620b40ab402b0fc817f0ff750f6d92712b44689c2c215be89d/yarl-1.20.1-cp313-cp313-win_amd64.whl", hash = "sha256:495b4ef2fea40596bfc0affe3837411d6aa3371abcf31aac0ccc4bdd64d4ef5c", size = 86346, upload-time = "2025-06-10T00:44:51.182Z" }, { url = "https://files.pythonhosted.org/packages/43/c7/669c52519dca4c95153c8ad96dd123c79f354a376346b198f438e56ffeb4/yarl-1.20.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:f60233b98423aab21d249a30eb27c389c14929f47be8430efa7dbd91493a729d", size = 138826, upload-time = "2025-06-10T00:44:52.883Z" }, { url = "https://files.pythonhosted.org/packages/6a/42/fc0053719b44f6ad04a75d7f05e0e9674d45ef62f2d9ad2c1163e5c05827/yarl-1.20.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:6f3eff4cc3f03d650d8755c6eefc844edde99d641d0dcf4da3ab27141a5f8ddf", size = 93217, upload-time = "2025-06-10T00:44:54.658Z" }, { url = "https://files.pythonhosted.org/packages/4f/7f/fa59c4c27e2a076bba0d959386e26eba77eb52ea4a0aac48e3515c186b4c/yarl-1.20.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:69ff8439d8ba832d6bed88af2c2b3445977eba9a4588b787b32945871c2444e3", size = 92700, upload-time = "2025-06-10T00:44:56.784Z" }, { url = "https://files.pythonhosted.org/packages/2f/d4/062b2f48e7c93481e88eff97a6312dca15ea200e959f23e96d8ab898c5b8/yarl-1.20.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cf34efa60eb81dd2645a2e13e00bb98b76c35ab5061a3989c7a70f78c85006d", size = 347644, upload-time = "2025-06-10T00:44:59.071Z" }, { url = "https://files.pythonhosted.org/packages/89/47/78b7f40d13c8f62b499cc702fdf69e090455518ae544c00a3bf4afc9fc77/yarl-1.20.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8e0fe9364ad0fddab2688ce72cb7a8e61ea42eff3c7caeeb83874a5d479c896c", size = 323452, upload-time = "2025-06-10T00:45:01.605Z" }, { url = "https://files.pythonhosted.org/packages/eb/2b/490d3b2dc66f52987d4ee0d3090a147ea67732ce6b4d61e362c1846d0d32/yarl-1.20.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f64fbf81878ba914562c672024089e3401974a39767747691c65080a67b18c1", size = 346378, upload-time = "2025-06-10T00:45:03.946Z" }, { url = "https://files.pythonhosted.org/packages/66/ad/775da9c8a94ce925d1537f939a4f17d782efef1f973039d821cbe4bcc211/yarl-1.20.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6342d643bf9a1de97e512e45e4b9560a043347e779a173250824f8b254bd5ce", size = 353261, upload-time = "2025-06-10T00:45:05.992Z" }, { url = "https://files.pythonhosted.org/packages/4b/23/0ed0922b47a4f5c6eb9065d5ff1e459747226ddce5c6a4c111e728c9f701/yarl-1.20.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56dac5f452ed25eef0f6e3c6a066c6ab68971d96a9fb441791cad0efba6140d3", size = 335987, upload-time = "2025-06-10T00:45:08.227Z" }, { url = "https://files.pythonhosted.org/packages/3e/49/bc728a7fe7d0e9336e2b78f0958a2d6b288ba89f25a1762407a222bf53c3/yarl-1.20.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7d7f497126d65e2cad8dc5f97d34c27b19199b6414a40cb36b52f41b79014be", size = 329361, upload-time = "2025-06-10T00:45:10.11Z" }, { url = "https://files.pythonhosted.org/packages/93/8f/b811b9d1f617c83c907e7082a76e2b92b655400e61730cd61a1f67178393/yarl-1.20.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:67e708dfb8e78d8a19169818eeb5c7a80717562de9051bf2413aca8e3696bf16", size = 346460, upload-time = "2025-06-10T00:45:12.055Z" }, { url = "https://files.pythonhosted.org/packages/70/fd/af94f04f275f95da2c3b8b5e1d49e3e79f1ed8b6ceb0f1664cbd902773ff/yarl-1.20.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:595c07bc79af2494365cc96ddeb772f76272364ef7c80fb892ef9d0649586513", size = 334486, upload-time = "2025-06-10T00:45:13.995Z" }, { url = "https://files.pythonhosted.org/packages/84/65/04c62e82704e7dd0a9b3f61dbaa8447f8507655fd16c51da0637b39b2910/yarl-1.20.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:7bdd2f80f4a7df852ab9ab49484a4dee8030023aa536df41f2d922fd57bf023f", size = 342219, upload-time = "2025-06-10T00:45:16.479Z" }, { url = "https://files.pythonhosted.org/packages/91/95/459ca62eb958381b342d94ab9a4b6aec1ddec1f7057c487e926f03c06d30/yarl-1.20.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:c03bfebc4ae8d862f853a9757199677ab74ec25424d0ebd68a0027e9c639a390", size = 350693, upload-time = "2025-06-10T00:45:18.399Z" }, { url = "https://files.pythonhosted.org/packages/a6/00/d393e82dd955ad20617abc546a8f1aee40534d599ff555ea053d0ec9bf03/yarl-1.20.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:344d1103e9c1523f32a5ed704d576172d2cabed3122ea90b1d4e11fe17c66458", size = 355803, upload-time = "2025-06-10T00:45:20.677Z" }, { url = "https://files.pythonhosted.org/packages/9e/ed/c5fb04869b99b717985e244fd93029c7a8e8febdfcffa06093e32d7d44e7/yarl-1.20.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:88cab98aa4e13e1ade8c141daeedd300a4603b7132819c484841bb7af3edce9e", size = 341709, upload-time = "2025-06-10T00:45:23.221Z" }, { url = "https://files.pythonhosted.org/packages/24/fd/725b8e73ac2a50e78a4534ac43c6addf5c1c2d65380dd48a9169cc6739a9/yarl-1.20.1-cp313-cp313t-win32.whl", hash = "sha256:b121ff6a7cbd4abc28985b6028235491941b9fe8fe226e6fdc539c977ea1739d", size = 86591, upload-time = "2025-06-10T00:45:25.793Z" }, { url = "https://files.pythonhosted.org/packages/94/c3/b2e9f38bc3e11191981d57ea08cab2166e74ea770024a646617c9cddd9f6/yarl-1.20.1-cp313-cp313t-win_amd64.whl", hash = "sha256:541d050a355bbbc27e55d906bc91cb6fe42f96c01413dd0f4ed5a5240513874f", size = 93003, upload-time = "2025-06-10T00:45:27.752Z" }, { url = "https://files.pythonhosted.org/packages/01/75/0d37402d208d025afa6b5b8eb80e466d267d3fd1927db8e317d29a94a4cb/yarl-1.20.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e42ba79e2efb6845ebab49c7bf20306c4edf74a0b20fc6b2ccdd1a219d12fad3", size = 134259, upload-time = "2025-06-10T00:45:29.882Z" }, { url = "https://files.pythonhosted.org/packages/73/84/1fb6c85ae0cf9901046f07d0ac9eb162f7ce6d95db541130aa542ed377e6/yarl-1.20.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:41493b9b7c312ac448b7f0a42a089dffe1d6e6e981a2d76205801a023ed26a2b", size = 91269, upload-time = "2025-06-10T00:45:32.917Z" }, { url = "https://files.pythonhosted.org/packages/f3/9c/eae746b24c4ea29a5accba9a06c197a70fa38a49c7df244e0d3951108861/yarl-1.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f5a5928ff5eb13408c62a968ac90d43f8322fd56d87008b8f9dabf3c0f6ee983", size = 89995, upload-time = "2025-06-10T00:45:35.066Z" }, { url = "https://files.pythonhosted.org/packages/fb/30/693e71003ec4bc1daf2e4cf7c478c417d0985e0a8e8f00b2230d517876fc/yarl-1.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30c41ad5d717b3961b2dd785593b67d386b73feca30522048d37298fee981805", size = 325253, upload-time = "2025-06-10T00:45:37.052Z" }, { url = "https://files.pythonhosted.org/packages/0f/a2/5264dbebf90763139aeb0b0b3154763239398400f754ae19a0518b654117/yarl-1.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:59febc3969b0781682b469d4aca1a5cab7505a4f7b85acf6db01fa500fa3f6ba", size = 320897, upload-time = "2025-06-10T00:45:39.962Z" }, { url = "https://files.pythonhosted.org/packages/e7/17/77c7a89b3c05856489777e922f41db79ab4faf58621886df40d812c7facd/yarl-1.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d2b6fb3622b7e5bf7a6e5b679a69326b4279e805ed1699d749739a61d242449e", size = 340696, upload-time = "2025-06-10T00:45:41.915Z" }, { url = "https://files.pythonhosted.org/packages/6d/55/28409330b8ef5f2f681f5b478150496ec9cf3309b149dab7ec8ab5cfa3f0/yarl-1.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:749d73611db8d26a6281086f859ea7ec08f9c4c56cec864e52028c8b328db723", size = 335064, upload-time = "2025-06-10T00:45:43.893Z" }, { url = "https://files.pythonhosted.org/packages/85/58/cb0257cbd4002828ff735f44d3c5b6966c4fd1fc8cc1cd3cd8a143fbc513/yarl-1.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9427925776096e664c39e131447aa20ec738bdd77c049c48ea5200db2237e000", size = 327256, upload-time = "2025-06-10T00:45:46.393Z" }, { url = "https://files.pythonhosted.org/packages/53/f6/c77960370cfa46f6fb3d6a5a79a49d3abfdb9ef92556badc2dcd2748bc2a/yarl-1.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff70f32aa316393eaf8222d518ce9118148eddb8a53073c2403863b41033eed5", size = 316389, upload-time = "2025-06-10T00:45:48.358Z" }, { url = "https://files.pythonhosted.org/packages/64/ab/be0b10b8e029553c10905b6b00c64ecad3ebc8ace44b02293a62579343f6/yarl-1.20.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c7ddf7a09f38667aea38801da8b8d6bfe81df767d9dfc8c88eb45827b195cd1c", size = 340481, upload-time = "2025-06-10T00:45:50.663Z" }, { url = "https://files.pythonhosted.org/packages/c5/c3/3f327bd3905a4916029bf5feb7f86dcf864c7704f099715f62155fb386b2/yarl-1.20.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:57edc88517d7fc62b174fcfb2e939fbc486a68315d648d7e74d07fac42cec240", size = 336941, upload-time = "2025-06-10T00:45:52.554Z" }, { url = "https://files.pythonhosted.org/packages/d1/42/040bdd5d3b3bb02b4a6ace4ed4075e02f85df964d6e6cb321795d2a6496a/yarl-1.20.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:dab096ce479d5894d62c26ff4f699ec9072269d514b4edd630a393223f45a0ee", size = 339936, upload-time = "2025-06-10T00:45:54.919Z" }, { url = "https://files.pythonhosted.org/packages/0d/1c/911867b8e8c7463b84dfdc275e0d99b04b66ad5132b503f184fe76be8ea4/yarl-1.20.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:14a85f3bd2d7bb255be7183e5d7d6e70add151a98edf56a770d6140f5d5f4010", size = 360163, upload-time = "2025-06-10T00:45:56.87Z" }, { url = "https://files.pythonhosted.org/packages/e2/31/8c389f6c6ca0379b57b2da87f1f126c834777b4931c5ee8427dd65d0ff6b/yarl-1.20.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2c89b5c792685dd9cd3fa9761c1b9f46fc240c2a3265483acc1565769996a3f8", size = 359108, upload-time = "2025-06-10T00:45:58.869Z" }, { url = "https://files.pythonhosted.org/packages/7f/09/ae4a649fb3964324c70a3e2b61f45e566d9ffc0affd2b974cbf628957673/yarl-1.20.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:69e9b141de5511021942a6866990aea6d111c9042235de90e08f94cf972ca03d", size = 351875, upload-time = "2025-06-10T00:46:01.45Z" }, { url = "https://files.pythonhosted.org/packages/8d/43/bbb4ed4c34d5bb62b48bf957f68cd43f736f79059d4f85225ab1ef80f4b9/yarl-1.20.1-cp39-cp39-win32.whl", hash = "sha256:b5f307337819cdfdbb40193cad84978a029f847b0a357fbe49f712063cfc4f06", size = 82293, upload-time = "2025-06-10T00:46:03.763Z" }, { url = "https://files.pythonhosted.org/packages/d7/cd/ce185848a7dba68ea69e932674b5c1a42a1852123584bccc5443120f857c/yarl-1.20.1-cp39-cp39-win_amd64.whl", hash = "sha256:eae7bfe2069f9c1c5b05fc7fe5d612e5bbc089a39309904ee8b829e322dcad00", size = 87385, upload-time = "2025-06-10T00:46:05.655Z" }, { url = "https://files.pythonhosted.org/packages/b4/2d/2345fce04cfd4bee161bf1e7d9cdc702e3e16109021035dbb24db654a622/yarl-1.20.1-py3-none-any.whl", hash = "sha256:83b8eb083fe4683c6115795d9fc1cfaf2cbbefb19b3a1cb68f6527460f483a77", size = 46542, upload-time = "2025-06-10T00:46:07.521Z" }, ] [[package]] name = "zipp" version = "3.20.2" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] sdist = { url = "https://files.pythonhosted.org/packages/54/bf/5c0000c44ebc80123ecbdddba1f5dcd94a5ada602a9c225d84b5aaa55e86/zipp-3.20.2.tar.gz", hash = "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29", size = 24199, upload-time = "2024-09-13T13:44:16.101Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/62/8b/5ba542fa83c90e09eac972fc9baca7a88e7e7ca4b221a89251954019308b/zipp-3.20.2-py3-none-any.whl", hash = "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350", size = 9200, upload-time = "2024-09-13T13:44:14.38Z" }, ] [[package]] name = "zipp" version = "3.21.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.10'", "python_full_version == '3.9.*'", ] sdist = { url = "https://files.pythonhosted.org/packages/3f/50/bad581df71744867e9468ebd0bcd6505de3b275e06f202c2cb016e3ff56f/zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4", size = 24545, upload-time = "2024-11-10T15:05:20.202Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b7/1a/7e4798e9339adc931158c9d69ecc34f5e6791489d469f5e50ec15e35f458/zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931", size = 9630, upload-time = "2024-11-10T15:05:19.275Z" }, ]