diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index ff261bad783..62c2d13f507 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -3,7 +3,6 @@ FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT} USER vscode -RUN curl -sSf https://rye.astral.sh/get | RYE_VERSION="0.44.0" RYE_INSTALL_OPTION="--yes" bash -ENV PATH=/home/vscode/.rye/shims:$PATH +COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ RUN echo "[[ -d .venv ]] && source .venv/bin/activate || export PATH=\$PATH" >> /home/vscode/.bashrc diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index c17fdc169fc..e01283d8ced 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -7,7 +7,7 @@ "context": ".." }, - "postStartCommand": "rye sync --all-features", + "postStartCommand": "uv sync --all-extras", "customizations": { "vscode": { @@ -20,7 +20,7 @@ "python.defaultInterpreterPath": ".venv/bin/python", "python.typeChecking": "basic", "terminal.integrated.env.linux": { - "PATH": "/home/vscode/.rye/shims:${env:PATH}" + "PATH": "${env:PATH}" } } } diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 830150bcdce..0794fd8d552 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,16 +28,13 @@ jobs: steps: - uses: actions/checkout@v6 - - name: Install Rye - run: | - curl -sSf https://rye.astral.sh/get | bash - echo "$HOME/.rye/shims" >> $GITHUB_PATH - env: - RYE_VERSION: '0.44.0' - RYE_INSTALL_OPTION: '--yes' + - name: Install uv + uses: astral-sh/setup-uv@v5 + with: + version: '0.10.2' - name: Install dependencies - run: rye sync --all-features + run: uv sync --all-extras - name: Run lints run: ./scripts/lint @@ -53,19 +50,16 @@ jobs: steps: - uses: actions/checkout@v6 - - name: Install Rye - run: | - curl -sSf https://rye.astral.sh/get | bash - echo "$HOME/.rye/shims" >> $GITHUB_PATH - env: - RYE_VERSION: '0.44.0' - RYE_INSTALL_OPTION: '--yes' + - name: Install uv + uses: astral-sh/setup-uv@v5 + with: + version: '0.10.2' - name: Install dependencies - run: rye sync --all-features + run: uv sync --all-extras - name: Run build - run: rye build + run: uv build - name: Get GitHub OIDC Token if: |- @@ -94,13 +88,10 @@ jobs: steps: - uses: actions/checkout@v6 - - name: Install Rye - run: | - curl -sSf https://rye.astral.sh/get | bash - echo "$HOME/.rye/shims" >> $GITHUB_PATH - env: - RYE_VERSION: '0.44.0' - RYE_INSTALL_OPTION: '--yes' + - name: Install uv + uses: astral-sh/setup-uv@v5 + with: + version: '0.10.2' - name: Bootstrap run: ./scripts/bootstrap @@ -117,16 +108,12 @@ jobs: steps: - uses: actions/checkout@v6 - - name: Install Rye - run: | - curl -sSf https://rye.astral.sh/get | bash - echo "$HOME/.rye/shims" >> $GITHUB_PATH - env: - RYE_VERSION: '0.44.0' - RYE_INSTALL_OPTION: '--yes' + - name: Install uv + uses: astral-sh/setup-uv@v5 + with: + version: '0.10.2' - name: Install dependencies - run: | - rye sync --all-features + run: uv sync --all-extras - env: CLOUDFLARE_ACCOUNT_ID: f037e56e89293a057740de681ac9abbe @@ -134,4 +121,4 @@ jobs: CLOUDFLARE_ZONE_ID: 0da42c8d2132a9ddaf714f9e7c920711 CLOUDFLARE_API_KEY: ${{ secrets.CLOUDFLARE_API_KEY }} run: | - rye run python ./examples/dns/record.py + uv run python ./examples/dns/record.py diff --git a/.github/workflows/detect-breaking-changes.yml b/.github/workflows/detect-breaking-changes.yml index b1ee63a0dd7..3a4894a9f32 100644 --- a/.github/workflows/detect-breaking-changes.yml +++ b/.github/workflows/detect-breaking-changes.yml @@ -22,19 +22,15 @@ jobs: # Ensure we can check out the pull request base in the script below. fetch-depth: ${{ env.FETCH_DEPTH }} - - name: Install Rye - run: | - curl -sSf https://rye.astral.sh/get | bash - echo "$HOME/.rye/shims" >> $GITHUB_PATH - env: - RYE_VERSION: '0.44.0' - RYE_INSTALL_OPTION: '--yes' + - name: Install uv + uses: astral-sh/setup-uv@v5 + with: + version: '0.10.2' - name: Install dependencies - run: | - rye sync --all-features + run: uv sync --all-extras - name: Detect removed symbols run: | - rye run python scripts/detect-breaking-changes.py "${{ github.event.pull_request.base.sha }}" + uv run python scripts/detect-breaking-changes.py "${{ github.event.pull_request.base.sha }}" - name: Detect breaking changes run: | diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index b711a25bda7..5d3e356c4f2 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -16,13 +16,10 @@ jobs: steps: - uses: actions/checkout@v6 - - name: Install Rye - run: | - curl -sSf https://rye.astral.sh/get | bash - echo "$HOME/.rye/shims" >> $GITHUB_PATH - env: - RYE_VERSION: '0.44.0' - RYE_INSTALL_OPTION: '--yes' + - name: Install uv + uses: astral-sh/setup-uv@v5 + with: + version: '0.9.13' - name: Publish to PyPI run: | diff --git a/.stats.yml b/.stats.yml index 1682359bc84..18f0f9afb04 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 2194 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare%2Fcloudflare-0ce49e6bb0d3819f135b9a567b661205fdf5df21cff157eab2b7abd7b5b50347.yml -openapi_spec_hash: 512a5bb3a32860590c8949765605d65a -config_hash: 5367ae3e3a9a0d6578c2756965a99e3a +configured_endpoints: 2200 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare%2Fcloudflare-a6c352830d1270d0abb5bb983058ea21815e1bb7d2e163965335dcb0e706f057.yml +openapi_spec_hash: eefd0341bf7de31f0e0fa3f4020bee7c +config_hash: a6f7ab07cd1fde3ee07c4cae6ed2d568 diff --git a/Brewfile b/Brewfile index 492ca37bb07..c43041ceff9 100644 --- a/Brewfile +++ b/Brewfile @@ -1,2 +1,2 @@ -brew "rye" +brew "uv" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 320cdedd0ff..0392e10e0aa 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,32 +1,32 @@ ## Setting up the environment -### With Rye +### With `uv` -We use [Rye](https://rye.astral.sh/) to manage dependencies because it will automatically provision a Python environment with the expected Python version. To set it up, run: +We use [uv](https://docs.astral.sh/uv/) to manage dependencies because it will automatically provision a Python environment with the expected Python version. To set it up, run: ```sh $ ./scripts/bootstrap ``` -Or [install Rye manually](https://rye.astral.sh/guide/installation/) and run: +Or [install uv manually](https://docs.astral.sh/uv/getting-started/installation/) and run: ```sh -$ rye sync --all-features +$ uv sync --all-extras ``` -You can then run scripts using `rye run python script.py` or by activating the virtual environment: +You can then run scripts using `uv run python script.py` or by manually activating the virtual environment: ```sh -# Activate the virtual environment - https://docs.python.org/3/library/venv.html#how-venvs-work +# manually activate - https://docs.python.org/3/library/venv.html#how-venvs-work $ source .venv/bin/activate -# now you can omit the `rye run` prefix +# now you can omit the `uv run` prefix $ python script.py ``` -### Without Rye +### Without `uv` -Alternatively if you don't want to install `Rye`, you can stick with the standard `pip` setup by ensuring you have the Python version specified in `.python-version`, create a virtual environment however you desire and then install dependencies using this command: +Alternatively if you don't want to install `uv`, you can stick with the standard `pip` setup by ensuring you have the Python version specified in `.python-version`, create a virtual environment however you desire and then install dependencies using this command: ```sh $ pip install -r requirements-dev.lock @@ -45,7 +45,7 @@ All files in the `examples/` directory are not modified by the generator and can ```py # add an example to examples/.py -#!/usr/bin/env -S rye run python +#!/usr/bin/env -S uv run python … ``` @@ -72,7 +72,7 @@ Building this package will create two files in the `dist/` directory, a `.tar.gz To create a distributable version of the library, all you have to do is run this command: ```sh -$ rye build +$ uv build # or $ python -m build ``` diff --git a/bin/publish-pypi b/bin/publish-pypi index 826054e9248..e72ca2fa409 100644 --- a/bin/publish-pypi +++ b/bin/publish-pypi @@ -1,6 +1,7 @@ #!/usr/bin/env bash set -eux +rm -rf dist mkdir -p dist -rye build --clean -rye publish --yes --token=$PYPI_TOKEN +uv build +uv publish --token=$PYPI_TOKEN diff --git a/noxfile.py b/noxfile.py deleted file mode 100644 index 53bca7ff2aa..00000000000 --- a/noxfile.py +++ /dev/null @@ -1,9 +0,0 @@ -import nox - - -@nox.session(reuse_venv=True, name="test-pydantic-v1") -def test_pydantic_v1(session: nox.Session) -> None: - session.install("-r", "requirements-dev.lock") - session.install("pydantic<2") - - session.run("pytest", "--showlocals", "--ignore=tests/functional", *session.posargs) diff --git a/pyproject.toml b/pyproject.toml index e3ea96e58e4..a79b693633d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,10 +43,19 @@ Repository = "https://github.com/cloudflare/cloudflare-python" [project.optional-dependencies] aiohttp = ["aiohttp", "httpx_aiohttp>=0.1.9"] -[tool.rye] +[tool.uv] managed = true -# version pins are in requirements-dev.lock -dev-dependencies = [ +required-version = ">=0.9" +conflicts = [ + [ + { group = "pydantic-v1" }, + { group = "pydantic-v2" }, + ], +] + +[dependency-groups] +# version pins are in uv.lock +dev = [ "pyright==1.1.399", "mypy==1.17", "respx", @@ -54,42 +63,19 @@ dev-dependencies = [ "pytest-asyncio", "ruff", "time-machine", - "nox", "dirty-equals>=0.6.0", "importlib-metadata>=6.7.0", "rich>=13.7.1", "pytest-xdist>=3.6.1", "griffe>=1", ] - -[tool.rye.scripts] -format = { chain = [ - "format:ruff", - "format:docs", - "fix:ruff", - # run formatting again to fix any inconsistencies when imports are stripped - "format:ruff", -]} -"format:docs" = "bash -c 'python scripts/utils/ruffen-docs.py README.md $(find . -type f -name api.md)'" -"format:ruff" = "ruff format" - -"lint" = { chain = [ - "check:ruff", - "typecheck", - "check:importable", -]} -"check:ruff" = "ruff check ." -"fix:ruff" = "ruff check --fix ." - -"check:importable" = "python -c 'import cloudflare'" - -typecheck = { chain = [ - "typecheck:pyright", - "typecheck:mypy" -]} -"typecheck:pyright" = "pyright" -"typecheck:verify-types" = "pyright --verifytypes cloudflare --ignoreexternal" -"typecheck:mypy" = "mypy ." +pydantic-v1 = [ + "pydantic>=1.9.0,<2", +] +pydantic-v2 = [ + "pydantic~=2.0 ; python_full_version < '3.14'", + "pydantic~=2.12 ; python_full_version >= '3.14'", +] [build-system] requires = ["hatchling==1.26.3", "hatch-fancy-pypi-readme"] diff --git a/requirements-dev.lock b/requirements-dev.lock index be86ad20d91..444b5b6e445 100644 --- a/requirements-dev.lock +++ b/requirements-dev.lock @@ -1,152 +1,114 @@ -# generated by rye -# use `rye lock` or `rye sync` to update this lockfile -# -# last locked with the following flags: -# pre: false -# features: [] -# all-features: true -# with-sources: false -# generate-hashes: false -# universal: false - --e file:. -aiohappyeyeballs==2.6.1 - # via aiohttp -aiohttp==3.13.3 - # via cloudflare - # via httpx-aiohttp -aiosignal==1.4.0 - # via aiohttp +# This file was autogenerated by uv via the following command: +# uv export -o requirements-dev.lock --no-hashes +-e . annotated-types==0.7.0 # via pydantic anyio==4.12.1 - # via cloudflare - # via httpx -argcomplete==3.6.3 - # via nox -async-timeout==5.0.1 - # via aiohttp -attrs==25.4.0 - # via aiohttp - # via nox -backports-asyncio-runner==1.2.0 + # via + # cloudflare + # httpx +backports-asyncio-runner==1.2.0 ; python_full_version < '3.11' # via pytest-asyncio certifi==2026.1.4 - # via httpcore - # via httpx + # via + # httpcore + # httpx colorama==0.4.6 - # via griffe -colorlog==6.10.1 - # via nox -dependency-groups==1.3.1 - # via nox + # via + # griffe + # pytest dirty-equals==0.11 -distlib==0.4.0 - # via virtualenv distro==1.9.0 # via cloudflare -exceptiongroup==1.3.1 - # via anyio - # via pytest +exceptiongroup==1.3.1 ; python_full_version < '3.11' + # via + # anyio + # pytest execnet==2.1.2 # via pytest-xdist -filelock==3.19.1 - # via virtualenv -frozenlist==1.8.0 - # via aiohttp - # via aiosignal -griffe==1.14.0 +griffe==1.14.0 ; python_full_version < '3.10' +griffe==1.15.0 ; python_full_version >= '3.10' h11==0.16.0 # via httpcore httpcore==1.0.9 # via httpx httpx==0.28.1 - # via cloudflare - # via httpx-aiohttp - # via respx -httpx-aiohttp==0.1.12 - # via cloudflare -humanize==4.13.0 - # via nox + # via + # cloudflare + # respx idna==3.11 - # via anyio - # via httpx - # via yarl + # via + # anyio + # httpx importlib-metadata==8.7.1 -iniconfig==2.1.0 +iniconfig==2.1.0 ; python_full_version < '3.10' # via pytest -markdown-it-py==3.0.0 +iniconfig==2.3.0 ; python_full_version >= '3.10' + # via pytest +markdown-it-py==3.0.0 ; python_full_version < '3.10' + # via rich +markdown-it-py==4.0.0 ; python_full_version >= '3.10' # via rich mdurl==0.1.2 # via markdown-it-py -multidict==6.7.0 - # via aiohttp - # via yarl mypy==1.17.0 mypy-extensions==1.1.0 # via mypy nodeenv==1.10.0 # via pyright -nox==2025.11.12 packaging==25.0 - # via dependency-groups - # via nox # via pytest pathspec==1.0.3 # via mypy -platformdirs==4.4.0 - # via virtualenv pluggy==1.6.0 # via pytest -propcache==0.4.1 - # via aiohttp - # via yarl pydantic==2.12.5 # via cloudflare pydantic-core==2.41.5 # via pydantic pygments==2.19.2 - # via pytest - # via rich + # via + # pytest + # rich pyright==1.1.399 -pytest==8.4.2 - # via pytest-asyncio - # via pytest-xdist -pytest-asyncio==1.2.0 +pytest==8.4.2 ; python_full_version < '3.10' + # via + # pytest-asyncio + # pytest-xdist +pytest==9.0.2 ; python_full_version >= '3.10' + # via + # pytest-asyncio + # pytest-xdist +pytest-asyncio==1.2.0 ; python_full_version < '3.10' +pytest-asyncio==1.3.0 ; python_full_version >= '3.10' pytest-xdist==3.8.0 -python-dateutil==2.9.0.post0 +python-dateutil==2.9.0.post0 ; python_full_version < '3.10' # via time-machine respx==0.22.0 rich==14.2.0 ruff==0.14.13 -six==1.17.0 +six==1.17.0 ; python_full_version < '3.10' # via python-dateutil sniffio==1.3.1 # via cloudflare -time-machine==2.19.0 -tomli==2.4.0 - # via dependency-groups - # via mypy - # via nox - # via pytest +time-machine==2.19.0 ; python_full_version < '3.10' +time-machine==3.2.0 ; python_full_version >= '3.10' +tomli==2.4.0 ; python_full_version < '3.11' + # via + # mypy + # pytest typing-extensions==4.15.0 - # via aiosignal - # via anyio - # via cloudflare - # via exceptiongroup - # via multidict - # via mypy - # via pydantic - # via pydantic-core - # via pyright - # via pytest-asyncio - # via typing-inspection - # via virtualenv + # via + # anyio + # cloudflare + # exceptiongroup + # mypy + # pydantic + # pydantic-core + # pyright + # pytest-asyncio + # typing-inspection typing-inspection==0.4.2 # via pydantic -virtualenv==20.36.1 - # via nox -yarl==1.22.0 - # via aiohttp zipp==3.23.0 # via importlib-metadata diff --git a/requirements.lock b/requirements.lock deleted file mode 100644 index 67880761fcb..00000000000 --- a/requirements.lock +++ /dev/null @@ -1,76 +0,0 @@ -# generated by rye -# use `rye lock` or `rye sync` to update this lockfile -# -# last locked with the following flags: -# pre: false -# features: [] -# all-features: true -# with-sources: false -# generate-hashes: false -# universal: false - --e file:. -aiohappyeyeballs==2.6.1 - # via aiohttp -aiohttp==3.13.3 - # via cloudflare - # via httpx-aiohttp -aiosignal==1.4.0 - # via aiohttp -annotated-types==0.7.0 - # via pydantic -anyio==4.12.1 - # via cloudflare - # via httpx -async-timeout==5.0.1 - # via aiohttp -attrs==25.4.0 - # via aiohttp -certifi==2026.1.4 - # via httpcore - # via httpx -distro==1.9.0 - # via cloudflare -exceptiongroup==1.3.1 - # via anyio -frozenlist==1.8.0 - # via aiohttp - # via aiosignal -h11==0.16.0 - # via httpcore -httpcore==1.0.9 - # via httpx -httpx==0.28.1 - # via cloudflare - # via httpx-aiohttp -httpx-aiohttp==0.1.12 - # via cloudflare -idna==3.11 - # via anyio - # via httpx - # via yarl -multidict==6.7.0 - # via aiohttp - # via yarl -propcache==0.4.1 - # via aiohttp - # via yarl -pydantic==2.12.5 - # via cloudflare -pydantic-core==2.41.5 - # via pydantic -sniffio==1.3.1 - # via cloudflare -typing-extensions==4.15.0 - # via aiosignal - # via anyio - # via cloudflare - # via exceptiongroup - # via multidict - # via pydantic - # via pydantic-core - # via typing-inspection -typing-inspection==0.4.2 - # via pydantic -yarl==1.22.0 - # via aiohttp diff --git a/scripts/bootstrap b/scripts/bootstrap index b430fee36d6..4638ec6943c 100755 --- a/scripts/bootstrap +++ b/scripts/bootstrap @@ -19,9 +19,12 @@ if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "$SKIP_BREW" != "1" ] } fi -echo "==> Installing Python dependencies…" +echo "==> Installing Python…" +uv python install -# experimental uv support makes installations significantly faster -rye config --set-bool behavior.use-uv=true +echo "==> Installing Python dependencies…" +uv sync --all-extras -rye sync --all-features +echo "==> Exporting Python dependencies…" +# note: `--no-hashes` is required because of https://github.com/pypa/pip/issues/4995 +uv export -o requirements-dev.lock --no-hashes diff --git a/scripts/format b/scripts/format index 667ec2d7af0..c8e1f69d252 100755 --- a/scripts/format +++ b/scripts/format @@ -4,5 +4,11 @@ set -e cd "$(dirname "$0")/.." -echo "==> Running formatters" -rye run format +echo "==> Running ruff" +uv run ruff format +uv run ruff check --fix . +# run formatting again to fix any inconsistencies when imports are stripped +uv run ruff format + +echo "==> Formatting docs" +uv run python scripts/utils/ruffen-docs.py README.md $(find . -type f -name api.md) diff --git a/scripts/lint b/scripts/lint index 3c726986511..1949ec0b8ef 100755 --- a/scripts/lint +++ b/scripts/lint @@ -5,12 +5,18 @@ set -e cd "$(dirname "$0")/.." if [ "$1" = "--fix" ]; then - echo "==> Running lints with --fix" - rye run fix:ruff + echo "==> Running ruff with --fix" + uv run ruff check . --fix else - echo "==> Running lints" - rye run lint + echo "==> Running ruff" + uv run ruff check . fi +echo "==> Running pyright" +uv run pyright + +echo "==> Running mypy" +uv run mypy . + echo "==> Making sure it imports" -rye run python -c 'import cloudflare' +uv run python -c 'import cloudflare' diff --git a/scripts/test b/scripts/test index dbeda2d2176..b56970b78e8 100755 --- a/scripts/test +++ b/scripts/test @@ -54,8 +54,31 @@ fi export DEFER_PYDANTIC_BUILD=false -echo "==> Running tests" -rye run pytest "$@" +# Note that we need to specify the patch version here so that uv +# won't use unstable (alpha, beta, rc) releases for the tests +PY_VERSION_MIN=">=3.9.0" +PY_VERSION_MAX=">=3.14.0" -echo "==> Running Pydantic v1 tests" -rye run nox -s test-pydantic-v1 -- "$@" +function run_tests() { + echo "==> Running tests with Pydantic v2" + uv run --isolated --all-extras pytest "$@" + + # Skip Pydantic v1 tests on latest Python (not supported) + if [[ "$UV_PYTHON" != "$PY_VERSION_MAX" ]]; then + echo "==> Running tests with Pydantic v1" + uv run --isolated --all-extras --group=pydantic-v1 pytest "$@" + fi +} + +# If UV_PYTHON is already set in the environment, just run the command once +if [[ -n "$UV_PYTHON" ]]; then + run_tests "$@" +else + # If UV_PYTHON is not set, run the command for min and max versions + + echo "==> Running tests for Python $PY_VERSION_MIN" + UV_PYTHON="$PY_VERSION_MIN" run_tests "$@" + + echo "==> Running tests for Python $PY_VERSION_MAX" + UV_PYTHON="$PY_VERSION_MAX" run_tests "$@" +fi diff --git a/src/cloudflare/resources/aisearch/instances/instances.py b/src/cloudflare/resources/aisearch/instances/instances.py index 44e302e2e3e..0b4aa0f18c3 100644 --- a/src/cloudflare/resources/aisearch/instances/instances.py +++ b/src/cloudflare/resources/aisearch/instances/instances.py @@ -192,7 +192,7 @@ def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InstanceCreateResponse: - """Create a new instances. + """Create a new instance. Args: id: AI Search instance ID. @@ -420,13 +420,10 @@ def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InstanceUpdateResponse: - """Update instances. + """ + Update instance. Args: - id: AI Search instance ID. - - Lowercase alphanumeric, hyphens, and underscores. - index_method: Controls which storage backends are used during indexing. Defaults to vector-only. @@ -496,7 +493,7 @@ def list( self, *, account_id: str, - namespace: Optional[str] | Omit = omit, + namespace: str | Omit = omit, order_by: Literal["created_at"] | Omit = omit, order_by_direction: Literal["asc", "desc"] | Omit = omit, page: int | Omit = omit, @@ -513,11 +510,17 @@ def list( List instances. Args: - order_by: Order By Column Name + namespace: Filter by namespace. - order_by_direction: Order By Direction + order_by: Field to order results by. - search: Search by id + order_by_direction: Order direction. + + page: Page number (1-indexed). + + per_page: Number of results per page. + + search: Filter instances whose id contains this string (case-insensitive). extra_headers: Send extra headers @@ -564,13 +567,10 @@ def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InstanceDeleteResponse: - """Delete instances. + """ + Delete instance. Args: - id: AI Search instance ID. - - Lowercase alphanumeric, hyphens, and underscores. - extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -693,13 +693,10 @@ def read( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InstanceReadResponse: - """Read instances. + """ + Read instance. Args: - id: AI Search instance ID. - - Lowercase alphanumeric, hyphens, and underscores. - extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -969,7 +966,7 @@ async def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InstanceCreateResponse: - """Create a new instances. + """Create a new instance. Args: id: AI Search instance ID. @@ -1197,13 +1194,10 @@ async def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InstanceUpdateResponse: - """Update instances. + """ + Update instance. Args: - id: AI Search instance ID. - - Lowercase alphanumeric, hyphens, and underscores. - index_method: Controls which storage backends are used during indexing. Defaults to vector-only. @@ -1273,7 +1267,7 @@ def list( self, *, account_id: str, - namespace: Optional[str] | Omit = omit, + namespace: str | Omit = omit, order_by: Literal["created_at"] | Omit = omit, order_by_direction: Literal["asc", "desc"] | Omit = omit, page: int | Omit = omit, @@ -1290,11 +1284,17 @@ def list( List instances. Args: - order_by: Order By Column Name + namespace: Filter by namespace. - order_by_direction: Order By Direction + order_by: Field to order results by. - search: Search by id + order_by_direction: Order direction. + + page: Page number (1-indexed). + + per_page: Number of results per page. + + search: Filter instances whose id contains this string (case-insensitive). extra_headers: Send extra headers @@ -1341,13 +1341,10 @@ async def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InstanceDeleteResponse: - """Delete instances. + """ + Delete instance. Args: - id: AI Search instance ID. - - Lowercase alphanumeric, hyphens, and underscores. - extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -1470,13 +1467,10 @@ async def read( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InstanceReadResponse: - """Read instances. + """ + Read instance. Args: - id: AI Search instance ID. - - Lowercase alphanumeric, hyphens, and underscores. - extra_headers: Send extra headers extra_query: Add additional query parameters to the request diff --git a/src/cloudflare/resources/aisearch/namespaces/instances/instances.py b/src/cloudflare/resources/aisearch/namespaces/instances/instances.py index 8618c213255..d13a23fec7b 100644 --- a/src/cloudflare/resources/aisearch/namespaces/instances/instances.py +++ b/src/cloudflare/resources/aisearch/namespaces/instances/instances.py @@ -205,7 +205,7 @@ def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InstanceCreateResponse: - """Create a new instances. + """Create a new instance. Args: id: AI Search instance ID. @@ -438,13 +438,10 @@ def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InstanceUpdateResponse: - """Update instances. + """ + Update instance. Args: - id: AI Search instance ID. - - Lowercase alphanumeric, hyphens, and underscores. - index_method: Controls which storage backends are used during indexing. Defaults to vector-only. @@ -522,7 +519,7 @@ def list( name: str, *, account_id: str, - namespace: Optional[str] | Omit = omit, + namespace: str | Omit = omit, order_by: Literal["created_at"] | Omit = omit, order_by_direction: Literal["asc", "desc"] | Omit = omit, page: int | Omit = omit, @@ -539,11 +536,17 @@ def list( List instances. Args: - order_by: Order By Column Name + namespace: Filter by namespace. - order_by_direction: Order By Direction + order_by: Field to order results by. - search: Search by id + order_by_direction: Order direction. + + page: Page number (1-indexed). + + per_page: Number of results per page. + + search: Filter instances whose id contains this string (case-insensitive). extra_headers: Send extra headers @@ -595,13 +598,10 @@ def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InstanceDeleteResponse: - """Delete instances. + """ + Delete instance. Args: - id: AI Search instance ID. - - Lowercase alphanumeric, hyphens, and underscores. - extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -738,13 +738,10 @@ def read( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InstanceReadResponse: - """Read instances. + """ + Read instance. Args: - id: AI Search instance ID. - - Lowercase alphanumeric, hyphens, and underscores. - extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -1042,7 +1039,7 @@ async def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InstanceCreateResponse: - """Create a new instances. + """Create a new instance. Args: id: AI Search instance ID. @@ -1275,13 +1272,10 @@ async def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InstanceUpdateResponse: - """Update instances. + """ + Update instance. Args: - id: AI Search instance ID. - - Lowercase alphanumeric, hyphens, and underscores. - index_method: Controls which storage backends are used during indexing. Defaults to vector-only. @@ -1359,7 +1353,7 @@ def list( name: str, *, account_id: str, - namespace: Optional[str] | Omit = omit, + namespace: str | Omit = omit, order_by: Literal["created_at"] | Omit = omit, order_by_direction: Literal["asc", "desc"] | Omit = omit, page: int | Omit = omit, @@ -1376,11 +1370,17 @@ def list( List instances. Args: - order_by: Order By Column Name + namespace: Filter by namespace. - order_by_direction: Order By Direction + order_by: Field to order results by. - search: Search by id + order_by_direction: Order direction. + + page: Page number (1-indexed). + + per_page: Number of results per page. + + search: Filter instances whose id contains this string (case-insensitive). extra_headers: Send extra headers @@ -1432,13 +1432,10 @@ async def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InstanceDeleteResponse: - """Delete instances. + """ + Delete instance. Args: - id: AI Search instance ID. - - Lowercase alphanumeric, hyphens, and underscores. - extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -1575,13 +1572,10 @@ async def read( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InstanceReadResponse: - """Read instances. + """ + Read instance. Args: - id: AI Search instance ID. - - Lowercase alphanumeric, hyphens, and underscores. - extra_headers: Send extra headers extra_query: Add additional query parameters to the request diff --git a/src/cloudflare/resources/aisearch/namespaces/instances/items.py b/src/cloudflare/resources/aisearch/namespaces/instances/items.py index ecd58bba6a1..5fd2ac78d1b 100644 --- a/src/cloudflare/resources/aisearch/namespaces/instances/items.py +++ b/src/cloudflare/resources/aisearch/namespaces/instances/items.py @@ -280,6 +280,7 @@ def create_or_update( name: str, key: str, next_action: Literal["INDEX"], + wait_for_completion: bool | 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, @@ -295,6 +296,12 @@ def create_or_update( key: Item key / filename. Must not exceed 128 characters. + wait_for_completion: Wait for indexing to fully complete before responding. On RAGs with vector + indexing enabled, this additionally waits for Vectorize ingestion confirmation + (up to 40s) so the returned item reflects a queryable state. On timeout the item + is returned in `running` state and the background alarm continues polling. + Defaults to false. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -320,6 +327,7 @@ def create_or_update( { "key": key, "next_action": next_action, + "wait_for_completion": wait_for_completion, }, item_create_or_update_params.ItemCreateOrUpdateParams, ), @@ -510,6 +518,7 @@ def sync( name: str, id: str, next_action: Literal["INDEX"], + wait_for_completion: bool | 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, @@ -524,6 +533,12 @@ def sync( Lowercase alphanumeric, hyphens, and underscores. + wait_for_completion: Wait for indexing to fully complete before responding. On RAGs with vector + indexing enabled, this additionally waits for Vectorize ingestion confirmation + (up to 40s) so the returned item reflects a queryable state. On timeout the item + is returned in `running` state and the background alarm continues polling. + Defaults to false. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -548,7 +563,13 @@ def sync( id=id, item_id=item_id, ), - body=maybe_transform({"next_action": next_action}, item_sync_params.ItemSyncParams), + body=maybe_transform( + { + "next_action": next_action, + "wait_for_completion": wait_for_completion, + }, + item_sync_params.ItemSyncParams, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -852,6 +873,7 @@ async def create_or_update( name: str, key: str, next_action: Literal["INDEX"], + wait_for_completion: bool | 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, @@ -867,6 +889,12 @@ async def create_or_update( key: Item key / filename. Must not exceed 128 characters. + wait_for_completion: Wait for indexing to fully complete before responding. On RAGs with vector + indexing enabled, this additionally waits for Vectorize ingestion confirmation + (up to 40s) so the returned item reflects a queryable state. On timeout the item + is returned in `running` state and the background alarm continues polling. + Defaults to false. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -892,6 +920,7 @@ async def create_or_update( { "key": key, "next_action": next_action, + "wait_for_completion": wait_for_completion, }, item_create_or_update_params.ItemCreateOrUpdateParams, ), @@ -1082,6 +1111,7 @@ async def sync( name: str, id: str, next_action: Literal["INDEX"], + wait_for_completion: bool | 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, @@ -1096,6 +1126,12 @@ async def sync( Lowercase alphanumeric, hyphens, and underscores. + wait_for_completion: Wait for indexing to fully complete before responding. On RAGs with vector + indexing enabled, this additionally waits for Vectorize ingestion confirmation + (up to 40s) so the returned item reflects a queryable state. On timeout the item + is returned in `running` state and the background alarm continues polling. + Defaults to false. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -1120,7 +1156,13 @@ async def sync( id=id, item_id=item_id, ), - body=await async_maybe_transform({"next_action": next_action}, item_sync_params.ItemSyncParams), + body=await async_maybe_transform( + { + "next_action": next_action, + "wait_for_completion": wait_for_completion, + }, + item_sync_params.ItemSyncParams, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, diff --git a/src/cloudflare/resources/api_gateway/operations/operations.py b/src/cloudflare/resources/api_gateway/operations/operations.py index 3850a9a70ec..cd3ba74b2fd 100644 --- a/src/cloudflare/resources/api_gateway/operations/operations.py +++ b/src/cloudflare/resources/api_gateway/operations/operations.py @@ -354,6 +354,7 @@ def get( *, zone_id: str, feature: List[Literal["thresholds", "parameter_schemas", "schema_info"]] | Omit = omit, + with_schemas: bool | 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, @@ -374,6 +375,10 @@ def get( to the resulting feature object. Have a look at the top-level object description for more details on the specific meaning. + with_schemas: When true, includes OpenAPI schemas (both uploaded and learned) for the + operation in the response. Due to the conversion overhead, this parameter is + only supported on single-operation retrieval. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -395,7 +400,13 @@ def get( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=maybe_transform({"feature": feature}, operation_get_params.OperationGetParams), + query=maybe_transform( + { + "feature": feature, + "with_schemas": with_schemas, + }, + operation_get_params.OperationGetParams, + ), post_parser=ResultWrapper[OperationGetResponse]._unwrapper, ), cast_to=cast(Type[OperationGetResponse], ResultWrapper[OperationGetResponse]), @@ -704,6 +715,7 @@ async def get( *, zone_id: str, feature: List[Literal["thresholds", "parameter_schemas", "schema_info"]] | Omit = omit, + with_schemas: bool | 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, @@ -724,6 +736,10 @@ async def get( to the resulting feature object. Have a look at the top-level object description for more details on the specific meaning. + with_schemas: When true, includes OpenAPI schemas (both uploaded and learned) for the + operation in the response. Due to the conversion overhead, this parameter is + only supported on single-operation retrieval. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -745,7 +761,13 @@ async def get( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform({"feature": feature}, operation_get_params.OperationGetParams), + query=await async_maybe_transform( + { + "feature": feature, + "with_schemas": with_schemas, + }, + operation_get_params.OperationGetParams, + ), post_parser=ResultWrapper[OperationGetResponse]._unwrapper, ), cast_to=cast(Type[OperationGetResponse], ResultWrapper[OperationGetResponse]), diff --git a/src/cloudflare/resources/billing/usage.py b/src/cloudflare/resources/billing/usage.py index d847aea692d..0071a8d4315 100644 --- a/src/cloudflare/resources/billing/usage.py +++ b/src/cloudflare/resources/billing/usage.py @@ -62,7 +62,8 @@ def paygo( When no query parameters are provided, returns usage for the current billing period. This - endpoint is currently in beta and access is restricted to select accounts. + endpoint is currently in alpha and access is restricted to select accounts. + While in alpha, the endpoint may get breaking changes. Args: account_id: Represents a Cloudflare resource identifier tag. @@ -138,7 +139,8 @@ async def paygo( When no query parameters are provided, returns usage for the current billing period. This - endpoint is currently in beta and access is restricted to select accounts. + endpoint is currently in alpha and access is restricted to select accounts. + While in alpha, the endpoint may get breaking changes. Args: account_id: Represents a Cloudflare resource identifier tag. diff --git a/src/cloudflare/resources/botnet_feed/asn.py b/src/cloudflare/resources/botnet_feed/asn.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/resources/botnet_feed/botnet_feed.py b/src/cloudflare/resources/botnet_feed/botnet_feed.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/resources/botnet_feed/configs/__init__.py b/src/cloudflare/resources/botnet_feed/configs/__init__.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/resources/botnet_feed/configs/asn.py b/src/cloudflare/resources/botnet_feed/configs/asn.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/resources/botnet_feed/configs/configs.py b/src/cloudflare/resources/botnet_feed/configs/configs.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/resources/browser_rendering/api.md b/src/cloudflare/resources/browser_rendering/api.md index c384cdcb32d..af4ab6e36d7 100644 --- a/src/cloudflare/resources/browser_rendering/api.md +++ b/src/cloudflare/resources/browser_rendering/api.md @@ -160,6 +160,7 @@ from cloudflare.types.browser_rendering.devtools.browser import ( TargetCreateResponse, TargetListResponse, TargetActivateResponse, + TargetCloseResponse, TargetGetResponse, ) ``` @@ -169,4 +170,5 @@ Methods: - client.browser_rendering.devtools.browser.targets.create(session_id, \*, account_id, \*\*params) -> TargetCreateResponse - client.browser_rendering.devtools.browser.targets.list(session_id, \*, account_id) -> TargetListResponse - client.browser_rendering.devtools.browser.targets.activate(target_id, \*, account_id, session_id) -> TargetActivateResponse +- client.browser_rendering.devtools.browser.targets.close(target_id, \*, account_id, session_id) -> TargetCloseResponse - client.browser_rendering.devtools.browser.targets.get(target_id, \*, account_id, session_id) -> TargetGetResponse diff --git a/src/cloudflare/resources/browser_rendering/devtools/browser/targets.py b/src/cloudflare/resources/browser_rendering/devtools/browser/targets.py index 75a19833916..425af81d325 100644 --- a/src/cloudflare/resources/browser_rendering/devtools/browser/targets.py +++ b/src/cloudflare/resources/browser_rendering/devtools/browser/targets.py @@ -18,6 +18,7 @@ from .....types.browser_rendering.devtools.browser import target_create_params from .....types.browser_rendering.devtools.browser.target_get_response import TargetGetResponse from .....types.browser_rendering.devtools.browser.target_list_response import TargetListResponse +from .....types.browser_rendering.devtools.browser.target_close_response import TargetCloseResponse from .....types.browser_rendering.devtools.browser.target_create_response import TargetCreateResponse from .....types.browser_rendering.devtools.browser.target_activate_response import TargetActivateResponse @@ -189,6 +190,58 @@ def activate( cast_to=TargetActivateResponse, ) + def close( + self, + target_id: str, + *, + account_id: str, + session_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, + ) -> TargetCloseResponse: + """Closes a specific browser target (tab, page, etc.) by its ID. + + Returns 'Target is + closing' on success or an error if the target is not found. + + Args: + account_id: Account ID. + + session_id: Browser session ID. + + target_id: Target ID to close. + + 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 account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not session_id: + raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}") + if not target_id: + raise ValueError(f"Expected a non-empty value for `target_id` but received {target_id!r}") + return self._get( + path_template( + "/accounts/{account_id}/browser-rendering/devtools/browser/{session_id}/json/close/{target_id}", + account_id=account_id, + session_id=session_id, + target_id=target_id, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=TargetCloseResponse, + ) + def get( self, target_id: str, @@ -405,6 +458,58 @@ async def activate( cast_to=TargetActivateResponse, ) + async def close( + self, + target_id: str, + *, + account_id: str, + session_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, + ) -> TargetCloseResponse: + """Closes a specific browser target (tab, page, etc.) by its ID. + + Returns 'Target is + closing' on success or an error if the target is not found. + + Args: + account_id: Account ID. + + session_id: Browser session ID. + + target_id: Target ID to close. + + 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 account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not session_id: + raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}") + if not target_id: + raise ValueError(f"Expected a non-empty value for `target_id` but received {target_id!r}") + return await self._get( + path_template( + "/accounts/{account_id}/browser-rendering/devtools/browser/{session_id}/json/close/{target_id}", + account_id=account_id, + session_id=session_id, + target_id=target_id, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=TargetCloseResponse, + ) + async def get( self, target_id: str, @@ -469,6 +574,9 @@ def __init__(self, targets: TargetsResource) -> None: self.activate = to_raw_response_wrapper( targets.activate, ) + self.close = to_raw_response_wrapper( + targets.close, + ) self.get = to_raw_response_wrapper( targets.get, ) @@ -487,6 +595,9 @@ def __init__(self, targets: AsyncTargetsResource) -> None: self.activate = async_to_raw_response_wrapper( targets.activate, ) + self.close = async_to_raw_response_wrapper( + targets.close, + ) self.get = async_to_raw_response_wrapper( targets.get, ) @@ -505,6 +616,9 @@ def __init__(self, targets: TargetsResource) -> None: self.activate = to_streamed_response_wrapper( targets.activate, ) + self.close = to_streamed_response_wrapper( + targets.close, + ) self.get = to_streamed_response_wrapper( targets.get, ) @@ -523,6 +637,9 @@ def __init__(self, targets: AsyncTargetsResource) -> None: self.activate = async_to_streamed_response_wrapper( targets.activate, ) + self.close = async_to_streamed_response_wrapper( + targets.close, + ) self.get = async_to_streamed_response_wrapper( targets.get, ) diff --git a/src/cloudflare/resources/email_security/api.md b/src/cloudflare/resources/email_security/api.md index 53e335ba90a..cfa43e12f75 100644 --- a/src/cloudflare/resources/email_security/api.md +++ b/src/cloudflare/resources/email_security/api.md @@ -11,7 +11,7 @@ from cloudflare.types.email_security import InvestigateListResponse, Investigate Methods: - client.email_security.investigate.list(\*, account_id, \*\*params) -> SyncV4PagePaginationArray[InvestigateListResponse] -- client.email_security.investigate.get(postfix_id, \*, account_id, \*\*params) -> InvestigateGetResponse +- client.email_security.investigate.get(investigate_id, \*, account_id, \*\*params) -> InvestigateGetResponse ### Detections @@ -23,7 +23,7 @@ from cloudflare.types.email_security.investigate import DetectionGetResponse Methods: -- client.email_security.investigate.detections.get(postfix_id, \*, account_id) -> DetectionGetResponse +- client.email_security.investigate.detections.get(investigate_id, \*, account_id) -> DetectionGetResponse ### Preview @@ -36,7 +36,7 @@ from cloudflare.types.email_security.investigate import PreviewCreateResponse, P Methods: - client.email_security.investigate.preview.create(\*, account_id, \*\*params) -> PreviewCreateResponse -- client.email_security.investigate.preview.get(postfix_id, \*, account_id) -> PreviewGetResponse +- client.email_security.investigate.preview.get(investigate_id, \*, account_id) -> PreviewGetResponse ### Raw @@ -48,7 +48,7 @@ from cloudflare.types.email_security.investigate import RawGetResponse Methods: -- client.email_security.investigate.raw.get(postfix_id, \*, account_id) -> RawGetResponse +- client.email_security.investigate.raw.get(investigate_id, \*, account_id) -> RawGetResponse ### Trace @@ -60,7 +60,7 @@ from cloudflare.types.email_security.investigate import TraceGetResponse Methods: -- client.email_security.investigate.trace.get(postfix_id, \*, account_id, \*\*params) -> TraceGetResponse +- client.email_security.investigate.trace.get(investigate_id, \*, account_id) -> TraceGetResponse ### Move @@ -72,14 +72,14 @@ from cloudflare.types.email_security.investigate import MoveCreateResponse, Move Methods: -- client.email_security.investigate.move.create(postfix_id, \*, account_id, \*\*params) -> MoveCreateResponse +- client.email_security.investigate.move.create(investigate_id, \*, account_id, \*\*params) -> SyncSinglePage[MoveCreateResponse] - client.email_security.investigate.move.bulk(\*, account_id, \*\*params) -> SyncSinglePage[MoveBulkResponse] ### Reclassify Methods: -- client.email_security.investigate.reclassify.create(postfix_id, \*, account_id, \*\*params) -> object +- client.email_security.investigate.reclassify.create(investigate_id, \*, account_id, \*\*params) -> object ### Release @@ -125,11 +125,11 @@ from cloudflare.types.email_security.settings import ( Methods: -- client.email_security.settings.allow_policies.create(\*, account_id, \*\*params) -> AllowPolicyCreateResponse +- client.email_security.settings.allow_policies.create(\*, account_id, \*\*params) -> Optional[AllowPolicyCreateResponse] - client.email_security.settings.allow_policies.list(\*, account_id, \*\*params) -> SyncV4PagePaginationArray[AllowPolicyListResponse] -- client.email_security.settings.allow_policies.delete(policy_id, \*, account_id) -> AllowPolicyDeleteResponse -- client.email_security.settings.allow_policies.edit(policy_id, \*, account_id, \*\*params) -> AllowPolicyEditResponse -- client.email_security.settings.allow_policies.get(policy_id, \*, account_id) -> AllowPolicyGetResponse +- client.email_security.settings.allow_policies.delete(policy_id, \*, account_id) -> Optional[AllowPolicyDeleteResponse] +- client.email_security.settings.allow_policies.edit(policy_id, \*, account_id, \*\*params) -> Optional[AllowPolicyEditResponse] +- client.email_security.settings.allow_policies.get(policy_id, \*, account_id) -> Optional[AllowPolicyGetResponse] ### BlockSenders @@ -147,11 +147,11 @@ from cloudflare.types.email_security.settings import ( Methods: -- client.email_security.settings.block_senders.create(\*, account_id, \*\*params) -> BlockSenderCreateResponse +- client.email_security.settings.block_senders.create(\*, account_id, \*\*params) -> Optional[BlockSenderCreateResponse] - client.email_security.settings.block_senders.list(\*, account_id, \*\*params) -> SyncV4PagePaginationArray[BlockSenderListResponse] -- client.email_security.settings.block_senders.delete(pattern_id, \*, account_id) -> BlockSenderDeleteResponse -- client.email_security.settings.block_senders.edit(pattern_id, \*, account_id, \*\*params) -> BlockSenderEditResponse -- client.email_security.settings.block_senders.get(pattern_id, \*, account_id) -> BlockSenderGetResponse +- client.email_security.settings.block_senders.delete(pattern_id, \*, account_id) -> Optional[BlockSenderDeleteResponse] +- client.email_security.settings.block_senders.edit(pattern_id, \*, account_id, \*\*params) -> Optional[BlockSenderEditResponse] +- client.email_security.settings.block_senders.get(pattern_id, \*, account_id) -> Optional[BlockSenderGetResponse] ### Domains @@ -161,7 +161,6 @@ Types: from cloudflare.types.email_security.settings import ( DomainListResponse, DomainDeleteResponse, - DomainBulkDeleteResponse, DomainEditResponse, DomainGetResponse, ) @@ -170,10 +169,9 @@ from cloudflare.types.email_security.settings import ( Methods: - client.email_security.settings.domains.list(\*, account_id, \*\*params) -> SyncV4PagePaginationArray[DomainListResponse] -- client.email_security.settings.domains.delete(domain_id, \*, account_id) -> DomainDeleteResponse -- client.email_security.settings.domains.bulk_delete(\*, account_id) -> SyncSinglePage[DomainBulkDeleteResponse] -- client.email_security.settings.domains.edit(domain_id, \*, account_id, \*\*params) -> DomainEditResponse -- client.email_security.settings.domains.get(domain_id, \*, account_id) -> DomainGetResponse +- client.email_security.settings.domains.delete(domain_id, \*, account_id) -> Optional[DomainDeleteResponse] +- client.email_security.settings.domains.edit(domain_id, \*, account_id, \*\*params) -> Optional[DomainEditResponse] +- client.email_security.settings.domains.get(domain_id, \*, account_id) -> Optional[DomainGetResponse] ### ImpersonationRegistry @@ -191,11 +189,11 @@ from cloudflare.types.email_security.settings import ( Methods: -- client.email_security.settings.impersonation_registry.create(\*, account_id, \*\*params) -> ImpersonationRegistryCreateResponse +- client.email_security.settings.impersonation_registry.create(\*, account_id, \*\*params) -> Optional[ImpersonationRegistryCreateResponse] - client.email_security.settings.impersonation_registry.list(\*, account_id, \*\*params) -> SyncV4PagePaginationArray[ImpersonationRegistryListResponse] -- client.email_security.settings.impersonation_registry.delete(display_name_id, \*, account_id) -> ImpersonationRegistryDeleteResponse -- client.email_security.settings.impersonation_registry.edit(display_name_id, \*, account_id, \*\*params) -> ImpersonationRegistryEditResponse -- client.email_security.settings.impersonation_registry.get(display_name_id, \*, account_id) -> ImpersonationRegistryGetResponse +- client.email_security.settings.impersonation_registry.delete(impersonation_registry_id, \*, account_id) -> Optional[ImpersonationRegistryDeleteResponse] +- client.email_security.settings.impersonation_registry.edit(impersonation_registry_id, \*, account_id, \*\*params) -> Optional[ImpersonationRegistryEditResponse] +- client.email_security.settings.impersonation_registry.get(impersonation_registry_id, \*, account_id) -> Optional[ImpersonationRegistryGetResponse] ### TrustedDomains @@ -213,11 +211,11 @@ from cloudflare.types.email_security.settings import ( Methods: -- client.email_security.settings.trusted_domains.create(\*, account_id, \*\*params) -> TrustedDomainCreateResponse +- client.email_security.settings.trusted_domains.create(\*, account_id, \*\*params) -> Optional[TrustedDomainCreateResponse] - client.email_security.settings.trusted_domains.list(\*, account_id, \*\*params) -> SyncV4PagePaginationArray[TrustedDomainListResponse] -- client.email_security.settings.trusted_domains.delete(trusted_domain_id, \*, account_id) -> TrustedDomainDeleteResponse -- client.email_security.settings.trusted_domains.edit(trusted_domain_id, \*, account_id, \*\*params) -> TrustedDomainEditResponse -- client.email_security.settings.trusted_domains.get(trusted_domain_id, \*, account_id) -> TrustedDomainGetResponse +- client.email_security.settings.trusted_domains.delete(trusted_domain_id, \*, account_id) -> Optional[TrustedDomainDeleteResponse] +- client.email_security.settings.trusted_domains.edit(trusted_domain_id, \*, account_id, \*\*params) -> Optional[TrustedDomainEditResponse] +- client.email_security.settings.trusted_domains.get(trusted_domain_id, \*, account_id) -> Optional[TrustedDomainGetResponse] ## Submissions diff --git a/src/cloudflare/resources/email_security/investigate/detections.py b/src/cloudflare/resources/email_security/investigate/detections.py index 3bf800a5931..f53430d18c5 100644 --- a/src/cloudflare/resources/email_security/investigate/detections.py +++ b/src/cloudflare/resources/email_security/investigate/detections.py @@ -45,7 +45,7 @@ def with_streaming_response(self) -> DetectionsResourceWithStreamingResponse: def get( self, - postfix_id: str, + investigate_id: str, *, account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -60,9 +60,9 @@ def get( non-benign messages. Args: - account_id: Account Identifier + account_id: Identifier. - postfix_id: The identifier of the message. + investigate_id: Unique identifier for a message retrieved from investigation extra_headers: Send extra headers @@ -74,13 +74,13 @@ def get( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not postfix_id: - raise ValueError(f"Expected a non-empty value for `postfix_id` but received {postfix_id!r}") + if not investigate_id: + raise ValueError(f"Expected a non-empty value for `investigate_id` but received {investigate_id!r}") return self._get( path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}/detections", + "/accounts/{account_id}/email-security/investigate/{investigate_id}/detections", account_id=account_id, - postfix_id=postfix_id, + investigate_id=investigate_id, ), options=make_request_options( extra_headers=extra_headers, @@ -115,7 +115,7 @@ def with_streaming_response(self) -> AsyncDetectionsResourceWithStreamingRespons async def get( self, - postfix_id: str, + investigate_id: str, *, account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -130,9 +130,9 @@ async def get( non-benign messages. Args: - account_id: Account Identifier + account_id: Identifier. - postfix_id: The identifier of the message. + investigate_id: Unique identifier for a message retrieved from investigation extra_headers: Send extra headers @@ -144,13 +144,13 @@ async def get( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not postfix_id: - raise ValueError(f"Expected a non-empty value for `postfix_id` but received {postfix_id!r}") + if not investigate_id: + raise ValueError(f"Expected a non-empty value for `investigate_id` but received {investigate_id!r}") return await self._get( path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}/detections", + "/accounts/{account_id}/email-security/investigate/{investigate_id}/detections", account_id=account_id, - postfix_id=postfix_id, + investigate_id=investigate_id, ), options=make_request_options( extra_headers=extra_headers, diff --git a/src/cloudflare/resources/email_security/investigate/investigate.py b/src/cloudflare/resources/email_security/investigate/investigate.py index c6167137eed..6572f57e9f6 100644 --- a/src/cloudflare/resources/email_security/investigate/investigate.py +++ b/src/cloudflare/resources/email_security/investigate/investigate.py @@ -142,9 +142,8 @@ def list( detections_only: bool | Omit = omit, domain: str | Omit = omit, end: Union[str, datetime] | Omit = omit, - exact_subject: str | Omit = omit, final_disposition: Literal["MALICIOUS", "SUSPICIOUS", "SPOOF", "SPAM", "BULK", "NONE"] | Omit = omit, - message_action: Literal["PREVIEW", "QUARANTINE_RELEASED", "MOVED", "SUBMITTED"] | Omit = omit, + message_action: Literal["PREVIEW", "QUARANTINE_RELEASED", "MOVED"] | Omit = omit, message_id: str | Omit = omit, metric: str | Omit = omit, page: Optional[int] | Omit = omit, @@ -154,7 +153,6 @@ def list( sender: str | Omit = omit, start: Union[str, datetime] | Omit = omit, subject: str | Omit = omit, - submissions: bool | 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, @@ -162,70 +160,31 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncV4PagePaginationArray[InvestigateListResponse]: - """Returns information for each email that matches the search parameter(s). - - If the - search takes too long, the endpoint returns 202 with a Location header pointing - to a polling endpoint where results can be retrieved once ready. + """ + Returns information for each email that matches the search parameter(s). Args: - account_id: Account Identifier - - action_log: Determines if the message action log is included in the response. + account_id: Identifier. - detections_only: Determines if the search results will include detections or not. + action_log: Whether to include the message action log in the response. - domain: Filter by a domain found in the email: sender domain, recipient domain, or a - domain in a link. + detections_only: Whether to include only detections in search results. - end: The end of the search date range. Defaults to `now` if not provided. + domain: Sender domains to filter by. - exact_subject: Search for messages with an exact subject match. + end: The end of the search date range. Defaults to `now`. - final_disposition: The dispositions the search filters by. + final_disposition: Dispositions to filter by. - message_action: The message actions the search filters by. + message_action: Message actions to filter by. - page: Deprecated: Use cursor pagination instead. + page: Deprecated: Use cursor pagination instead. End of life: November 1, 2026. per_page: The number of results per page. Maximum value is 1000. - query: The space-delimited term used in the query. The search is case-insensitive. - - The content of the following email metadata fields are searched: - - - alert_id - - CC - - From (envelope_from) - - From Name - - final_disposition - - md5 hash (of any attachment) - - sha1 hash (of any attachment) - - sha256 hash (of any attachment) - - name (of any attachment) - - Reason - - Received DateTime (yyyy-mm-ddThh:mm:ss) - - Sent DateTime (yyyy-mm-ddThh:mm:ss) - - ReplyTo - - To (envelope_to) - - To Name - - Message-ID - - smtp_helo_server_ip - - smtp_previous_hop_ip - - x_originating_ip - - Subject - - recipient: Filter by recipient. Matches either an email address or a domain. - - sender: Filter by sender. Matches either an email address or a domain. - - start: The beginning of the search date range. Defaults to `now - 30 days` if not - provided. - - subject: Search for messages containing individual keywords in any order within the - subject. + query: Space-delimited search term. Case-insensitive. - submissions: Search for submissions instead of original messages + start: The beginning of the search date range. Defaults to `now - 30 days`. extra_headers: Send extra headers @@ -253,7 +212,6 @@ def list( "detections_only": detections_only, "domain": domain, "end": end, - "exact_subject": exact_subject, "final_disposition": final_disposition, "message_action": message_action, "message_id": message_id, @@ -265,7 +223,6 @@ def list( "sender": sender, "start": start, "subject": subject, - "submissions": submissions, }, investigate_list_params.InvestigateListParams, ), @@ -275,7 +232,7 @@ def list( def get( self, - postfix_id: str, + investigate_id: str, *, account_id: str, submission: bool | Omit = omit, @@ -287,13 +244,14 @@ def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InvestigateGetResponse: """ - Retrieves detailed information about a specific email message, including - headers, metadata, and security scan results. + Retrieves comprehensive details for a specific email message including headers, + recipients, sender information, and current quarantine status. Use the + investigate_id from search results to fetch detailed information. Args: - account_id: Account Identifier + account_id: Identifier. - postfix_id: The identifier of the message. + investigate_id: Unique identifier for a message retrieved from investigation submission: When true, search the submissions datastore only. When false or omitted, search the regular datastore only. @@ -308,13 +266,13 @@ def get( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not postfix_id: - raise ValueError(f"Expected a non-empty value for `postfix_id` but received {postfix_id!r}") + if not investigate_id: + raise ValueError(f"Expected a non-empty value for `investigate_id` but received {investigate_id!r}") return self._get( path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}", + "/accounts/{account_id}/email-security/investigate/{investigate_id}", account_id=account_id, - postfix_id=postfix_id, + investigate_id=investigate_id, ), options=make_request_options( extra_headers=extra_headers, @@ -386,9 +344,8 @@ def list( detections_only: bool | Omit = omit, domain: str | Omit = omit, end: Union[str, datetime] | Omit = omit, - exact_subject: str | Omit = omit, final_disposition: Literal["MALICIOUS", "SUSPICIOUS", "SPOOF", "SPAM", "BULK", "NONE"] | Omit = omit, - message_action: Literal["PREVIEW", "QUARANTINE_RELEASED", "MOVED", "SUBMITTED"] | Omit = omit, + message_action: Literal["PREVIEW", "QUARANTINE_RELEASED", "MOVED"] | Omit = omit, message_id: str | Omit = omit, metric: str | Omit = omit, page: Optional[int] | Omit = omit, @@ -398,7 +355,6 @@ def list( sender: str | Omit = omit, start: Union[str, datetime] | Omit = omit, subject: str | Omit = omit, - submissions: bool | 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, @@ -406,70 +362,31 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[InvestigateListResponse, AsyncV4PagePaginationArray[InvestigateListResponse]]: - """Returns information for each email that matches the search parameter(s). - - If the - search takes too long, the endpoint returns 202 with a Location header pointing - to a polling endpoint where results can be retrieved once ready. + """ + Returns information for each email that matches the search parameter(s). Args: - account_id: Account Identifier - - action_log: Determines if the message action log is included in the response. + account_id: Identifier. - detections_only: Determines if the search results will include detections or not. + action_log: Whether to include the message action log in the response. - domain: Filter by a domain found in the email: sender domain, recipient domain, or a - domain in a link. + detections_only: Whether to include only detections in search results. - end: The end of the search date range. Defaults to `now` if not provided. + domain: Sender domains to filter by. - exact_subject: Search for messages with an exact subject match. + end: The end of the search date range. Defaults to `now`. - final_disposition: The dispositions the search filters by. + final_disposition: Dispositions to filter by. - message_action: The message actions the search filters by. + message_action: Message actions to filter by. - page: Deprecated: Use cursor pagination instead. + page: Deprecated: Use cursor pagination instead. End of life: November 1, 2026. per_page: The number of results per page. Maximum value is 1000. - query: The space-delimited term used in the query. The search is case-insensitive. - - The content of the following email metadata fields are searched: - - - alert_id - - CC - - From (envelope_from) - - From Name - - final_disposition - - md5 hash (of any attachment) - - sha1 hash (of any attachment) - - sha256 hash (of any attachment) - - name (of any attachment) - - Reason - - Received DateTime (yyyy-mm-ddThh:mm:ss) - - Sent DateTime (yyyy-mm-ddThh:mm:ss) - - ReplyTo - - To (envelope_to) - - To Name - - Message-ID - - smtp_helo_server_ip - - smtp_previous_hop_ip - - x_originating_ip - - Subject - - recipient: Filter by recipient. Matches either an email address or a domain. - - sender: Filter by sender. Matches either an email address or a domain. - - start: The beginning of the search date range. Defaults to `now - 30 days` if not - provided. - - subject: Search for messages containing individual keywords in any order within the - subject. + query: Space-delimited search term. Case-insensitive. - submissions: Search for submissions instead of original messages + start: The beginning of the search date range. Defaults to `now - 30 days`. extra_headers: Send extra headers @@ -497,7 +414,6 @@ def list( "detections_only": detections_only, "domain": domain, "end": end, - "exact_subject": exact_subject, "final_disposition": final_disposition, "message_action": message_action, "message_id": message_id, @@ -509,7 +425,6 @@ def list( "sender": sender, "start": start, "subject": subject, - "submissions": submissions, }, investigate_list_params.InvestigateListParams, ), @@ -519,7 +434,7 @@ def list( async def get( self, - postfix_id: str, + investigate_id: str, *, account_id: str, submission: bool | Omit = omit, @@ -531,13 +446,14 @@ async def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InvestigateGetResponse: """ - Retrieves detailed information about a specific email message, including - headers, metadata, and security scan results. + Retrieves comprehensive details for a specific email message including headers, + recipients, sender information, and current quarantine status. Use the + investigate_id from search results to fetch detailed information. Args: - account_id: Account Identifier + account_id: Identifier. - postfix_id: The identifier of the message. + investigate_id: Unique identifier for a message retrieved from investigation submission: When true, search the submissions datastore only. When false or omitted, search the regular datastore only. @@ -552,13 +468,13 @@ async def get( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not postfix_id: - raise ValueError(f"Expected a non-empty value for `postfix_id` but received {postfix_id!r}") + if not investigate_id: + raise ValueError(f"Expected a non-empty value for `investigate_id` but received {investigate_id!r}") return await self._get( path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}", + "/accounts/{account_id}/email-security/investigate/{investigate_id}", account_id=account_id, - postfix_id=postfix_id, + investigate_id=investigate_id, ), options=make_request_options( extra_headers=extra_headers, diff --git a/src/cloudflare/resources/email_security/investigate/move.py b/src/cloudflare/resources/email_security/investigate/move.py index ae07fced89e..8fa530641c6 100644 --- a/src/cloudflare/resources/email_security/investigate/move.py +++ b/src/cloudflare/resources/email_security/investigate/move.py @@ -2,13 +2,12 @@ from __future__ import annotations -from typing import Type, cast from typing_extensions import Literal import httpx from ...._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given -from ...._utils import path_template, maybe_transform, async_maybe_transform +from ...._utils import path_template, maybe_transform from ...._compat import cached_property from ...._resource import SyncAPIResource, AsyncAPIResource from ...._response import ( @@ -17,7 +16,6 @@ async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) -from ...._wrappers import ResultWrapper from ....pagination import SyncSinglePage, AsyncSinglePage from ...._base_client import AsyncPaginator, make_request_options from ....types.email_security.investigate import move_bulk_params, move_create_params @@ -49,31 +47,28 @@ def with_streaming_response(self) -> MoveResourceWithStreamingResponse: def create( self, - postfix_id: str, + investigate_id: str, *, account_id: str, destination: Literal[ "Inbox", "JunkEmail", "DeletedItems", "RecoverableItemsDeletions", "RecoverableItemsPurges" ], - submission: bool | 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, - ) -> MoveCreateResponse: + ) -> SyncSinglePage[MoveCreateResponse]: """ - Moves a single email message to a different folder or changes its quarantine - status. + Moves a single message to a specified mailbox folder (Inbox, JunkEmail, + DeletedItems, RecoverableItemsDeletions, or RecoverableItemsPurges). Requires + active integration. Args: - account_id: Account Identifier + account_id: Identifier. - postfix_id: The identifier of the message. - - submission: When true, search the submissions datastore only. When false or omitted, search - the regular datastore only. + investigate_id: Unique identifier for a message retrieved from investigation extra_headers: Send extra headers @@ -85,24 +80,21 @@ def create( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not postfix_id: - raise ValueError(f"Expected a non-empty value for `postfix_id` but received {postfix_id!r}") - return self._post( + if not investigate_id: + raise ValueError(f"Expected a non-empty value for `investigate_id` but received {investigate_id!r}") + return self._get_api_list( path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}/move", + "/accounts/{account_id}/email-security/investigate/{investigate_id}/move", account_id=account_id, - postfix_id=postfix_id, + investigate_id=investigate_id, ), + page=SyncSinglePage[MoveCreateResponse], body=maybe_transform({"destination": destination}, move_create_params.MoveCreateParams), options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform({"submission": submission}, move_create_params.MoveCreateParams), - post_parser=ResultWrapper[MoveCreateResponse]._unwrapper, + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - cast_to=cast(Type[MoveCreateResponse], ResultWrapper[MoveCreateResponse]), + model=MoveCreateResponse, + method="post", ) def bulk( @@ -122,14 +114,17 @@ def bulk( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncSinglePage[MoveBulkResponse]: """ - Maximum batch size: 1000 messages per request + Moves multiple messages to a specified mailbox folder (Inbox, JunkEmail, + DeletedItems, RecoverableItemsDeletions, or RecoverableItemsPurges). Requires + active integration. Args: - account_id: Account Identifier + account_id: Identifier. - ids: List of message IDs to move. + ids: List of message IDs to move - postfix_ids: Deprecated: Use `ids` instead. List of message IDs to move. + postfix_ids: Deprecated, use `ids` instead. End of life: November 1, 2026. List of message + IDs to move. extra_headers: Send extra headers @@ -180,33 +175,30 @@ def with_streaming_response(self) -> AsyncMoveResourceWithStreamingResponse: """ return AsyncMoveResourceWithStreamingResponse(self) - async def create( + def create( self, - postfix_id: str, + investigate_id: str, *, account_id: str, destination: Literal[ "Inbox", "JunkEmail", "DeletedItems", "RecoverableItemsDeletions", "RecoverableItemsPurges" ], - submission: bool | 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, - ) -> MoveCreateResponse: + ) -> AsyncPaginator[MoveCreateResponse, AsyncSinglePage[MoveCreateResponse]]: """ - Moves a single email message to a different folder or changes its quarantine - status. + Moves a single message to a specified mailbox folder (Inbox, JunkEmail, + DeletedItems, RecoverableItemsDeletions, or RecoverableItemsPurges). Requires + active integration. Args: - account_id: Account Identifier + account_id: Identifier. - postfix_id: The identifier of the message. - - submission: When true, search the submissions datastore only. When false or omitted, search - the regular datastore only. + investigate_id: Unique identifier for a message retrieved from investigation extra_headers: Send extra headers @@ -218,24 +210,21 @@ async def create( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not postfix_id: - raise ValueError(f"Expected a non-empty value for `postfix_id` but received {postfix_id!r}") - return await self._post( + if not investigate_id: + raise ValueError(f"Expected a non-empty value for `investigate_id` but received {investigate_id!r}") + return self._get_api_list( path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}/move", + "/accounts/{account_id}/email-security/investigate/{investigate_id}/move", account_id=account_id, - postfix_id=postfix_id, + investigate_id=investigate_id, ), - body=await async_maybe_transform({"destination": destination}, move_create_params.MoveCreateParams), + page=AsyncSinglePage[MoveCreateResponse], + body=maybe_transform({"destination": destination}, move_create_params.MoveCreateParams), options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=await async_maybe_transform({"submission": submission}, move_create_params.MoveCreateParams), - post_parser=ResultWrapper[MoveCreateResponse]._unwrapper, + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - cast_to=cast(Type[MoveCreateResponse], ResultWrapper[MoveCreateResponse]), + model=MoveCreateResponse, + method="post", ) def bulk( @@ -255,14 +244,17 @@ def bulk( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[MoveBulkResponse, AsyncSinglePage[MoveBulkResponse]]: """ - Maximum batch size: 1000 messages per request + Moves multiple messages to a specified mailbox folder (Inbox, JunkEmail, + DeletedItems, RecoverableItemsDeletions, or RecoverableItemsPurges). Requires + active integration. Args: - account_id: Account Identifier + account_id: Identifier. - ids: List of message IDs to move. + ids: List of message IDs to move - postfix_ids: Deprecated: Use `ids` instead. List of message IDs to move. + postfix_ids: Deprecated, use `ids` instead. End of life: November 1, 2026. List of message + IDs to move. extra_headers: Send extra headers diff --git a/src/cloudflare/resources/email_security/investigate/preview.py b/src/cloudflare/resources/email_security/investigate/preview.py index 17fe835b7f4..1bfbe97d41b 100644 --- a/src/cloudflare/resources/email_security/investigate/preview.py +++ b/src/cloudflare/resources/email_security/investigate/preview.py @@ -6,7 +6,7 @@ import httpx -from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ...._types import Body, Query, Headers, NotGiven, not_given from ...._utils import path_template, maybe_transform, async_maybe_transform from ...._compat import cached_property from ...._resource import SyncAPIResource, AsyncAPIResource @@ -50,7 +50,6 @@ def create( *, account_id: str, postfix_id: str, - submission: bool | 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, @@ -59,16 +58,14 @@ def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PreviewCreateResponse: """ - Generates a preview of an email message for safe viewing without executing any - embedded content. + Generates a preview image for a message that was not flagged as a detection. + Useful for investigating benign messages. Returns a base64-encoded PNG + screenshot of the email body. Args: - account_id: Account Identifier + account_id: Identifier. - postfix_id: The identifier of the message. - - submission: When true, search the submissions datastore only. When false or omitted, search - the regular datastore only. + postfix_id: The identifier of the message extra_headers: Send extra headers @@ -88,7 +85,6 @@ def create( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=maybe_transform({"submission": submission}, preview_create_params.PreviewCreateParams), post_parser=ResultWrapper[PreviewCreateResponse]._unwrapper, ), cast_to=cast(Type[PreviewCreateResponse], ResultWrapper[PreviewCreateResponse]), @@ -96,7 +92,7 @@ def create( def get( self, - postfix_id: str, + investigate_id: str, *, account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -111,9 +107,9 @@ def get( non-benign messages. Args: - account_id: Account Identifier + account_id: Identifier. - postfix_id: The identifier of the message. + investigate_id: Unique identifier for a message retrieved from investigation extra_headers: Send extra headers @@ -125,13 +121,13 @@ def get( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not postfix_id: - raise ValueError(f"Expected a non-empty value for `postfix_id` but received {postfix_id!r}") + if not investigate_id: + raise ValueError(f"Expected a non-empty value for `investigate_id` but received {investigate_id!r}") return self._get( path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}/preview", + "/accounts/{account_id}/email-security/investigate/{investigate_id}/preview", account_id=account_id, - postfix_id=postfix_id, + investigate_id=investigate_id, ), options=make_request_options( extra_headers=extra_headers, @@ -169,7 +165,6 @@ async def create( *, account_id: str, postfix_id: str, - submission: bool | 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, @@ -178,16 +173,14 @@ async def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PreviewCreateResponse: """ - Generates a preview of an email message for safe viewing without executing any - embedded content. + Generates a preview image for a message that was not flagged as a detection. + Useful for investigating benign messages. Returns a base64-encoded PNG + screenshot of the email body. Args: - account_id: Account Identifier + account_id: Identifier. - postfix_id: The identifier of the message. - - submission: When true, search the submissions datastore only. When false or omitted, search - the regular datastore only. + postfix_id: The identifier of the message extra_headers: Send extra headers @@ -207,9 +200,6 @@ async def create( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform( - {"submission": submission}, preview_create_params.PreviewCreateParams - ), post_parser=ResultWrapper[PreviewCreateResponse]._unwrapper, ), cast_to=cast(Type[PreviewCreateResponse], ResultWrapper[PreviewCreateResponse]), @@ -217,7 +207,7 @@ async def create( async def get( self, - postfix_id: str, + investigate_id: str, *, account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -232,9 +222,9 @@ async def get( non-benign messages. Args: - account_id: Account Identifier + account_id: Identifier. - postfix_id: The identifier of the message. + investigate_id: Unique identifier for a message retrieved from investigation extra_headers: Send extra headers @@ -246,13 +236,13 @@ async def get( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not postfix_id: - raise ValueError(f"Expected a non-empty value for `postfix_id` but received {postfix_id!r}") + if not investigate_id: + raise ValueError(f"Expected a non-empty value for `investigate_id` but received {investigate_id!r}") return await self._get( path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}/preview", + "/accounts/{account_id}/email-security/investigate/{investigate_id}/preview", account_id=account_id, - postfix_id=postfix_id, + investigate_id=investigate_id, ), options=make_request_options( extra_headers=extra_headers, diff --git a/src/cloudflare/resources/email_security/investigate/raw.py b/src/cloudflare/resources/email_security/investigate/raw.py index 39a8a4b6d39..9a3c682452c 100644 --- a/src/cloudflare/resources/email_security/investigate/raw.py +++ b/src/cloudflare/resources/email_security/investigate/raw.py @@ -45,7 +45,7 @@ def with_streaming_response(self) -> RawResourceWithStreamingResponse: def get( self, - postfix_id: str, + investigate_id: str, *, account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -59,9 +59,9 @@ def get( Returns the raw eml of any non-benign message. Args: - account_id: Account Identifier + account_id: Identifier. - postfix_id: The identifier of the message. + investigate_id: Unique identifier for a message retrieved from investigation extra_headers: Send extra headers @@ -73,13 +73,13 @@ def get( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not postfix_id: - raise ValueError(f"Expected a non-empty value for `postfix_id` but received {postfix_id!r}") + if not investigate_id: + raise ValueError(f"Expected a non-empty value for `investigate_id` but received {investigate_id!r}") return self._get( path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}/raw", + "/accounts/{account_id}/email-security/investigate/{investigate_id}/raw", account_id=account_id, - postfix_id=postfix_id, + investigate_id=investigate_id, ), options=make_request_options( extra_headers=extra_headers, @@ -114,7 +114,7 @@ def with_streaming_response(self) -> AsyncRawResourceWithStreamingResponse: async def get( self, - postfix_id: str, + investigate_id: str, *, account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -128,9 +128,9 @@ async def get( Returns the raw eml of any non-benign message. Args: - account_id: Account Identifier + account_id: Identifier. - postfix_id: The identifier of the message. + investigate_id: Unique identifier for a message retrieved from investigation extra_headers: Send extra headers @@ -142,13 +142,13 @@ async def get( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not postfix_id: - raise ValueError(f"Expected a non-empty value for `postfix_id` but received {postfix_id!r}") + if not investigate_id: + raise ValueError(f"Expected a non-empty value for `investigate_id` but received {investigate_id!r}") return await self._get( path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}/raw", + "/accounts/{account_id}/email-security/investigate/{investigate_id}/raw", account_id=account_id, - postfix_id=postfix_id, + investigate_id=investigate_id, ), options=make_request_options( extra_headers=extra_headers, diff --git a/src/cloudflare/resources/email_security/investigate/reclassify.py b/src/cloudflare/resources/email_security/investigate/reclassify.py index 27daa3d7260..80a1b87eebb 100644 --- a/src/cloudflare/resources/email_security/investigate/reclassify.py +++ b/src/cloudflare/resources/email_security/investigate/reclassify.py @@ -46,11 +46,10 @@ def with_streaming_response(self) -> ReclassifyResourceWithStreamingResponse: def create( self, - postfix_id: str, + investigate_id: str, *, account_id: str, expected_disposition: Literal["NONE", "BULK", "MALICIOUS", "SPAM", "SPOOF", "SUSPICIOUS"], - submission: bool | Omit = omit, eml_content: str | Omit = omit, escalated_submission_id: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -60,19 +59,18 @@ def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> object: - """ - Submits an email message for reclassification, updating its threat assessment - based on new analysis. + """Submits a request to reclassify an email's disposition. - Args: - account_id: Account Identifier + Use for reporting false + positives or false negatives. Optionally provide the raw EML content for + reanalysis. The reclassification is processed asynchronously. - postfix_id: The identifier of the message. + Args: + account_id: Identifier. - submission: When true, search the submissions datastore only. When false or omitted, search - the regular datastore only. + investigate_id: Unique identifier for a message retrieved from investigation - eml_content: Base64 encoded content of the EML file + eml_content: Base64 encoded content of the EML file. extra_headers: Send extra headers @@ -84,13 +82,13 @@ def create( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not postfix_id: - raise ValueError(f"Expected a non-empty value for `postfix_id` but received {postfix_id!r}") + if not investigate_id: + raise ValueError(f"Expected a non-empty value for `investigate_id` but received {investigate_id!r}") return self._post( path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}/reclassify", + "/accounts/{account_id}/email-security/investigate/{investigate_id}/reclassify", account_id=account_id, - postfix_id=postfix_id, + investigate_id=investigate_id, ), body=maybe_transform( { @@ -105,7 +103,6 @@ def create( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=maybe_transform({"submission": submission}, reclassify_create_params.ReclassifyCreateParams), post_parser=ResultWrapper[object]._unwrapper, ), cast_to=cast(Type[object], ResultWrapper[object]), @@ -134,11 +131,10 @@ def with_streaming_response(self) -> AsyncReclassifyResourceWithStreamingRespons async def create( self, - postfix_id: str, + investigate_id: str, *, account_id: str, expected_disposition: Literal["NONE", "BULK", "MALICIOUS", "SPAM", "SPOOF", "SUSPICIOUS"], - submission: bool | Omit = omit, eml_content: str | Omit = omit, escalated_submission_id: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -148,19 +144,18 @@ async def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> object: - """ - Submits an email message for reclassification, updating its threat assessment - based on new analysis. + """Submits a request to reclassify an email's disposition. - Args: - account_id: Account Identifier + Use for reporting false + positives or false negatives. Optionally provide the raw EML content for + reanalysis. The reclassification is processed asynchronously. - postfix_id: The identifier of the message. + Args: + account_id: Identifier. - submission: When true, search the submissions datastore only. When false or omitted, search - the regular datastore only. + investigate_id: Unique identifier for a message retrieved from investigation - eml_content: Base64 encoded content of the EML file + eml_content: Base64 encoded content of the EML file. extra_headers: Send extra headers @@ -172,13 +167,13 @@ async def create( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not postfix_id: - raise ValueError(f"Expected a non-empty value for `postfix_id` but received {postfix_id!r}") + if not investigate_id: + raise ValueError(f"Expected a non-empty value for `investigate_id` but received {investigate_id!r}") return await self._post( path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}/reclassify", + "/accounts/{account_id}/email-security/investigate/{investigate_id}/reclassify", account_id=account_id, - postfix_id=postfix_id, + investigate_id=investigate_id, ), body=await async_maybe_transform( { @@ -193,9 +188,6 @@ async def create( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform( - {"submission": submission}, reclassify_create_params.ReclassifyCreateParams - ), post_parser=ResultWrapper[object]._unwrapper, ), cast_to=cast(Type[object], ResultWrapper[object]), diff --git a/src/cloudflare/resources/email_security/investigate/release.py b/src/cloudflare/resources/email_security/investigate/release.py index 78d9770cc96..21f78d710b2 100644 --- a/src/cloudflare/resources/email_security/investigate/release.py +++ b/src/cloudflare/resources/email_security/investigate/release.py @@ -54,13 +54,12 @@ def bulk( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncSinglePage[ReleaseBulkResponse]: """ - Releases a quarantined email message, allowing it to be delivered to the - recipient. + Releases one or more quarantined messages, delivering them to the intended + recipients. Use when a message was incorrectly quarantined. Returns delivery + status for each recipient. Args: - account_id: Account Identifier - - body: A list of messages identfied by their `postfix_id`s that should be released. + account_id: Identifier. extra_headers: Send extra headers @@ -117,13 +116,12 @@ def bulk( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[ReleaseBulkResponse, AsyncSinglePage[ReleaseBulkResponse]]: """ - Releases a quarantined email message, allowing it to be delivered to the - recipient. + Releases one or more quarantined messages, delivering them to the intended + recipients. Use when a message was incorrectly quarantined. Returns delivery + status for each recipient. Args: - account_id: Account Identifier - - body: A list of messages identfied by their `postfix_id`s that should be released. + account_id: Identifier. extra_headers: Send extra headers diff --git a/src/cloudflare/resources/email_security/investigate/trace.py b/src/cloudflare/resources/email_security/investigate/trace.py index bcb66883386..daf3560d6d1 100644 --- a/src/cloudflare/resources/email_security/investigate/trace.py +++ b/src/cloudflare/resources/email_security/investigate/trace.py @@ -6,8 +6,8 @@ import httpx -from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ...._utils import path_template, maybe_transform, async_maybe_transform +from ...._types import Body, Query, Headers, NotGiven, not_given +from ...._utils import path_template from ...._compat import cached_property from ...._resource import SyncAPIResource, AsyncAPIResource from ...._response import ( @@ -18,7 +18,6 @@ ) from ...._wrappers import ResultWrapper from ...._base_client import make_request_options -from ....types.email_security.investigate import trace_get_params from ....types.email_security.investigate.trace_get_response import TraceGetResponse __all__ = ["TraceResource", "AsyncTraceResource"] @@ -46,10 +45,9 @@ def with_streaming_response(self) -> TraceResourceWithStreamingResponse: def get( self, - postfix_id: str, + investigate_id: str, *, account_id: str, - submission: bool | 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, @@ -57,17 +55,16 @@ def get( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TraceGetResponse: - """ - Gets the delivery trace for an email message, showing its path through email - security processing. + """Retrieves delivery and processing trace information for an email message. - Args: - account_id: Account Identifier + Shows + the delivery path, retraction history, and move operations performed on the + message. Useful for debugging delivery issues. - postfix_id: The identifier of the message. + Args: + account_id: Identifier. - submission: When true, search the submissions datastore only. When false or omitted, search - the regular datastore only. + investigate_id: Unique identifier for a message retrieved from investigation extra_headers: Send extra headers @@ -79,20 +76,19 @@ def get( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not postfix_id: - raise ValueError(f"Expected a non-empty value for `postfix_id` but received {postfix_id!r}") + if not investigate_id: + raise ValueError(f"Expected a non-empty value for `investigate_id` but received {investigate_id!r}") return self._get( path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}/trace", + "/accounts/{account_id}/email-security/investigate/{investigate_id}/trace", account_id=account_id, - postfix_id=postfix_id, + investigate_id=investigate_id, ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=maybe_transform({"submission": submission}, trace_get_params.TraceGetParams), post_parser=ResultWrapper[TraceGetResponse]._unwrapper, ), cast_to=cast(Type[TraceGetResponse], ResultWrapper[TraceGetResponse]), @@ -121,10 +117,9 @@ def with_streaming_response(self) -> AsyncTraceResourceWithStreamingResponse: async def get( self, - postfix_id: str, + investigate_id: str, *, account_id: str, - submission: bool | 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, @@ -132,17 +127,16 @@ async def get( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TraceGetResponse: - """ - Gets the delivery trace for an email message, showing its path through email - security processing. + """Retrieves delivery and processing trace information for an email message. - Args: - account_id: Account Identifier + Shows + the delivery path, retraction history, and move operations performed on the + message. Useful for debugging delivery issues. - postfix_id: The identifier of the message. + Args: + account_id: Identifier. - submission: When true, search the submissions datastore only. When false or omitted, search - the regular datastore only. + investigate_id: Unique identifier for a message retrieved from investigation extra_headers: Send extra headers @@ -154,20 +148,19 @@ async def get( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not postfix_id: - raise ValueError(f"Expected a non-empty value for `postfix_id` but received {postfix_id!r}") + if not investigate_id: + raise ValueError(f"Expected a non-empty value for `investigate_id` but received {investigate_id!r}") return await self._get( path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}/trace", + "/accounts/{account_id}/email-security/investigate/{investigate_id}/trace", account_id=account_id, - postfix_id=postfix_id, + investigate_id=investigate_id, ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform({"submission": submission}, trace_get_params.TraceGetParams), post_parser=ResultWrapper[TraceGetResponse]._unwrapper, ), cast_to=cast(Type[TraceGetResponse], ResultWrapper[TraceGetResponse]), diff --git a/src/cloudflare/resources/email_security/phishguard/reports.py b/src/cloudflare/resources/email_security/phishguard/reports.py index b41c7cdaefc..06029293bc6 100644 --- a/src/cloudflare/resources/email_security/phishguard/reports.py +++ b/src/cloudflare/resources/email_security/phishguard/reports.py @@ -60,16 +60,22 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncSinglePage[ReportListResponse]: - """ - Retrieves `PhishGuard` reports showing phishing attempts and suspicious email - patterns detected. + """Retrieves PhishGuard security alert reports for a specified date range. + + Reports + include detected threats, dispositions, and contextual information. Use for + security monitoring and threat analysis. Args: - account_id: Account Identifier + account_id: Identifier. + + end: End of the time range (RFC3339). Takes precedence over to_date. + + from_date: Deprecated, use `start` instead. Start date in YYYY-MM-DD format. - end: The end of the search date range (RFC3339 format). + start: Start of the time range (RFC3339). Takes precedence over from_date. - start: The beginning of the search date range (RFC3339 format). + to_date: Deprecated, use `end` instead. End date in YYYY-MM-DD format. extra_headers: Send extra headers @@ -138,16 +144,22 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[ReportListResponse, AsyncSinglePage[ReportListResponse]]: - """ - Retrieves `PhishGuard` reports showing phishing attempts and suspicious email - patterns detected. + """Retrieves PhishGuard security alert reports for a specified date range. + + Reports + include detected threats, dispositions, and contextual information. Use for + security monitoring and threat analysis. Args: - account_id: Account Identifier + account_id: Identifier. + + end: End of the time range (RFC3339). Takes precedence over to_date. + + from_date: Deprecated, use `start` instead. Start date in YYYY-MM-DD format. - end: The end of the search date range (RFC3339 format). + start: Start of the time range (RFC3339). Takes precedence over from_date. - start: The beginning of the search date range (RFC3339 format). + to_date: Deprecated, use `end` instead. End date in YYYY-MM-DD format. extra_headers: Send extra headers diff --git a/src/cloudflare/resources/email_security/settings/allow_policies.py b/src/cloudflare/resources/email_security/settings/allow_policies.py index d9c3950c649..67b7f077364 100644 --- a/src/cloudflare/resources/email_security/settings/allow_policies.py +++ b/src/cloudflare/resources/email_security/settings/allow_policies.py @@ -75,25 +75,42 @@ def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AllowPolicyCreateResponse: - """ - Creates a new email allow policy that permits specific senders, domains, or - patterns to bypass security scanning. + ) -> Optional[AllowPolicyCreateResponse]: + """Creates a new allow policy that exempts matching emails from security + detections. + + Use with caution as this bypasses email security scanning. Policies + can match on sender patterns and apply to specific detections or all detections. Args: - account_id: Account Identifier + account_id: Identifier. is_acceptable_sender: Messages from this sender will be exempted from Spam, Spoof and Bulk - dispositions. Note: This will not exempt messages with Malicious or Suspicious + dispositions. Note - This will not exempt messages with Malicious or Suspicious dispositions. - is_exempt_recipient: Messages to this recipient will bypass all detections. + is_exempt_recipient: Messages to this recipient will bypass all detections + + is_trusted_sender: Messages from this sender will bypass all detections and link following - is_trusted_sender: Messages from this sender will bypass all detections and link following. + pattern_type: Type of pattern matching. Note: UNKNOWN is deprecated and cannot be used when + creating or updating policies, but may be returned for existing entries. verify_sender: Enforce DMARC, SPF or DKIM authentication. When on, Email Security only honors policies that pass authentication. + is_recipient: + Deprecated as of July 1, 2025. Use `is_exempt_recipient` instead. End of life: + July 1, 2026. + + is_sender: + Deprecated as of July 1, 2025. Use `is_trusted_sender` instead. End of life: + July 1, 2026. + + is_spoof: + Deprecated as of July 1, 2025. Use `is_acceptable_sender` instead. End of life: + July 1, 2026. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -127,9 +144,9 @@ def create( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[AllowPolicyCreateResponse]._unwrapper, + post_parser=ResultWrapper[Optional[AllowPolicyCreateResponse]]._unwrapper, ), - cast_to=cast(Type[AllowPolicyCreateResponse], ResultWrapper[AllowPolicyCreateResponse]), + cast_to=cast(Type[Optional[AllowPolicyCreateResponse]], ResultWrapper[AllowPolicyCreateResponse]), ) def list( @@ -139,9 +156,6 @@ def list( direction: Literal["asc", "desc"] | Omit = omit, is_acceptable_sender: bool | Omit = omit, is_exempt_recipient: bool | Omit = omit, - is_recipient: bool | Omit = omit, - is_sender: bool | Omit = omit, - is_spoof: bool | Omit = omit, is_trusted_sender: bool | Omit = omit, order: Literal["pattern", "created_at"] | Omit = omit, page: int | Omit = omit, @@ -157,23 +171,38 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncV4PagePaginationArray[AllowPolicyListResponse]: - """ - Lists, searches, and sorts an account’s email allow policies. + """Returns a paginated list of email allow policies. + + These policies exempt matching + emails from security detection, allowing them to bypass disposition actions. + Supports filtering by pattern type and policy attributes. Args: - account_id: Account Identifier + account_id: Identifier. direction: The sorting direction. - order: The field to sort by. + is_acceptable_sender: Filter to show only policies where messages from the sender are exempted from + Spam, Spoof, and Bulk dispositions (not Malicious or Suspicious). + + is_exempt_recipient: Filter to show only policies where messages to the recipient bypass all + detections. + + is_trusted_sender: Filter to show only policies where messages from the sender bypass all + detections and link following. - page: The page number of paginated results. + order: Field to sort by. - per_page: The number of results per page. + page: Current page within paginated list of results. - search: Allows searching in multiple properties of a record simultaneously. This - parameter is intended for human users, not automation. Its exact behavior is - intentionally left unspecified and is subject to change in the future. + pattern_type: Type of pattern matching. Note: UNKNOWN is deprecated and cannot be used when + creating or updating policies, but may be returned for existing entries. + + per_page: The number of results per page. Maximum value is 1000. + + search: Search term for filtering records. Behavior may change. + + verify_sender: Filter to show only policies that enforce DMARC, SPF, or DKIM authentication. extra_headers: Send extra headers @@ -198,9 +227,6 @@ def list( "direction": direction, "is_acceptable_sender": is_acceptable_sender, "is_exempt_recipient": is_exempt_recipient, - "is_recipient": is_recipient, - "is_sender": is_sender, - "is_spoof": is_spoof, "is_trusted_sender": is_trusted_sender, "order": order, "page": page, @@ -218,7 +244,7 @@ def list( def delete( self, - policy_id: int, + policy_id: str, *, account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -227,16 +253,16 @@ def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AllowPolicyDeleteResponse: - """Removes an email allow policy. + ) -> Optional[AllowPolicyDeleteResponse]: + """Removes an allow policy. - Previously allowed senders will be subject to - normal security scanning. + After deletion, emails matching this pattern will be + subject to normal security scanning and disposition actions. Args: - account_id: Account Identifier + account_id: Identifier. - policy_id: The unique identifier for the allow policy. + policy_id: Allow policy identifier extra_headers: Send extra headers @@ -248,6 +274,8 @@ def delete( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not policy_id: + raise ValueError(f"Expected a non-empty value for `policy_id` but received {policy_id!r}") return self._delete( path_template( "/accounts/{account_id}/email-security/settings/allow_policies/{policy_id}", @@ -259,47 +287,66 @@ def delete( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[AllowPolicyDeleteResponse]._unwrapper, + post_parser=ResultWrapper[Optional[AllowPolicyDeleteResponse]]._unwrapper, ), - cast_to=cast(Type[AllowPolicyDeleteResponse], ResultWrapper[AllowPolicyDeleteResponse]), + cast_to=cast(Type[Optional[AllowPolicyDeleteResponse]], ResultWrapper[AllowPolicyDeleteResponse]), ) def edit( self, - policy_id: int, + policy_id: str, *, account_id: str, comments: Optional[str] | Omit = omit, - is_acceptable_sender: Optional[bool] | Omit = omit, - is_exempt_recipient: Optional[bool] | Omit = omit, - is_regex: Optional[bool] | Omit = omit, - is_trusted_sender: Optional[bool] | Omit = omit, - pattern: Optional[str] | Omit = omit, - pattern_type: Optional[Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"]] | Omit = omit, - verify_sender: Optional[bool] | Omit = omit, + is_acceptable_sender: bool | Omit = omit, + is_exempt_recipient: bool | Omit = omit, + is_recipient: bool | Omit = omit, + is_regex: bool | Omit = omit, + is_sender: bool | Omit = omit, + is_spoof: bool | Omit = omit, + is_trusted_sender: bool | Omit = omit, + pattern: str | Omit = omit, + pattern_type: Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"] | Omit = omit, + verify_sender: bool | 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, - ) -> AllowPolicyEditResponse: - """ - Updates an existing email allow policy, modifying its matching criteria or - scope. + ) -> Optional[AllowPolicyEditResponse]: + """Updates an existing allow policy. + + Only provided fields will be modified. Changes + take effect for new emails matching the pattern. Args: - account_id: Account Identifier + account_id: Identifier. - policy_id: The unique identifier for the allow policy. + policy_id: Allow policy identifier is_acceptable_sender: Messages from this sender will be exempted from Spam, Spoof and Bulk - dispositions. Note: This will not exempt messages with Malicious or Suspicious + dispositions. Note - This will not exempt messages with Malicious or Suspicious dispositions. - is_exempt_recipient: Messages to this recipient will bypass all detections. + is_exempt_recipient: Messages to this recipient will bypass all detections + + is_recipient: + Deprecated as of July 1, 2025. Use `is_exempt_recipient` instead. End of life: + July 1, 2026. + + is_sender: + Deprecated as of July 1, 2025. Use `is_trusted_sender` instead. End of life: + July 1, 2026. + + is_spoof: + Deprecated as of July 1, 2025. Use `is_acceptable_sender` instead. End of life: + July 1, 2026. - is_trusted_sender: Messages from this sender will bypass all detections and link following. + is_trusted_sender: Messages from this sender will bypass all detections and link following + + pattern_type: Type of pattern matching. Note: UNKNOWN is deprecated and cannot be used when + creating or updating policies, but may be returned for existing entries. verify_sender: Enforce DMARC, SPF or DKIM authentication. When on, Email Security only honors policies that pass authentication. @@ -314,6 +361,8 @@ def edit( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not policy_id: + raise ValueError(f"Expected a non-empty value for `policy_id` but received {policy_id!r}") return self._patch( path_template( "/accounts/{account_id}/email-security/settings/allow_policies/{policy_id}", @@ -325,7 +374,10 @@ def edit( "comments": comments, "is_acceptable_sender": is_acceptable_sender, "is_exempt_recipient": is_exempt_recipient, + "is_recipient": is_recipient, "is_regex": is_regex, + "is_sender": is_sender, + "is_spoof": is_spoof, "is_trusted_sender": is_trusted_sender, "pattern": pattern, "pattern_type": pattern_type, @@ -338,14 +390,14 @@ def edit( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[AllowPolicyEditResponse]._unwrapper, + post_parser=ResultWrapper[Optional[AllowPolicyEditResponse]]._unwrapper, ), - cast_to=cast(Type[AllowPolicyEditResponse], ResultWrapper[AllowPolicyEditResponse]), + cast_to=cast(Type[Optional[AllowPolicyEditResponse]], ResultWrapper[AllowPolicyEditResponse]), ) def get( self, - policy_id: int, + policy_id: str, *, account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -354,15 +406,15 @@ def get( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AllowPolicyGetResponse: + ) -> Optional[AllowPolicyGetResponse]: """ - Retrieves details for a specific email allow policy, including its matching - criteria and scope. + Retrieves details for a specific allow policy including its pattern, + dispositions that are exempted, and whether it applies to all detections. Args: - account_id: Account Identifier + account_id: Identifier. - policy_id: The unique identifier for the allow policy. + policy_id: Allow policy identifier extra_headers: Send extra headers @@ -374,6 +426,8 @@ def get( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not policy_id: + raise ValueError(f"Expected a non-empty value for `policy_id` but received {policy_id!r}") return self._get( path_template( "/accounts/{account_id}/email-security/settings/allow_policies/{policy_id}", @@ -385,9 +439,9 @@ def get( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[AllowPolicyGetResponse]._unwrapper, + post_parser=ResultWrapper[Optional[AllowPolicyGetResponse]]._unwrapper, ), - cast_to=cast(Type[AllowPolicyGetResponse], ResultWrapper[AllowPolicyGetResponse]), + cast_to=cast(Type[Optional[AllowPolicyGetResponse]], ResultWrapper[AllowPolicyGetResponse]), ) @@ -432,25 +486,42 @@ async def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AllowPolicyCreateResponse: - """ - Creates a new email allow policy that permits specific senders, domains, or - patterns to bypass security scanning. + ) -> Optional[AllowPolicyCreateResponse]: + """Creates a new allow policy that exempts matching emails from security + detections. + + Use with caution as this bypasses email security scanning. Policies + can match on sender patterns and apply to specific detections or all detections. Args: - account_id: Account Identifier + account_id: Identifier. is_acceptable_sender: Messages from this sender will be exempted from Spam, Spoof and Bulk - dispositions. Note: This will not exempt messages with Malicious or Suspicious + dispositions. Note - This will not exempt messages with Malicious or Suspicious dispositions. - is_exempt_recipient: Messages to this recipient will bypass all detections. + is_exempt_recipient: Messages to this recipient will bypass all detections + + is_trusted_sender: Messages from this sender will bypass all detections and link following - is_trusted_sender: Messages from this sender will bypass all detections and link following. + pattern_type: Type of pattern matching. Note: UNKNOWN is deprecated and cannot be used when + creating or updating policies, but may be returned for existing entries. verify_sender: Enforce DMARC, SPF or DKIM authentication. When on, Email Security only honors policies that pass authentication. + is_recipient: + Deprecated as of July 1, 2025. Use `is_exempt_recipient` instead. End of life: + July 1, 2026. + + is_sender: + Deprecated as of July 1, 2025. Use `is_trusted_sender` instead. End of life: + July 1, 2026. + + is_spoof: + Deprecated as of July 1, 2025. Use `is_acceptable_sender` instead. End of life: + July 1, 2026. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -484,9 +555,9 @@ async def create( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[AllowPolicyCreateResponse]._unwrapper, + post_parser=ResultWrapper[Optional[AllowPolicyCreateResponse]]._unwrapper, ), - cast_to=cast(Type[AllowPolicyCreateResponse], ResultWrapper[AllowPolicyCreateResponse]), + cast_to=cast(Type[Optional[AllowPolicyCreateResponse]], ResultWrapper[AllowPolicyCreateResponse]), ) def list( @@ -496,9 +567,6 @@ def list( direction: Literal["asc", "desc"] | Omit = omit, is_acceptable_sender: bool | Omit = omit, is_exempt_recipient: bool | Omit = omit, - is_recipient: bool | Omit = omit, - is_sender: bool | Omit = omit, - is_spoof: bool | Omit = omit, is_trusted_sender: bool | Omit = omit, order: Literal["pattern", "created_at"] | Omit = omit, page: int | Omit = omit, @@ -514,23 +582,38 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[AllowPolicyListResponse, AsyncV4PagePaginationArray[AllowPolicyListResponse]]: - """ - Lists, searches, and sorts an account’s email allow policies. + """Returns a paginated list of email allow policies. + + These policies exempt matching + emails from security detection, allowing them to bypass disposition actions. + Supports filtering by pattern type and policy attributes. Args: - account_id: Account Identifier + account_id: Identifier. direction: The sorting direction. - order: The field to sort by. + is_acceptable_sender: Filter to show only policies where messages from the sender are exempted from + Spam, Spoof, and Bulk dispositions (not Malicious or Suspicious). + + is_exempt_recipient: Filter to show only policies where messages to the recipient bypass all + detections. + + is_trusted_sender: Filter to show only policies where messages from the sender bypass all + detections and link following. - page: The page number of paginated results. + order: Field to sort by. - per_page: The number of results per page. + page: Current page within paginated list of results. - search: Allows searching in multiple properties of a record simultaneously. This - parameter is intended for human users, not automation. Its exact behavior is - intentionally left unspecified and is subject to change in the future. + pattern_type: Type of pattern matching. Note: UNKNOWN is deprecated and cannot be used when + creating or updating policies, but may be returned for existing entries. + + per_page: The number of results per page. Maximum value is 1000. + + search: Search term for filtering records. Behavior may change. + + verify_sender: Filter to show only policies that enforce DMARC, SPF, or DKIM authentication. extra_headers: Send extra headers @@ -555,9 +638,6 @@ def list( "direction": direction, "is_acceptable_sender": is_acceptable_sender, "is_exempt_recipient": is_exempt_recipient, - "is_recipient": is_recipient, - "is_sender": is_sender, - "is_spoof": is_spoof, "is_trusted_sender": is_trusted_sender, "order": order, "page": page, @@ -575,7 +655,7 @@ def list( async def delete( self, - policy_id: int, + policy_id: str, *, account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -584,16 +664,16 @@ async def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AllowPolicyDeleteResponse: - """Removes an email allow policy. + ) -> Optional[AllowPolicyDeleteResponse]: + """Removes an allow policy. - Previously allowed senders will be subject to - normal security scanning. + After deletion, emails matching this pattern will be + subject to normal security scanning and disposition actions. Args: - account_id: Account Identifier + account_id: Identifier. - policy_id: The unique identifier for the allow policy. + policy_id: Allow policy identifier extra_headers: Send extra headers @@ -605,6 +685,8 @@ async def delete( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not policy_id: + raise ValueError(f"Expected a non-empty value for `policy_id` but received {policy_id!r}") return await self._delete( path_template( "/accounts/{account_id}/email-security/settings/allow_policies/{policy_id}", @@ -616,47 +698,66 @@ async def delete( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[AllowPolicyDeleteResponse]._unwrapper, + post_parser=ResultWrapper[Optional[AllowPolicyDeleteResponse]]._unwrapper, ), - cast_to=cast(Type[AllowPolicyDeleteResponse], ResultWrapper[AllowPolicyDeleteResponse]), + cast_to=cast(Type[Optional[AllowPolicyDeleteResponse]], ResultWrapper[AllowPolicyDeleteResponse]), ) async def edit( self, - policy_id: int, + policy_id: str, *, account_id: str, comments: Optional[str] | Omit = omit, - is_acceptable_sender: Optional[bool] | Omit = omit, - is_exempt_recipient: Optional[bool] | Omit = omit, - is_regex: Optional[bool] | Omit = omit, - is_trusted_sender: Optional[bool] | Omit = omit, - pattern: Optional[str] | Omit = omit, - pattern_type: Optional[Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"]] | Omit = omit, - verify_sender: Optional[bool] | Omit = omit, + is_acceptable_sender: bool | Omit = omit, + is_exempt_recipient: bool | Omit = omit, + is_recipient: bool | Omit = omit, + is_regex: bool | Omit = omit, + is_sender: bool | Omit = omit, + is_spoof: bool | Omit = omit, + is_trusted_sender: bool | Omit = omit, + pattern: str | Omit = omit, + pattern_type: Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"] | Omit = omit, + verify_sender: bool | 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, - ) -> AllowPolicyEditResponse: - """ - Updates an existing email allow policy, modifying its matching criteria or - scope. + ) -> Optional[AllowPolicyEditResponse]: + """Updates an existing allow policy. + + Only provided fields will be modified. Changes + take effect for new emails matching the pattern. Args: - account_id: Account Identifier + account_id: Identifier. - policy_id: The unique identifier for the allow policy. + policy_id: Allow policy identifier is_acceptable_sender: Messages from this sender will be exempted from Spam, Spoof and Bulk - dispositions. Note: This will not exempt messages with Malicious or Suspicious + dispositions. Note - This will not exempt messages with Malicious or Suspicious dispositions. - is_exempt_recipient: Messages to this recipient will bypass all detections. + is_exempt_recipient: Messages to this recipient will bypass all detections + + is_recipient: + Deprecated as of July 1, 2025. Use `is_exempt_recipient` instead. End of life: + July 1, 2026. + + is_sender: + Deprecated as of July 1, 2025. Use `is_trusted_sender` instead. End of life: + July 1, 2026. + + is_spoof: + Deprecated as of July 1, 2025. Use `is_acceptable_sender` instead. End of life: + July 1, 2026. - is_trusted_sender: Messages from this sender will bypass all detections and link following. + is_trusted_sender: Messages from this sender will bypass all detections and link following + + pattern_type: Type of pattern matching. Note: UNKNOWN is deprecated and cannot be used when + creating or updating policies, but may be returned for existing entries. verify_sender: Enforce DMARC, SPF or DKIM authentication. When on, Email Security only honors policies that pass authentication. @@ -671,6 +772,8 @@ async def edit( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not policy_id: + raise ValueError(f"Expected a non-empty value for `policy_id` but received {policy_id!r}") return await self._patch( path_template( "/accounts/{account_id}/email-security/settings/allow_policies/{policy_id}", @@ -682,7 +785,10 @@ async def edit( "comments": comments, "is_acceptable_sender": is_acceptable_sender, "is_exempt_recipient": is_exempt_recipient, + "is_recipient": is_recipient, "is_regex": is_regex, + "is_sender": is_sender, + "is_spoof": is_spoof, "is_trusted_sender": is_trusted_sender, "pattern": pattern, "pattern_type": pattern_type, @@ -695,14 +801,14 @@ async def edit( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[AllowPolicyEditResponse]._unwrapper, + post_parser=ResultWrapper[Optional[AllowPolicyEditResponse]]._unwrapper, ), - cast_to=cast(Type[AllowPolicyEditResponse], ResultWrapper[AllowPolicyEditResponse]), + cast_to=cast(Type[Optional[AllowPolicyEditResponse]], ResultWrapper[AllowPolicyEditResponse]), ) async def get( self, - policy_id: int, + policy_id: str, *, account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -711,15 +817,15 @@ async def get( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AllowPolicyGetResponse: + ) -> Optional[AllowPolicyGetResponse]: """ - Retrieves details for a specific email allow policy, including its matching - criteria and scope. + Retrieves details for a specific allow policy including its pattern, + dispositions that are exempted, and whether it applies to all detections. Args: - account_id: Account Identifier + account_id: Identifier. - policy_id: The unique identifier for the allow policy. + policy_id: Allow policy identifier extra_headers: Send extra headers @@ -731,6 +837,8 @@ async def get( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not policy_id: + raise ValueError(f"Expected a non-empty value for `policy_id` but received {policy_id!r}") return await self._get( path_template( "/accounts/{account_id}/email-security/settings/allow_policies/{policy_id}", @@ -742,9 +850,9 @@ async def get( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[AllowPolicyGetResponse]._unwrapper, + post_parser=ResultWrapper[Optional[AllowPolicyGetResponse]]._unwrapper, ), - cast_to=cast(Type[AllowPolicyGetResponse], ResultWrapper[AllowPolicyGetResponse]), + cast_to=cast(Type[Optional[AllowPolicyGetResponse]], ResultWrapper[AllowPolicyGetResponse]), ) diff --git a/src/cloudflare/resources/email_security/settings/block_senders.py b/src/cloudflare/resources/email_security/settings/block_senders.py index 9f22d1a96a5..b0c57670eac 100644 --- a/src/cloudflare/resources/email_security/settings/block_senders.py +++ b/src/cloudflare/resources/email_security/settings/block_senders.py @@ -68,13 +68,18 @@ def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> BlockSenderCreateResponse: - """ - Adds a sender pattern to the email block list, preventing messages from matching - senders from being delivered. + ) -> Optional[BlockSenderCreateResponse]: + """Creates a new blocked sender pattern. + + Emails matching this pattern will be + blocked from delivery. Patterns can be email addresses, domains, or IP + addresses, and support regular expressions. Args: - account_id: Account Identifier + account_id: Identifier. + + pattern_type: Type of pattern matching. Note: UNKNOWN is deprecated and cannot be used when + creating or updating policies, but may be returned for existing entries. extra_headers: Send extra headers @@ -102,9 +107,9 @@ def create( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[BlockSenderCreateResponse]._unwrapper, + post_parser=ResultWrapper[Optional[BlockSenderCreateResponse]]._unwrapper, ), - cast_to=cast(Type[BlockSenderCreateResponse], ResultWrapper[BlockSenderCreateResponse]), + cast_to=cast(Type[Optional[BlockSenderCreateResponse]], ResultWrapper[BlockSenderCreateResponse]), ) def list( @@ -125,23 +130,28 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncV4PagePaginationArray[BlockSenderListResponse]: - """ - Lists all blocked sender entries with their patterns and block reasons. + """Returns a paginated list of blocked email sender patterns. + + These patterns + prevent emails from matching senders from being delivered. Supports filtering by + pattern type and searching across patterns. Args: - account_id: Account Identifier + account_id: Identifier. direction: The sorting direction. - order: The field to sort by. + order: Field to sort by. + + page: Current page within paginated list of results. + + pattern: Filter by pattern value. - page: The page number of paginated results. + pattern_type: Filter by pattern type. - per_page: The number of results per page. + per_page: The number of results per page. Maximum value is 1000. - search: Allows searching in multiple properties of a record simultaneously. This - parameter is intended for human users, not automation. Its exact behavior is - intentionally left unspecified and is subject to change in the future. + search: Search term for filtering records. Behavior may change. extra_headers: Send extra headers @@ -179,7 +189,7 @@ def list( def delete( self, - pattern_id: int, + pattern_id: str, *, account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -188,15 +198,16 @@ def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> BlockSenderDeleteResponse: - """ - Removes a sender from the email block list, allowing their messages to be - delivered normally. + ) -> Optional[BlockSenderDeleteResponse]: + """Removes a blocked sender pattern. + + After deletion, emails from this sender will + no longer be automatically blocked based on this rule. Args: - account_id: Account Identifier + account_id: Identifier. - pattern_id: The unique identifier for the allow policy. + pattern_id: Blocked sender pattern identifier extra_headers: Send extra headers @@ -208,6 +219,8 @@ def delete( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not pattern_id: + raise ValueError(f"Expected a non-empty value for `pattern_id` but received {pattern_id!r}") return self._delete( path_template( "/accounts/{account_id}/email-security/settings/block_senders/{pattern_id}", @@ -219,34 +232,39 @@ def delete( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[BlockSenderDeleteResponse]._unwrapper, + post_parser=ResultWrapper[Optional[BlockSenderDeleteResponse]]._unwrapper, ), - cast_to=cast(Type[BlockSenderDeleteResponse], ResultWrapper[BlockSenderDeleteResponse]), + cast_to=cast(Type[Optional[BlockSenderDeleteResponse]], ResultWrapper[BlockSenderDeleteResponse]), ) def edit( self, - pattern_id: int, + pattern_id: str, *, account_id: str, comments: Optional[str] | Omit = omit, - is_regex: Optional[bool] | Omit = omit, - pattern: Optional[str] | Omit = omit, - pattern_type: Optional[Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"]] | Omit = omit, + is_regex: bool | Omit = omit, + pattern: str | Omit = omit, + pattern_type: Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"] | 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, - ) -> BlockSenderEditResponse: - """ - Modifies a blocked sender entry, updating its pattern or block reason. + ) -> Optional[BlockSenderEditResponse]: + """Updates an existing blocked sender pattern. + + Only provided fields will be + modified. The pattern will continue blocking emails until deleted. Args: - account_id: Account Identifier + account_id: Identifier. + + pattern_id: Blocked sender pattern identifier - pattern_id: The unique identifier for the allow policy. + pattern_type: Type of pattern matching. Note: UNKNOWN is deprecated and cannot be used when + creating or updating policies, but may be returned for existing entries. extra_headers: Send extra headers @@ -258,6 +276,8 @@ def edit( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not pattern_id: + raise ValueError(f"Expected a non-empty value for `pattern_id` but received {pattern_id!r}") return self._patch( path_template( "/accounts/{account_id}/email-security/settings/block_senders/{pattern_id}", @@ -278,14 +298,14 @@ def edit( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[BlockSenderEditResponse]._unwrapper, + post_parser=ResultWrapper[Optional[BlockSenderEditResponse]]._unwrapper, ), - cast_to=cast(Type[BlockSenderEditResponse], ResultWrapper[BlockSenderEditResponse]), + cast_to=cast(Type[Optional[BlockSenderEditResponse]], ResultWrapper[BlockSenderEditResponse]), ) def get( self, - pattern_id: int, + pattern_id: str, *, account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -294,15 +314,15 @@ def get( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> BlockSenderGetResponse: + ) -> Optional[BlockSenderGetResponse]: """ - Gets information about a specific blocked sender entry, including the pattern - and block reason. + Retrieves details for a specific blocked sender pattern including its pattern + type, value, and metadata. Args: - account_id: Account Identifier + account_id: Identifier. - pattern_id: The unique identifier for the allow policy. + pattern_id: Blocked sender pattern identifier extra_headers: Send extra headers @@ -314,6 +334,8 @@ def get( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not pattern_id: + raise ValueError(f"Expected a non-empty value for `pattern_id` but received {pattern_id!r}") return self._get( path_template( "/accounts/{account_id}/email-security/settings/block_senders/{pattern_id}", @@ -325,9 +347,9 @@ def get( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[BlockSenderGetResponse]._unwrapper, + post_parser=ResultWrapper[Optional[BlockSenderGetResponse]]._unwrapper, ), - cast_to=cast(Type[BlockSenderGetResponse], ResultWrapper[BlockSenderGetResponse]), + cast_to=cast(Type[Optional[BlockSenderGetResponse]], ResultWrapper[BlockSenderGetResponse]), ) @@ -365,13 +387,18 @@ async def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> BlockSenderCreateResponse: - """ - Adds a sender pattern to the email block list, preventing messages from matching - senders from being delivered. + ) -> Optional[BlockSenderCreateResponse]: + """Creates a new blocked sender pattern. + + Emails matching this pattern will be + blocked from delivery. Patterns can be email addresses, domains, or IP + addresses, and support regular expressions. Args: - account_id: Account Identifier + account_id: Identifier. + + pattern_type: Type of pattern matching. Note: UNKNOWN is deprecated and cannot be used when + creating or updating policies, but may be returned for existing entries. extra_headers: Send extra headers @@ -399,9 +426,9 @@ async def create( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[BlockSenderCreateResponse]._unwrapper, + post_parser=ResultWrapper[Optional[BlockSenderCreateResponse]]._unwrapper, ), - cast_to=cast(Type[BlockSenderCreateResponse], ResultWrapper[BlockSenderCreateResponse]), + cast_to=cast(Type[Optional[BlockSenderCreateResponse]], ResultWrapper[BlockSenderCreateResponse]), ) def list( @@ -422,23 +449,28 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[BlockSenderListResponse, AsyncV4PagePaginationArray[BlockSenderListResponse]]: - """ - Lists all blocked sender entries with their patterns and block reasons. + """Returns a paginated list of blocked email sender patterns. + + These patterns + prevent emails from matching senders from being delivered. Supports filtering by + pattern type and searching across patterns. Args: - account_id: Account Identifier + account_id: Identifier. direction: The sorting direction. - order: The field to sort by. + order: Field to sort by. + + page: Current page within paginated list of results. + + pattern: Filter by pattern value. - page: The page number of paginated results. + pattern_type: Filter by pattern type. - per_page: The number of results per page. + per_page: The number of results per page. Maximum value is 1000. - search: Allows searching in multiple properties of a record simultaneously. This - parameter is intended for human users, not automation. Its exact behavior is - intentionally left unspecified and is subject to change in the future. + search: Search term for filtering records. Behavior may change. extra_headers: Send extra headers @@ -476,7 +508,7 @@ def list( async def delete( self, - pattern_id: int, + pattern_id: str, *, account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -485,15 +517,16 @@ async def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> BlockSenderDeleteResponse: - """ - Removes a sender from the email block list, allowing their messages to be - delivered normally. + ) -> Optional[BlockSenderDeleteResponse]: + """Removes a blocked sender pattern. + + After deletion, emails from this sender will + no longer be automatically blocked based on this rule. Args: - account_id: Account Identifier + account_id: Identifier. - pattern_id: The unique identifier for the allow policy. + pattern_id: Blocked sender pattern identifier extra_headers: Send extra headers @@ -505,6 +538,8 @@ async def delete( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not pattern_id: + raise ValueError(f"Expected a non-empty value for `pattern_id` but received {pattern_id!r}") return await self._delete( path_template( "/accounts/{account_id}/email-security/settings/block_senders/{pattern_id}", @@ -516,34 +551,39 @@ async def delete( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[BlockSenderDeleteResponse]._unwrapper, + post_parser=ResultWrapper[Optional[BlockSenderDeleteResponse]]._unwrapper, ), - cast_to=cast(Type[BlockSenderDeleteResponse], ResultWrapper[BlockSenderDeleteResponse]), + cast_to=cast(Type[Optional[BlockSenderDeleteResponse]], ResultWrapper[BlockSenderDeleteResponse]), ) async def edit( self, - pattern_id: int, + pattern_id: str, *, account_id: str, comments: Optional[str] | Omit = omit, - is_regex: Optional[bool] | Omit = omit, - pattern: Optional[str] | Omit = omit, - pattern_type: Optional[Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"]] | Omit = omit, + is_regex: bool | Omit = omit, + pattern: str | Omit = omit, + pattern_type: Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"] | 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, - ) -> BlockSenderEditResponse: - """ - Modifies a blocked sender entry, updating its pattern or block reason. + ) -> Optional[BlockSenderEditResponse]: + """Updates an existing blocked sender pattern. + + Only provided fields will be + modified. The pattern will continue blocking emails until deleted. Args: - account_id: Account Identifier + account_id: Identifier. + + pattern_id: Blocked sender pattern identifier - pattern_id: The unique identifier for the allow policy. + pattern_type: Type of pattern matching. Note: UNKNOWN is deprecated and cannot be used when + creating or updating policies, but may be returned for existing entries. extra_headers: Send extra headers @@ -555,6 +595,8 @@ async def edit( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not pattern_id: + raise ValueError(f"Expected a non-empty value for `pattern_id` but received {pattern_id!r}") return await self._patch( path_template( "/accounts/{account_id}/email-security/settings/block_senders/{pattern_id}", @@ -575,14 +617,14 @@ async def edit( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[BlockSenderEditResponse]._unwrapper, + post_parser=ResultWrapper[Optional[BlockSenderEditResponse]]._unwrapper, ), - cast_to=cast(Type[BlockSenderEditResponse], ResultWrapper[BlockSenderEditResponse]), + cast_to=cast(Type[Optional[BlockSenderEditResponse]], ResultWrapper[BlockSenderEditResponse]), ) async def get( self, - pattern_id: int, + pattern_id: str, *, account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -591,15 +633,15 @@ async def get( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> BlockSenderGetResponse: + ) -> Optional[BlockSenderGetResponse]: """ - Gets information about a specific blocked sender entry, including the pattern - and block reason. + Retrieves details for a specific blocked sender pattern including its pattern + type, value, and metadata. Args: - account_id: Account Identifier + account_id: Identifier. - pattern_id: The unique identifier for the allow policy. + pattern_id: Blocked sender pattern identifier extra_headers: Send extra headers @@ -611,6 +653,8 @@ async def get( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not pattern_id: + raise ValueError(f"Expected a non-empty value for `pattern_id` but received {pattern_id!r}") return await self._get( path_template( "/accounts/{account_id}/email-security/settings/block_senders/{pattern_id}", @@ -622,9 +666,9 @@ async def get( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[BlockSenderGetResponse]._unwrapper, + post_parser=ResultWrapper[Optional[BlockSenderGetResponse]]._unwrapper, ), - cast_to=cast(Type[BlockSenderGetResponse], ResultWrapper[BlockSenderGetResponse]), + cast_to=cast(Type[Optional[BlockSenderGetResponse]], ResultWrapper[BlockSenderGetResponse]), ) diff --git a/src/cloudflare/resources/email_security/settings/domains.py b/src/cloudflare/resources/email_security/settings/domains.py index 46628f5da7a..c8ca2d9854a 100644 --- a/src/cloudflare/resources/email_security/settings/domains.py +++ b/src/cloudflare/resources/email_security/settings/domains.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import List, Type, cast +from typing import List, Type, Optional, cast from typing_extensions import Literal import httpx @@ -18,14 +18,13 @@ async_to_streamed_response_wrapper, ) from ...._wrappers import ResultWrapper -from ....pagination import SyncSinglePage, AsyncSinglePage, SyncV4PagePaginationArray, AsyncV4PagePaginationArray +from ....pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray from ...._base_client import AsyncPaginator, make_request_options from ....types.email_security.settings import domain_edit_params, domain_list_params from ....types.email_security.settings.domain_get_response import DomainGetResponse from ....types.email_security.settings.domain_edit_response import DomainEditResponse from ....types.email_security.settings.domain_list_response import DomainListResponse from ....types.email_security.settings.domain_delete_response import DomainDeleteResponse -from ....types.email_security.settings.domain_bulk_delete_response import DomainBulkDeleteResponse __all__ = ["DomainsResource", "AsyncDomainsResource"] @@ -63,6 +62,7 @@ def list( page: int | Omit = omit, per_page: int | Omit = omit, search: str | Omit = omit, + status: Literal["pending", "active", "failed", "timeout"] | 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, @@ -70,31 +70,34 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncV4PagePaginationArray[DomainListResponse]: - """ - Lists, searches, and sorts an account’s email domains. + """Returns a paginated list of email domains protected by Email Security. + + Includes + domain configuration, delivery modes, and authorization status. Supports + filtering by delivery mode and integration ID. Args: - account_id: Account Identifier + account_id: Identifier. - active_delivery_mode: Filters response to domains with the currently active delivery mode. + active_delivery_mode: Currently active delivery mode to filter by. - allowed_delivery_mode: Filters response to domains with the provided delivery mode. + allowed_delivery_mode: Delivery mode to filter by. direction: The sorting direction. - domain: Filters results by the provided domains, allowing for multiple occurrences. + domain: Domain names to filter by. + + integration_id: Integration ID to filter by. - integration_id: Filters response to domains with the provided integration ID. + order: Field to sort by. - order: The field to sort by. + page: Current page within paginated list of results. - page: The page number of paginated results. + per_page: The number of results per page. Maximum value is 1000. - per_page: The number of results per page. + search: Search term for filtering records. Behavior may change. - search: Allows searching in multiple properties of a record simultaneously. This - parameter is intended for human users, not automation. Its exact behavior is - intentionally left unspecified and is subject to change in the future. + status: Filters response to domains with the provided status. extra_headers: Send extra headers @@ -125,6 +128,7 @@ def list( "page": page, "per_page": per_page, "search": search, + "status": status, }, domain_list_params.DomainListParams, ), @@ -134,7 +138,7 @@ def list( def delete( self, - domain_id: int, + domain_id: str, *, account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -143,14 +147,17 @@ def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> DomainDeleteResponse: - """ - Unprotect an email domain + ) -> Optional[DomainDeleteResponse]: + """Removes email security protection from a domain. + + After deletion, emails for this + domain will no longer be processed by Email Security. This action cannot be + undone. Args: - account_id: Account Identifier + account_id: Identifier. - domain_id: The unique identifier for the domain. + domain_id: Domain identifier extra_headers: Send extra headers @@ -162,6 +169,8 @@ def delete( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not domain_id: + raise ValueError(f"Expected a non-empty value for `domain_id` but received {domain_id!r}") return self._delete( path_template( "/accounts/{account_id}/email-security/settings/domains/{domain_id}", @@ -173,55 +182,16 @@ def delete( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[DomainDeleteResponse]._unwrapper, + post_parser=ResultWrapper[Optional[DomainDeleteResponse]]._unwrapper, ), - cast_to=cast(Type[DomainDeleteResponse], ResultWrapper[DomainDeleteResponse]), - ) - - def bulk_delete( - self, - *, - account_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, - ) -> SyncSinglePage[DomainBulkDeleteResponse]: - """ - Bulk removes multiple domains from email security configuration in a single - request. - - Args: - account_id: Account Identifier - - 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 account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return self._get_api_list( - path_template("/accounts/{account_id}/email-security/settings/domains", account_id=account_id), - page=SyncSinglePage[DomainBulkDeleteResponse], - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - model=DomainBulkDeleteResponse, - method="delete", + cast_to=cast(Type[Optional[DomainDeleteResponse]], ResultWrapper[DomainDeleteResponse]), ) def edit( self, - domain_id: int, + domain_id: str, *, account_id: str, - ip_restrictions: SequenceNotStr[str], allowed_delivery_modes: List[Literal["DIRECT", "BCC", "JOURNAL", "API", "RETRO_SCAN"]] | Omit = omit, domain: str | Omit = omit, drop_dispositions: List[ @@ -240,7 +210,8 @@ def edit( ] | Omit = omit, folder: Literal["AllItems", "Inbox"] | Omit = omit, - integration_id: str | Omit = omit, + integration_id: Optional[str] | Omit = omit, + ip_restrictions: SequenceNotStr[str] | Omit = omit, lookback_hops: int | Omit = omit, regions: List[Literal["GLOBAL", "AU", "DE", "IN", "US"]] | Omit = omit, require_tls_inbound: bool | Omit = omit, @@ -252,14 +223,17 @@ def edit( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> DomainEditResponse: - """ - Updates configuration for a domain in email security. + ) -> Optional[DomainEditResponse]: + """Updates configuration for a protected email domain. + + Only provided fields will be + modified. Changes affect delivery mode, security settings, and regional + processing. Args: - account_id: Account Identifier + account_id: Identifier. - domain_id: The unique identifier for the domain. + domain_id: Domain identifier extra_headers: Send extra headers @@ -271,6 +245,8 @@ def edit( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not domain_id: + raise ValueError(f"Expected a non-empty value for `domain_id` but received {domain_id!r}") return self._patch( path_template( "/accounts/{account_id}/email-security/settings/domains/{domain_id}", @@ -279,12 +255,12 @@ def edit( ), body=maybe_transform( { - "ip_restrictions": ip_restrictions, "allowed_delivery_modes": allowed_delivery_modes, "domain": domain, "drop_dispositions": drop_dispositions, "folder": folder, "integration_id": integration_id, + "ip_restrictions": ip_restrictions, "lookback_hops": lookback_hops, "regions": regions, "require_tls_inbound": require_tls_inbound, @@ -298,14 +274,14 @@ def edit( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[DomainEditResponse]._unwrapper, + post_parser=ResultWrapper[Optional[DomainEditResponse]]._unwrapper, ), - cast_to=cast(Type[DomainEditResponse], ResultWrapper[DomainEditResponse]), + cast_to=cast(Type[Optional[DomainEditResponse]], ResultWrapper[DomainEditResponse]), ) def get( self, - domain_id: int, + domain_id: str, *, account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -314,14 +290,15 @@ def get( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> DomainGetResponse: + ) -> Optional[DomainGetResponse]: """ - Gets configuration details for a specific domain in email security. + Retrieves detailed information for a specific protected email domain including + its delivery configuration, SPF/DMARC status, and authorization state. Args: - account_id: Account Identifier + account_id: Identifier. - domain_id: The unique identifier for the domain. + domain_id: Domain identifier extra_headers: Send extra headers @@ -333,6 +310,8 @@ def get( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not domain_id: + raise ValueError(f"Expected a non-empty value for `domain_id` but received {domain_id!r}") return self._get( path_template( "/accounts/{account_id}/email-security/settings/domains/{domain_id}", @@ -344,9 +323,9 @@ def get( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[DomainGetResponse]._unwrapper, + post_parser=ResultWrapper[Optional[DomainGetResponse]]._unwrapper, ), - cast_to=cast(Type[DomainGetResponse], ResultWrapper[DomainGetResponse]), + cast_to=cast(Type[Optional[DomainGetResponse]], ResultWrapper[DomainGetResponse]), ) @@ -383,6 +362,7 @@ def list( page: int | Omit = omit, per_page: int | Omit = omit, search: str | Omit = omit, + status: Literal["pending", "active", "failed", "timeout"] | 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, @@ -390,31 +370,34 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[DomainListResponse, AsyncV4PagePaginationArray[DomainListResponse]]: - """ - Lists, searches, and sorts an account’s email domains. + """Returns a paginated list of email domains protected by Email Security. + + Includes + domain configuration, delivery modes, and authorization status. Supports + filtering by delivery mode and integration ID. Args: - account_id: Account Identifier + account_id: Identifier. - active_delivery_mode: Filters response to domains with the currently active delivery mode. + active_delivery_mode: Currently active delivery mode to filter by. - allowed_delivery_mode: Filters response to domains with the provided delivery mode. + allowed_delivery_mode: Delivery mode to filter by. direction: The sorting direction. - domain: Filters results by the provided domains, allowing for multiple occurrences. + domain: Domain names to filter by. - integration_id: Filters response to domains with the provided integration ID. + integration_id: Integration ID to filter by. - order: The field to sort by. + order: Field to sort by. - page: The page number of paginated results. + page: Current page within paginated list of results. - per_page: The number of results per page. + per_page: The number of results per page. Maximum value is 1000. - search: Allows searching in multiple properties of a record simultaneously. This - parameter is intended for human users, not automation. Its exact behavior is - intentionally left unspecified and is subject to change in the future. + search: Search term for filtering records. Behavior may change. + + status: Filters response to domains with the provided status. extra_headers: Send extra headers @@ -445,6 +428,7 @@ def list( "page": page, "per_page": per_page, "search": search, + "status": status, }, domain_list_params.DomainListParams, ), @@ -454,7 +438,7 @@ def list( async def delete( self, - domain_id: int, + domain_id: str, *, account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -463,14 +447,17 @@ async def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> DomainDeleteResponse: - """ - Unprotect an email domain + ) -> Optional[DomainDeleteResponse]: + """Removes email security protection from a domain. + + After deletion, emails for this + domain will no longer be processed by Email Security. This action cannot be + undone. Args: - account_id: Account Identifier + account_id: Identifier. - domain_id: The unique identifier for the domain. + domain_id: Domain identifier extra_headers: Send extra headers @@ -482,6 +469,8 @@ async def delete( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not domain_id: + raise ValueError(f"Expected a non-empty value for `domain_id` but received {domain_id!r}") return await self._delete( path_template( "/accounts/{account_id}/email-security/settings/domains/{domain_id}", @@ -493,55 +482,16 @@ async def delete( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[DomainDeleteResponse]._unwrapper, + post_parser=ResultWrapper[Optional[DomainDeleteResponse]]._unwrapper, ), - cast_to=cast(Type[DomainDeleteResponse], ResultWrapper[DomainDeleteResponse]), - ) - - def bulk_delete( - self, - *, - account_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, - ) -> AsyncPaginator[DomainBulkDeleteResponse, AsyncSinglePage[DomainBulkDeleteResponse]]: - """ - Bulk removes multiple domains from email security configuration in a single - request. - - Args: - account_id: Account Identifier - - 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 account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return self._get_api_list( - path_template("/accounts/{account_id}/email-security/settings/domains", account_id=account_id), - page=AsyncSinglePage[DomainBulkDeleteResponse], - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - model=DomainBulkDeleteResponse, - method="delete", + cast_to=cast(Type[Optional[DomainDeleteResponse]], ResultWrapper[DomainDeleteResponse]), ) async def edit( self, - domain_id: int, + domain_id: str, *, account_id: str, - ip_restrictions: SequenceNotStr[str], allowed_delivery_modes: List[Literal["DIRECT", "BCC", "JOURNAL", "API", "RETRO_SCAN"]] | Omit = omit, domain: str | Omit = omit, drop_dispositions: List[ @@ -560,7 +510,8 @@ async def edit( ] | Omit = omit, folder: Literal["AllItems", "Inbox"] | Omit = omit, - integration_id: str | Omit = omit, + integration_id: Optional[str] | Omit = omit, + ip_restrictions: SequenceNotStr[str] | Omit = omit, lookback_hops: int | Omit = omit, regions: List[Literal["GLOBAL", "AU", "DE", "IN", "US"]] | Omit = omit, require_tls_inbound: bool | Omit = omit, @@ -572,14 +523,17 @@ async def edit( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> DomainEditResponse: - """ - Updates configuration for a domain in email security. + ) -> Optional[DomainEditResponse]: + """Updates configuration for a protected email domain. + + Only provided fields will be + modified. Changes affect delivery mode, security settings, and regional + processing. Args: - account_id: Account Identifier + account_id: Identifier. - domain_id: The unique identifier for the domain. + domain_id: Domain identifier extra_headers: Send extra headers @@ -591,6 +545,8 @@ async def edit( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not domain_id: + raise ValueError(f"Expected a non-empty value for `domain_id` but received {domain_id!r}") return await self._patch( path_template( "/accounts/{account_id}/email-security/settings/domains/{domain_id}", @@ -599,12 +555,12 @@ async def edit( ), body=await async_maybe_transform( { - "ip_restrictions": ip_restrictions, "allowed_delivery_modes": allowed_delivery_modes, "domain": domain, "drop_dispositions": drop_dispositions, "folder": folder, "integration_id": integration_id, + "ip_restrictions": ip_restrictions, "lookback_hops": lookback_hops, "regions": regions, "require_tls_inbound": require_tls_inbound, @@ -618,14 +574,14 @@ async def edit( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[DomainEditResponse]._unwrapper, + post_parser=ResultWrapper[Optional[DomainEditResponse]]._unwrapper, ), - cast_to=cast(Type[DomainEditResponse], ResultWrapper[DomainEditResponse]), + cast_to=cast(Type[Optional[DomainEditResponse]], ResultWrapper[DomainEditResponse]), ) async def get( self, - domain_id: int, + domain_id: str, *, account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -634,14 +590,15 @@ async def get( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> DomainGetResponse: + ) -> Optional[DomainGetResponse]: """ - Gets configuration details for a specific domain in email security. + Retrieves detailed information for a specific protected email domain including + its delivery configuration, SPF/DMARC status, and authorization state. Args: - account_id: Account Identifier + account_id: Identifier. - domain_id: The unique identifier for the domain. + domain_id: Domain identifier extra_headers: Send extra headers @@ -653,6 +610,8 @@ async def get( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not domain_id: + raise ValueError(f"Expected a non-empty value for `domain_id` but received {domain_id!r}") return await self._get( path_template( "/accounts/{account_id}/email-security/settings/domains/{domain_id}", @@ -664,9 +623,9 @@ async def get( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[DomainGetResponse]._unwrapper, + post_parser=ResultWrapper[Optional[DomainGetResponse]]._unwrapper, ), - cast_to=cast(Type[DomainGetResponse], ResultWrapper[DomainGetResponse]), + cast_to=cast(Type[Optional[DomainGetResponse]], ResultWrapper[DomainGetResponse]), ) @@ -680,9 +639,6 @@ def __init__(self, domains: DomainsResource) -> None: self.delete = to_raw_response_wrapper( domains.delete, ) - self.bulk_delete = to_raw_response_wrapper( - domains.bulk_delete, - ) self.edit = to_raw_response_wrapper( domains.edit, ) @@ -701,9 +657,6 @@ def __init__(self, domains: AsyncDomainsResource) -> None: self.delete = async_to_raw_response_wrapper( domains.delete, ) - self.bulk_delete = async_to_raw_response_wrapper( - domains.bulk_delete, - ) self.edit = async_to_raw_response_wrapper( domains.edit, ) @@ -722,9 +675,6 @@ def __init__(self, domains: DomainsResource) -> None: self.delete = to_streamed_response_wrapper( domains.delete, ) - self.bulk_delete = to_streamed_response_wrapper( - domains.bulk_delete, - ) self.edit = to_streamed_response_wrapper( domains.edit, ) @@ -743,9 +693,6 @@ def __init__(self, domains: AsyncDomainsResource) -> None: self.delete = async_to_streamed_response_wrapper( domains.delete, ) - self.bulk_delete = async_to_streamed_response_wrapper( - domains.bulk_delete, - ) self.edit = async_to_streamed_response_wrapper( domains.edit, ) diff --git a/src/cloudflare/resources/email_security/settings/impersonation_registry.py b/src/cloudflare/resources/email_security/settings/impersonation_registry.py index cc5a887645a..15d0da3afa2 100644 --- a/src/cloudflare/resources/email_security/settings/impersonation_registry.py +++ b/src/cloudflare/resources/email_security/settings/impersonation_registry.py @@ -61,18 +61,26 @@ def create( email: str, is_email_regex: bool, name: str, + comments: Optional[str] | Omit = omit, + directory_id: Optional[int] | Omit = omit, + directory_node_id: Optional[int] | Omit = omit, + external_directory_node_id: Optional[str] | Omit = omit, + provenance: Literal["A1S_INTERNAL", "SNOOPY-CASB_OFFICE_365", "SNOOPY-OFFICE_365", "SNOOPY-GOOGLE_DIRECTORY"] + | 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, - ) -> ImpersonationRegistryCreateResponse: + ) -> Optional[ImpersonationRegistryCreateResponse]: """ - Creates a display name entry for email security impersonation protection. + Creates a new entry in the impersonation registry to protect against + impersonation. Emails attempting to impersonate this identity will be flagged. + Supports regex patterns for flexible email matching. Args: - account_id: Account Identifier + account_id: Identifier. extra_headers: Send extra headers @@ -93,6 +101,11 @@ def create( "email": email, "is_email_regex": is_email_regex, "name": name, + "comments": comments, + "directory_id": directory_id, + "directory_node_id": directory_node_id, + "external_directory_node_id": external_directory_node_id, + "provenance": provenance, }, impersonation_registry_create_params.ImpersonationRegistryCreateParams, ), @@ -101,9 +114,11 @@ def create( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[ImpersonationRegistryCreateResponse]._unwrapper, + post_parser=ResultWrapper[Optional[ImpersonationRegistryCreateResponse]]._unwrapper, + ), + cast_to=cast( + Type[Optional[ImpersonationRegistryCreateResponse]], ResultWrapper[ImpersonationRegistryCreateResponse] ), - cast_to=cast(Type[ImpersonationRegistryCreateResponse], ResultWrapper[ImpersonationRegistryCreateResponse]), ) def list( @@ -125,22 +140,23 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncV4PagePaginationArray[ImpersonationRegistryListResponse]: """ - Lists, searches, and sorts entries in the impersonation registry. + Returns a paginated list of protected identities in the impersonation registry. + These entries define identities and email addresses to protect from + impersonation attacks. Can be manually added or automatically synced from + directory integrations. Args: - account_id: Account Identifier + account_id: Identifier. direction: The sorting direction. - order: The field to sort by. + order: Field to sort by. - page: The page number of paginated results. + page: Current page within paginated list of results. - per_page: The number of results per page. + per_page: The number of results per page. Maximum value is 1000. - search: Allows searching in multiple properties of a record simultaneously. This - parameter is intended for human users, not automation. Its exact behavior is - intentionally left unspecified and is subject to change in the future. + search: Search term for filtering records. Behavior may change. extra_headers: Send extra headers @@ -179,7 +195,7 @@ def list( def delete( self, - display_name_id: int, + impersonation_registry_id: str, *, account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -188,12 +204,16 @@ def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> ImpersonationRegistryDeleteResponse: - """ - Removes a display name from impersonation protection monitoring. + ) -> Optional[ImpersonationRegistryDeleteResponse]: + """Removes an entry from the impersonation registry. + + After deletion, this identity + will no longer be protected from impersonation. Args: - account_id: Account Identifier + account_id: Identifier. + + impersonation_registry_id: Impersonation registry entry identifier extra_headers: Send extra headers @@ -205,42 +225,58 @@ def delete( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not impersonation_registry_id: + raise ValueError( + f"Expected a non-empty value for `impersonation_registry_id` but received {impersonation_registry_id!r}" + ) return self._delete( path_template( - "/accounts/{account_id}/email-security/settings/impersonation_registry/{display_name_id}", + "/accounts/{account_id}/email-security/settings/impersonation_registry/{impersonation_registry_id}", account_id=account_id, - display_name_id=display_name_id, + impersonation_registry_id=impersonation_registry_id, ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[ImpersonationRegistryDeleteResponse]._unwrapper, + post_parser=ResultWrapper[Optional[ImpersonationRegistryDeleteResponse]]._unwrapper, + ), + cast_to=cast( + Type[Optional[ImpersonationRegistryDeleteResponse]], ResultWrapper[ImpersonationRegistryDeleteResponse] ), - cast_to=cast(Type[ImpersonationRegistryDeleteResponse], ResultWrapper[ImpersonationRegistryDeleteResponse]), ) def edit( self, - display_name_id: int, + impersonation_registry_id: str, *, account_id: str, - email: Optional[str] | Omit = omit, - is_email_regex: Optional[bool] | Omit = omit, - name: Optional[str] | Omit = omit, + comments: Optional[str] | Omit = omit, + directory_id: Optional[int] | Omit = omit, + directory_node_id: Optional[int] | Omit = omit, + email: str | Omit = omit, + external_directory_node_id: Optional[str] | Omit = omit, + is_email_regex: bool | Omit = omit, + name: str | Omit = omit, + provenance: Literal["A1S_INTERNAL", "SNOOPY-CASB_OFFICE_365", "SNOOPY-OFFICE_365", "SNOOPY-GOOGLE_DIRECTORY"] + | 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, - ) -> ImpersonationRegistryEditResponse: - """ - Updates a display name entry used for impersonation protection. + ) -> Optional[ImpersonationRegistryEditResponse]: + """Updates an existing impersonation registry entry. + + Only provided fields will be + modified. Directory-synced entries can't be updated. Args: - account_id: Account Identifier + account_id: Identifier. + + impersonation_registry_id: Impersonation registry entry identifier extra_headers: Send extra headers @@ -252,17 +288,26 @@ def edit( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not impersonation_registry_id: + raise ValueError( + f"Expected a non-empty value for `impersonation_registry_id` but received {impersonation_registry_id!r}" + ) return self._patch( path_template( - "/accounts/{account_id}/email-security/settings/impersonation_registry/{display_name_id}", + "/accounts/{account_id}/email-security/settings/impersonation_registry/{impersonation_registry_id}", account_id=account_id, - display_name_id=display_name_id, + impersonation_registry_id=impersonation_registry_id, ), body=maybe_transform( { + "comments": comments, + "directory_id": directory_id, + "directory_node_id": directory_node_id, "email": email, + "external_directory_node_id": external_directory_node_id, "is_email_regex": is_email_regex, "name": name, + "provenance": provenance, }, impersonation_registry_edit_params.ImpersonationRegistryEditParams, ), @@ -271,14 +316,16 @@ def edit( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[ImpersonationRegistryEditResponse]._unwrapper, + post_parser=ResultWrapper[Optional[ImpersonationRegistryEditResponse]]._unwrapper, + ), + cast_to=cast( + Type[Optional[ImpersonationRegistryEditResponse]], ResultWrapper[ImpersonationRegistryEditResponse] ), - cast_to=cast(Type[ImpersonationRegistryEditResponse], ResultWrapper[ImpersonationRegistryEditResponse]), ) def get( self, - display_name_id: int, + impersonation_registry_id: str, *, account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -287,12 +334,16 @@ def get( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> ImpersonationRegistryGetResponse: + ) -> Optional[ImpersonationRegistryGetResponse]: """ - Retrieves a display name entry used for impersonation protection. + Retrieves details for a specific impersonation registry entry including the + protected identity, email pattern, and synchronization source if + directory-synced. Args: - account_id: Account Identifier + account_id: Identifier. + + impersonation_registry_id: Impersonation registry entry identifier extra_headers: Send extra headers @@ -304,20 +355,26 @@ def get( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not impersonation_registry_id: + raise ValueError( + f"Expected a non-empty value for `impersonation_registry_id` but received {impersonation_registry_id!r}" + ) return self._get( path_template( - "/accounts/{account_id}/email-security/settings/impersonation_registry/{display_name_id}", + "/accounts/{account_id}/email-security/settings/impersonation_registry/{impersonation_registry_id}", account_id=account_id, - display_name_id=display_name_id, + impersonation_registry_id=impersonation_registry_id, ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[ImpersonationRegistryGetResponse]._unwrapper, + post_parser=ResultWrapper[Optional[ImpersonationRegistryGetResponse]]._unwrapper, + ), + cast_to=cast( + Type[Optional[ImpersonationRegistryGetResponse]], ResultWrapper[ImpersonationRegistryGetResponse] ), - cast_to=cast(Type[ImpersonationRegistryGetResponse], ResultWrapper[ImpersonationRegistryGetResponse]), ) @@ -348,18 +405,26 @@ async def create( email: str, is_email_regex: bool, name: str, + comments: Optional[str] | Omit = omit, + directory_id: Optional[int] | Omit = omit, + directory_node_id: Optional[int] | Omit = omit, + external_directory_node_id: Optional[str] | Omit = omit, + provenance: Literal["A1S_INTERNAL", "SNOOPY-CASB_OFFICE_365", "SNOOPY-OFFICE_365", "SNOOPY-GOOGLE_DIRECTORY"] + | 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, - ) -> ImpersonationRegistryCreateResponse: + ) -> Optional[ImpersonationRegistryCreateResponse]: """ - Creates a display name entry for email security impersonation protection. + Creates a new entry in the impersonation registry to protect against + impersonation. Emails attempting to impersonate this identity will be flagged. + Supports regex patterns for flexible email matching. Args: - account_id: Account Identifier + account_id: Identifier. extra_headers: Send extra headers @@ -380,6 +445,11 @@ async def create( "email": email, "is_email_regex": is_email_regex, "name": name, + "comments": comments, + "directory_id": directory_id, + "directory_node_id": directory_node_id, + "external_directory_node_id": external_directory_node_id, + "provenance": provenance, }, impersonation_registry_create_params.ImpersonationRegistryCreateParams, ), @@ -388,9 +458,11 @@ async def create( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[ImpersonationRegistryCreateResponse]._unwrapper, + post_parser=ResultWrapper[Optional[ImpersonationRegistryCreateResponse]]._unwrapper, + ), + cast_to=cast( + Type[Optional[ImpersonationRegistryCreateResponse]], ResultWrapper[ImpersonationRegistryCreateResponse] ), - cast_to=cast(Type[ImpersonationRegistryCreateResponse], ResultWrapper[ImpersonationRegistryCreateResponse]), ) def list( @@ -414,22 +486,23 @@ def list( ImpersonationRegistryListResponse, AsyncV4PagePaginationArray[ImpersonationRegistryListResponse] ]: """ - Lists, searches, and sorts entries in the impersonation registry. + Returns a paginated list of protected identities in the impersonation registry. + These entries define identities and email addresses to protect from + impersonation attacks. Can be manually added or automatically synced from + directory integrations. Args: - account_id: Account Identifier + account_id: Identifier. direction: The sorting direction. - order: The field to sort by. + order: Field to sort by. - page: The page number of paginated results. + page: Current page within paginated list of results. - per_page: The number of results per page. + per_page: The number of results per page. Maximum value is 1000. - search: Allows searching in multiple properties of a record simultaneously. This - parameter is intended for human users, not automation. Its exact behavior is - intentionally left unspecified and is subject to change in the future. + search: Search term for filtering records. Behavior may change. extra_headers: Send extra headers @@ -468,7 +541,7 @@ def list( async def delete( self, - display_name_id: int, + impersonation_registry_id: str, *, account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -477,12 +550,16 @@ async def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> ImpersonationRegistryDeleteResponse: - """ - Removes a display name from impersonation protection monitoring. + ) -> Optional[ImpersonationRegistryDeleteResponse]: + """Removes an entry from the impersonation registry. + + After deletion, this identity + will no longer be protected from impersonation. Args: - account_id: Account Identifier + account_id: Identifier. + + impersonation_registry_id: Impersonation registry entry identifier extra_headers: Send extra headers @@ -494,42 +571,58 @@ async def delete( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not impersonation_registry_id: + raise ValueError( + f"Expected a non-empty value for `impersonation_registry_id` but received {impersonation_registry_id!r}" + ) return await self._delete( path_template( - "/accounts/{account_id}/email-security/settings/impersonation_registry/{display_name_id}", + "/accounts/{account_id}/email-security/settings/impersonation_registry/{impersonation_registry_id}", account_id=account_id, - display_name_id=display_name_id, + impersonation_registry_id=impersonation_registry_id, ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[ImpersonationRegistryDeleteResponse]._unwrapper, + post_parser=ResultWrapper[Optional[ImpersonationRegistryDeleteResponse]]._unwrapper, + ), + cast_to=cast( + Type[Optional[ImpersonationRegistryDeleteResponse]], ResultWrapper[ImpersonationRegistryDeleteResponse] ), - cast_to=cast(Type[ImpersonationRegistryDeleteResponse], ResultWrapper[ImpersonationRegistryDeleteResponse]), ) async def edit( self, - display_name_id: int, + impersonation_registry_id: str, *, account_id: str, - email: Optional[str] | Omit = omit, - is_email_regex: Optional[bool] | Omit = omit, - name: Optional[str] | Omit = omit, + comments: Optional[str] | Omit = omit, + directory_id: Optional[int] | Omit = omit, + directory_node_id: Optional[int] | Omit = omit, + email: str | Omit = omit, + external_directory_node_id: Optional[str] | Omit = omit, + is_email_regex: bool | Omit = omit, + name: str | Omit = omit, + provenance: Literal["A1S_INTERNAL", "SNOOPY-CASB_OFFICE_365", "SNOOPY-OFFICE_365", "SNOOPY-GOOGLE_DIRECTORY"] + | 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, - ) -> ImpersonationRegistryEditResponse: - """ - Updates a display name entry used for impersonation protection. + ) -> Optional[ImpersonationRegistryEditResponse]: + """Updates an existing impersonation registry entry. + + Only provided fields will be + modified. Directory-synced entries can't be updated. Args: - account_id: Account Identifier + account_id: Identifier. + + impersonation_registry_id: Impersonation registry entry identifier extra_headers: Send extra headers @@ -541,17 +634,26 @@ async def edit( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not impersonation_registry_id: + raise ValueError( + f"Expected a non-empty value for `impersonation_registry_id` but received {impersonation_registry_id!r}" + ) return await self._patch( path_template( - "/accounts/{account_id}/email-security/settings/impersonation_registry/{display_name_id}", + "/accounts/{account_id}/email-security/settings/impersonation_registry/{impersonation_registry_id}", account_id=account_id, - display_name_id=display_name_id, + impersonation_registry_id=impersonation_registry_id, ), body=await async_maybe_transform( { + "comments": comments, + "directory_id": directory_id, + "directory_node_id": directory_node_id, "email": email, + "external_directory_node_id": external_directory_node_id, "is_email_regex": is_email_regex, "name": name, + "provenance": provenance, }, impersonation_registry_edit_params.ImpersonationRegistryEditParams, ), @@ -560,14 +662,16 @@ async def edit( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[ImpersonationRegistryEditResponse]._unwrapper, + post_parser=ResultWrapper[Optional[ImpersonationRegistryEditResponse]]._unwrapper, + ), + cast_to=cast( + Type[Optional[ImpersonationRegistryEditResponse]], ResultWrapper[ImpersonationRegistryEditResponse] ), - cast_to=cast(Type[ImpersonationRegistryEditResponse], ResultWrapper[ImpersonationRegistryEditResponse]), ) async def get( self, - display_name_id: int, + impersonation_registry_id: str, *, account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -576,12 +680,16 @@ async def get( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> ImpersonationRegistryGetResponse: + ) -> Optional[ImpersonationRegistryGetResponse]: """ - Retrieves a display name entry used for impersonation protection. + Retrieves details for a specific impersonation registry entry including the + protected identity, email pattern, and synchronization source if + directory-synced. Args: - account_id: Account Identifier + account_id: Identifier. + + impersonation_registry_id: Impersonation registry entry identifier extra_headers: Send extra headers @@ -593,20 +701,26 @@ async def get( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not impersonation_registry_id: + raise ValueError( + f"Expected a non-empty value for `impersonation_registry_id` but received {impersonation_registry_id!r}" + ) return await self._get( path_template( - "/accounts/{account_id}/email-security/settings/impersonation_registry/{display_name_id}", + "/accounts/{account_id}/email-security/settings/impersonation_registry/{impersonation_registry_id}", account_id=account_id, - display_name_id=display_name_id, + impersonation_registry_id=impersonation_registry_id, ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[ImpersonationRegistryGetResponse]._unwrapper, + post_parser=ResultWrapper[Optional[ImpersonationRegistryGetResponse]]._unwrapper, + ), + cast_to=cast( + Type[Optional[ImpersonationRegistryGetResponse]], ResultWrapper[ImpersonationRegistryGetResponse] ), - cast_to=cast(Type[ImpersonationRegistryGetResponse], ResultWrapper[ImpersonationRegistryGetResponse]), ) diff --git a/src/cloudflare/resources/email_security/settings/trusted_domains.py b/src/cloudflare/resources/email_security/settings/trusted_domains.py index 2bc4c7a45d2..3f5c4b27cef 100644 --- a/src/cloudflare/resources/email_security/settings/trusted_domains.py +++ b/src/cloudflare/resources/email_security/settings/trusted_domains.py @@ -2,13 +2,13 @@ from __future__ import annotations -from typing import Any, Type, Iterable, Optional, cast -from typing_extensions import Literal, overload +from typing import Type, Optional, cast +from typing_extensions import Literal import httpx from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ...._utils import path_template, required_args, maybe_transform, async_maybe_transform +from ...._utils import path_template, maybe_transform, async_maybe_transform from ...._compat import cached_property from ...._resource import SyncAPIResource, AsyncAPIResource from ...._response import ( @@ -54,7 +54,6 @@ def with_streaming_response(self) -> TrustedDomainsResourceWithStreamingResponse """ return TrustedDomainsResourceWithStreamingResponse(self) - @overload def create( self, *, @@ -70,13 +69,15 @@ def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> TrustedDomainCreateResponse: - """ - Adds a domain to the trusted domains list for email security, reducing false - positive detections. + ) -> Optional[TrustedDomainCreateResponse]: + """Creates a new trusted domain pattern. + + Use for partner domains or approved + senders that should bypass recent domain registration and similarity checks. + Configure whether it prevents recent domain or spoof dispositions. Args: - account_id: Account Identifier + account_id: Identifier. is_recent: Select to prevent recently registered domains from triggering a Suspicious or Malicious disposition. @@ -92,84 +93,28 @@ def create( timeout: Override the client-level default timeout for this request, in seconds """ - ... - - @overload - def create( - self, - *, - account_id: str, - body: Iterable[trusted_domain_create_params.Variant1Body], - # 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, - ) -> TrustedDomainCreateResponse: - """ - Adds a domain to the trusted domains list for email security, reducing false - positive detections. - - Args: - account_id: Account Identifier - - 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(["account_id", "is_recent", "is_regex", "is_similarity", "pattern"], ["account_id", "body"]) - def create( - self, - *, - account_id: str, - is_recent: bool | Omit = omit, - is_regex: bool | Omit = omit, - is_similarity: bool | Omit = omit, - pattern: str | Omit = omit, - comments: Optional[str] | Omit = omit, - body: Iterable[trusted_domain_create_params.Variant1Body] | 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, - ) -> TrustedDomainCreateResponse: if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return cast( - TrustedDomainCreateResponse, - self._post( - path_template("/accounts/{account_id}/email-security/settings/trusted_domains", account_id=account_id), - body=maybe_transform( - { - "is_recent": is_recent, - "is_regex": is_regex, - "is_similarity": is_similarity, - "pattern": pattern, - "comments": comments, - "body": body, - }, - trusted_domain_create_params.TrustedDomainCreateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[TrustedDomainCreateResponse]._unwrapper, - ), - cast_to=cast( - Any, ResultWrapper[TrustedDomainCreateResponse] - ), # Union types cannot be passed in as arguments in the type system + return self._post( + path_template("/accounts/{account_id}/email-security/settings/trusted_domains", account_id=account_id), + body=maybe_transform( + { + "is_recent": is_recent, + "is_regex": is_regex, + "is_similarity": is_similarity, + "pattern": pattern, + "comments": comments, + }, + trusted_domain_create_params.TrustedDomainCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[TrustedDomainCreateResponse]]._unwrapper, ), + cast_to=cast(Type[Optional[TrustedDomainCreateResponse]], ResultWrapper[TrustedDomainCreateResponse]), ) def list( @@ -191,23 +136,30 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncV4PagePaginationArray[TrustedDomainListResponse]: - """ - Lists, searches, and sorts an account’s trusted email domains. + """Returns a paginated list of trusted domain patterns. + + Trusted domains prevent + false positives for recently registered domains and lookalike domain detections. + Patterns can use regular expressions for flexible matching. Args: - account_id: Account Identifier + account_id: Identifier. direction: The sorting direction. - order: The field to sort by. + is_recent: Filter to show only recently registered domains that are trusted to prevent + triggering Suspicious or Malicious dispositions. + + is_similarity: Filter to show only proximity domains (partner or approved domains with similar + spelling to connected domains) that prevent Spoof dispositions. - page: The page number of paginated results. + order: Field to sort by. - per_page: The number of results per page. + page: Current page within paginated list of results. - search: Allows searching in multiple properties of a record simultaneously. This - parameter is intended for human users, not automation. Its exact behavior is - intentionally left unspecified and is subject to change in the future. + per_page: The number of results per page. Maximum value is 1000. + + search: Search term for filtering records. Behavior may change. extra_headers: Send extra headers @@ -246,7 +198,7 @@ def list( def delete( self, - trusted_domain_id: int, + trusted_domain_id: str, *, account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -255,15 +207,16 @@ def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> TrustedDomainDeleteResponse: - """ - Removes a domain from the trusted domains list, subjecting it to normal security - scanning. + ) -> Optional[TrustedDomainDeleteResponse]: + """Removes a trusted domain pattern. + + After deletion, emails from this domain will + be subject to normal recent domain and similarity checks. Args: - account_id: Account Identifier + account_id: Identifier. - trusted_domain_id: The unique identifier for the trusted domain. + trusted_domain_id: Trusted domain identifier extra_headers: Send extra headers @@ -275,6 +228,8 @@ def delete( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not trusted_domain_id: + raise ValueError(f"Expected a non-empty value for `trusted_domain_id` but received {trusted_domain_id!r}") return self._delete( path_template( "/accounts/{account_id}/email-security/settings/trusted_domains/{trusted_domain_id}", @@ -286,17 +241,17 @@ def delete( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[TrustedDomainDeleteResponse]._unwrapper, + post_parser=ResultWrapper[Optional[TrustedDomainDeleteResponse]]._unwrapper, ), - cast_to=cast(Type[TrustedDomainDeleteResponse], ResultWrapper[TrustedDomainDeleteResponse]), + cast_to=cast(Type[Optional[TrustedDomainDeleteResponse]], ResultWrapper[TrustedDomainDeleteResponse]), ) def edit( self, - trusted_domain_id: int, + trusted_domain_id: str, *, account_id: str, - comments: str | Omit = omit, + comments: Optional[str] | Omit = omit, is_recent: bool | Omit = omit, is_regex: bool | Omit = omit, is_similarity: bool | Omit = omit, @@ -307,14 +262,16 @@ def edit( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> TrustedDomainEditResponse: - """ - Modifies a trusted domain entry's configuration. + ) -> Optional[TrustedDomainEditResponse]: + """Updates an existing trusted domain pattern. + + Only provided fields will be + modified. Changes take effect for new emails matching the pattern. Args: - account_id: Account Identifier + account_id: Identifier. - trusted_domain_id: The unique identifier for the trusted domain. + trusted_domain_id: Trusted domain identifier is_recent: Select to prevent recently registered domains from triggering a Suspicious or Malicious disposition. @@ -332,6 +289,8 @@ def edit( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not trusted_domain_id: + raise ValueError(f"Expected a non-empty value for `trusted_domain_id` but received {trusted_domain_id!r}") return self._patch( path_template( "/accounts/{account_id}/email-security/settings/trusted_domains/{trusted_domain_id}", @@ -353,14 +312,14 @@ def edit( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[TrustedDomainEditResponse]._unwrapper, + post_parser=ResultWrapper[Optional[TrustedDomainEditResponse]]._unwrapper, ), - cast_to=cast(Type[TrustedDomainEditResponse], ResultWrapper[TrustedDomainEditResponse]), + cast_to=cast(Type[Optional[TrustedDomainEditResponse]], ResultWrapper[TrustedDomainEditResponse]), ) def get( self, - trusted_domain_id: int, + trusted_domain_id: str, *, account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -369,14 +328,15 @@ def get( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> TrustedDomainGetResponse: + ) -> Optional[TrustedDomainGetResponse]: """ - Gets information about a specific trusted domain entry. + Retrieves details for a specific trusted domain pattern including its pattern + value, whether it uses regex matching, and which detection types it affects. Args: - account_id: Account Identifier + account_id: Identifier. - trusted_domain_id: The unique identifier for the trusted domain. + trusted_domain_id: Trusted domain identifier extra_headers: Send extra headers @@ -388,6 +348,8 @@ def get( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not trusted_domain_id: + raise ValueError(f"Expected a non-empty value for `trusted_domain_id` but received {trusted_domain_id!r}") return self._get( path_template( "/accounts/{account_id}/email-security/settings/trusted_domains/{trusted_domain_id}", @@ -399,9 +361,9 @@ def get( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[TrustedDomainGetResponse]._unwrapper, + post_parser=ResultWrapper[Optional[TrustedDomainGetResponse]]._unwrapper, ), - cast_to=cast(Type[TrustedDomainGetResponse], ResultWrapper[TrustedDomainGetResponse]), + cast_to=cast(Type[Optional[TrustedDomainGetResponse]], ResultWrapper[TrustedDomainGetResponse]), ) @@ -425,7 +387,6 @@ def with_streaming_response(self) -> AsyncTrustedDomainsResourceWithStreamingRes """ return AsyncTrustedDomainsResourceWithStreamingResponse(self) - @overload async def create( self, *, @@ -441,13 +402,15 @@ async def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> TrustedDomainCreateResponse: - """ - Adds a domain to the trusted domains list for email security, reducing false - positive detections. + ) -> Optional[TrustedDomainCreateResponse]: + """Creates a new trusted domain pattern. + + Use for partner domains or approved + senders that should bypass recent domain registration and similarity checks. + Configure whether it prevents recent domain or spoof dispositions. Args: - account_id: Account Identifier + account_id: Identifier. is_recent: Select to prevent recently registered domains from triggering a Suspicious or Malicious disposition. @@ -463,84 +426,28 @@ async def create( timeout: Override the client-level default timeout for this request, in seconds """ - ... - - @overload - async def create( - self, - *, - account_id: str, - body: Iterable[trusted_domain_create_params.Variant1Body], - # 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, - ) -> TrustedDomainCreateResponse: - """ - Adds a domain to the trusted domains list for email security, reducing false - positive detections. - - Args: - account_id: Account Identifier - - 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(["account_id", "is_recent", "is_regex", "is_similarity", "pattern"], ["account_id", "body"]) - async def create( - self, - *, - account_id: str, - is_recent: bool | Omit = omit, - is_regex: bool | Omit = omit, - is_similarity: bool | Omit = omit, - pattern: str | Omit = omit, - comments: Optional[str] | Omit = omit, - body: Iterable[trusted_domain_create_params.Variant1Body] | 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, - ) -> TrustedDomainCreateResponse: if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return cast( - TrustedDomainCreateResponse, - await self._post( - path_template("/accounts/{account_id}/email-security/settings/trusted_domains", account_id=account_id), - body=await async_maybe_transform( - { - "is_recent": is_recent, - "is_regex": is_regex, - "is_similarity": is_similarity, - "pattern": pattern, - "comments": comments, - "body": body, - }, - trusted_domain_create_params.TrustedDomainCreateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[TrustedDomainCreateResponse]._unwrapper, - ), - cast_to=cast( - Any, ResultWrapper[TrustedDomainCreateResponse] - ), # Union types cannot be passed in as arguments in the type system + return await self._post( + path_template("/accounts/{account_id}/email-security/settings/trusted_domains", account_id=account_id), + body=await async_maybe_transform( + { + "is_recent": is_recent, + "is_regex": is_regex, + "is_similarity": is_similarity, + "pattern": pattern, + "comments": comments, + }, + trusted_domain_create_params.TrustedDomainCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[TrustedDomainCreateResponse]]._unwrapper, ), + cast_to=cast(Type[Optional[TrustedDomainCreateResponse]], ResultWrapper[TrustedDomainCreateResponse]), ) def list( @@ -562,23 +469,30 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[TrustedDomainListResponse, AsyncV4PagePaginationArray[TrustedDomainListResponse]]: - """ - Lists, searches, and sorts an account’s trusted email domains. + """Returns a paginated list of trusted domain patterns. + + Trusted domains prevent + false positives for recently registered domains and lookalike domain detections. + Patterns can use regular expressions for flexible matching. Args: - account_id: Account Identifier + account_id: Identifier. direction: The sorting direction. - order: The field to sort by. + is_recent: Filter to show only recently registered domains that are trusted to prevent + triggering Suspicious or Malicious dispositions. + + is_similarity: Filter to show only proximity domains (partner or approved domains with similar + spelling to connected domains) that prevent Spoof dispositions. - page: The page number of paginated results. + order: Field to sort by. - per_page: The number of results per page. + page: Current page within paginated list of results. - search: Allows searching in multiple properties of a record simultaneously. This - parameter is intended for human users, not automation. Its exact behavior is - intentionally left unspecified and is subject to change in the future. + per_page: The number of results per page. Maximum value is 1000. + + search: Search term for filtering records. Behavior may change. extra_headers: Send extra headers @@ -617,7 +531,7 @@ def list( async def delete( self, - trusted_domain_id: int, + trusted_domain_id: str, *, account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -626,15 +540,16 @@ async def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> TrustedDomainDeleteResponse: - """ - Removes a domain from the trusted domains list, subjecting it to normal security - scanning. + ) -> Optional[TrustedDomainDeleteResponse]: + """Removes a trusted domain pattern. + + After deletion, emails from this domain will + be subject to normal recent domain and similarity checks. Args: - account_id: Account Identifier + account_id: Identifier. - trusted_domain_id: The unique identifier for the trusted domain. + trusted_domain_id: Trusted domain identifier extra_headers: Send extra headers @@ -646,6 +561,8 @@ async def delete( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not trusted_domain_id: + raise ValueError(f"Expected a non-empty value for `trusted_domain_id` but received {trusted_domain_id!r}") return await self._delete( path_template( "/accounts/{account_id}/email-security/settings/trusted_domains/{trusted_domain_id}", @@ -657,17 +574,17 @@ async def delete( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[TrustedDomainDeleteResponse]._unwrapper, + post_parser=ResultWrapper[Optional[TrustedDomainDeleteResponse]]._unwrapper, ), - cast_to=cast(Type[TrustedDomainDeleteResponse], ResultWrapper[TrustedDomainDeleteResponse]), + cast_to=cast(Type[Optional[TrustedDomainDeleteResponse]], ResultWrapper[TrustedDomainDeleteResponse]), ) async def edit( self, - trusted_domain_id: int, + trusted_domain_id: str, *, account_id: str, - comments: str | Omit = omit, + comments: Optional[str] | Omit = omit, is_recent: bool | Omit = omit, is_regex: bool | Omit = omit, is_similarity: bool | Omit = omit, @@ -678,14 +595,16 @@ async def edit( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> TrustedDomainEditResponse: - """ - Modifies a trusted domain entry's configuration. + ) -> Optional[TrustedDomainEditResponse]: + """Updates an existing trusted domain pattern. + + Only provided fields will be + modified. Changes take effect for new emails matching the pattern. Args: - account_id: Account Identifier + account_id: Identifier. - trusted_domain_id: The unique identifier for the trusted domain. + trusted_domain_id: Trusted domain identifier is_recent: Select to prevent recently registered domains from triggering a Suspicious or Malicious disposition. @@ -703,6 +622,8 @@ async def edit( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not trusted_domain_id: + raise ValueError(f"Expected a non-empty value for `trusted_domain_id` but received {trusted_domain_id!r}") return await self._patch( path_template( "/accounts/{account_id}/email-security/settings/trusted_domains/{trusted_domain_id}", @@ -724,14 +645,14 @@ async def edit( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[TrustedDomainEditResponse]._unwrapper, + post_parser=ResultWrapper[Optional[TrustedDomainEditResponse]]._unwrapper, ), - cast_to=cast(Type[TrustedDomainEditResponse], ResultWrapper[TrustedDomainEditResponse]), + cast_to=cast(Type[Optional[TrustedDomainEditResponse]], ResultWrapper[TrustedDomainEditResponse]), ) async def get( self, - trusted_domain_id: int, + trusted_domain_id: str, *, account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -740,14 +661,15 @@ async def get( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> TrustedDomainGetResponse: + ) -> Optional[TrustedDomainGetResponse]: """ - Gets information about a specific trusted domain entry. + Retrieves details for a specific trusted domain pattern including its pattern + value, whether it uses regex matching, and which detection types it affects. Args: - account_id: Account Identifier + account_id: Identifier. - trusted_domain_id: The unique identifier for the trusted domain. + trusted_domain_id: Trusted domain identifier extra_headers: Send extra headers @@ -759,6 +681,8 @@ async def get( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not trusted_domain_id: + raise ValueError(f"Expected a non-empty value for `trusted_domain_id` but received {trusted_domain_id!r}") return await self._get( path_template( "/accounts/{account_id}/email-security/settings/trusted_domains/{trusted_domain_id}", @@ -770,9 +694,9 @@ async def get( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[TrustedDomainGetResponse]._unwrapper, + post_parser=ResultWrapper[Optional[TrustedDomainGetResponse]]._unwrapper, ), - cast_to=cast(Type[TrustedDomainGetResponse], ResultWrapper[TrustedDomainGetResponse]), + cast_to=cast(Type[Optional[TrustedDomainGetResponse]], ResultWrapper[TrustedDomainGetResponse]), ) diff --git a/src/cloudflare/resources/email_security/submissions.py b/src/cloudflare/resources/email_security/submissions.py index a35b261041e..be830a3f4e9 100644 --- a/src/cloudflare/resources/email_security/submissions.py +++ b/src/cloudflare/resources/email_security/submissions.py @@ -50,7 +50,6 @@ def list( self, *, account_id: str, - customer_status: Literal["escalated", "reviewed", "unreviewed"] | Omit = omit, end: Union[str, datetime] | Omit = omit, original_disposition: Literal["MALICIOUS", "SUSPICIOUS", "SPOOF", "SPAM", "BULK", "NONE"] | Omit = omit, outcome_disposition: Literal["MALICIOUS", "SUSPICIOUS", "SPOOF", "SPAM", "BULK", "NONE"] | Omit = omit, @@ -69,20 +68,22 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncV4PagePaginationArray[SubmissionListResponse]: - """ - This endpoint returns information for submissions to made to reclassify emails. + """Returns information for submissions made to reclassify emails. + + Shows the status, + outcome, and disposition changes for reclassification requests made by users or + the security team. Useful for tracking false positive/negative reports. Args: - account_id: Account Identifier + account_id: Identifier. - end: The end of the search date range. Defaults to `now` if not provided. + end: The end of the search date range. Defaults to `now`. - page: The page number of paginated results. + page: Current page within paginated list of results. - per_page: The number of results per page. + per_page: The number of results per page. Maximum value is 1000. - start: The beginning of the search date range. Defaults to `now - 30 days` if not - provided. + start: The beginning of the search date range. Defaults to `now - 30 days`. extra_headers: Send extra headers @@ -104,7 +105,6 @@ def list( timeout=timeout, query=maybe_transform( { - "customer_status": customer_status, "end": end, "original_disposition": original_disposition, "outcome_disposition": outcome_disposition, @@ -148,7 +148,6 @@ def list( self, *, account_id: str, - customer_status: Literal["escalated", "reviewed", "unreviewed"] | Omit = omit, end: Union[str, datetime] | Omit = omit, original_disposition: Literal["MALICIOUS", "SUSPICIOUS", "SPOOF", "SPAM", "BULK", "NONE"] | Omit = omit, outcome_disposition: Literal["MALICIOUS", "SUSPICIOUS", "SPOOF", "SPAM", "BULK", "NONE"] | Omit = omit, @@ -167,20 +166,22 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[SubmissionListResponse, AsyncV4PagePaginationArray[SubmissionListResponse]]: - """ - This endpoint returns information for submissions to made to reclassify emails. + """Returns information for submissions made to reclassify emails. + + Shows the status, + outcome, and disposition changes for reclassification requests made by users or + the security team. Useful for tracking false positive/negative reports. Args: - account_id: Account Identifier + account_id: Identifier. - end: The end of the search date range. Defaults to `now` if not provided. + end: The end of the search date range. Defaults to `now`. - page: The page number of paginated results. + page: Current page within paginated list of results. - per_page: The number of results per page. + per_page: The number of results per page. Maximum value is 1000. - start: The beginning of the search date range. Defaults to `now - 30 days` if not - provided. + start: The beginning of the search date range. Defaults to `now - 30 days`. extra_headers: Send extra headers @@ -202,7 +203,6 @@ def list( timeout=timeout, query=maybe_transform( { - "customer_status": customer_status, "end": end, "original_disposition": original_disposition, "outcome_disposition": outcome_disposition, diff --git a/src/cloudflare/resources/fraud/fraud.py b/src/cloudflare/resources/fraud/fraud.py index bdb431f9bc3..81e5efe5796 100644 --- a/src/cloudflare/resources/fraud/fraud.py +++ b/src/cloudflare/resources/fraud/fraud.py @@ -49,6 +49,7 @@ def update( self, *, zone_id: str, + authentication_settings: fraud_update_params.AuthenticationSettings | Omit = omit, user_profiles: Literal["enabled", "disabled"] | Omit = omit, username_expressions: SequenceNotStr[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -69,6 +70,14 @@ def update( Args: zone_id: Identifier. + authentication_settings: Configuration for classifying login authentication outcomes based on the origin + response. Requires `user_profiles` to be enabled. + + - Success and failure criteria are independently updatable — sending only + `success_criteria` leaves failure codes untouched, and vice versa. + - Omit `authentication_settings` entirely to leave both unchanged. + - Status codes must not overlap between success and failure criteria. + user_profiles: Whether Fraud User Profiles is enabled for the zone. username_expressions: List of expressions to detect usernames in write HTTP requests. @@ -93,6 +102,7 @@ def update( path_template("/zones/{zone_id}/fraud_detection/settings", zone_id=zone_id), body=maybe_transform( { + "authentication_settings": authentication_settings, "user_profiles": user_profiles, "username_expressions": username_expressions, }, @@ -172,6 +182,7 @@ async def update( self, *, zone_id: str, + authentication_settings: fraud_update_params.AuthenticationSettings | Omit = omit, user_profiles: Literal["enabled", "disabled"] | Omit = omit, username_expressions: SequenceNotStr[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -192,6 +203,14 @@ async def update( Args: zone_id: Identifier. + authentication_settings: Configuration for classifying login authentication outcomes based on the origin + response. Requires `user_profiles` to be enabled. + + - Success and failure criteria are independently updatable — sending only + `success_criteria` leaves failure codes untouched, and vice versa. + - Omit `authentication_settings` entirely to leave both unchanged. + - Status codes must not overlap between success and failure criteria. + user_profiles: Whether Fraud User Profiles is enabled for the zone. username_expressions: List of expressions to detect usernames in write HTTP requests. @@ -216,6 +235,7 @@ async def update( path_template("/zones/{zone_id}/fraud_detection/settings", zone_id=zone_id), body=await async_maybe_transform( { + "authentication_settings": authentication_settings, "user_profiles": user_profiles, "username_expressions": username_expressions, }, diff --git a/src/cloudflare/resources/magic_transit/api.md b/src/cloudflare/resources/magic_transit/api.md index a7477a25fa8..2d200bccc35 100644 --- a/src/cloudflare/resources/magic_transit/api.md +++ b/src/cloudflare/resources/magic_transit/api.md @@ -220,7 +220,7 @@ Methods: - client.magic_transit.connectors.create(\*, account_id, \*\*params) -> ConnectorCreateResponse - client.magic_transit.connectors.update(connector_id, \*, account_id, \*\*params) -> ConnectorUpdateResponse -- client.magic_transit.connectors.list(\*, account_id) -> SyncSinglePage[ConnectorListResponse] +- client.magic_transit.connectors.list(\*, account_id, \*\*params) -> SyncSinglePage[ConnectorListResponse] - client.magic_transit.connectors.delete(connector_id, \*, account_id) -> ConnectorDeleteResponse - client.magic_transit.connectors.edit(connector_id, \*, account_id, \*\*params) -> ConnectorEditResponse - client.magic_transit.connectors.get(connector_id, \*, account_id) -> ConnectorGetResponse diff --git a/src/cloudflare/resources/magic_transit/cf_interconnects.py b/src/cloudflare/resources/magic_transit/cf_interconnects.py index f2e3ef1890e..6a127aa7698 100644 --- a/src/cloudflare/resources/magic_transit/cf_interconnects.py +++ b/src/cloudflare/resources/magic_transit/cf_interconnects.py @@ -81,7 +81,8 @@ def update( cf_interconnect_id: Identifier automatic_return_routing: True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. description: An optional description of the interconnect. @@ -370,7 +371,8 @@ async def update( cf_interconnect_id: Identifier automatic_return_routing: True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. description: An optional description of the interconnect. diff --git a/src/cloudflare/resources/magic_transit/connectors/connectors.py b/src/cloudflare/resources/magic_transit/connectors/connectors.py index d842d3ecd80..bf11a0bced6 100644 --- a/src/cloudflare/resources/magic_transit/connectors/connectors.py +++ b/src/cloudflare/resources/magic_transit/connectors/connectors.py @@ -36,7 +36,12 @@ SnapshotsResourceWithStreamingResponse, AsyncSnapshotsResourceWithStreamingResponse, ) -from ....types.magic_transit import connector_edit_params, connector_create_params, connector_update_params +from ....types.magic_transit import ( + connector_edit_params, + connector_list_params, + connector_create_params, + connector_update_params, +) from ....types.magic_transit.connector_get_response import ConnectorGetResponse from ....types.magic_transit.connector_edit_response import ConnectorEditResponse from ....types.magic_transit.connector_list_response import ConnectorListResponse @@ -224,6 +229,7 @@ def list( self, *, account_id: str, + device_type: Literal["MANAGED", "LICENSED"] | 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, @@ -237,6 +243,8 @@ def list( Args: account_id: Account identifier + device_type: Filter connectors by device type. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -251,7 +259,11 @@ def list( path_template("/accounts/{account_id}/magic/connectors", account_id=account_id), page=SyncSinglePage[ConnectorListResponse], options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform({"device_type": device_type}, connector_list_params.ConnectorListParams), ), model=ConnectorListResponse, ) @@ -602,6 +614,7 @@ def list( self, *, account_id: str, + device_type: Literal["MANAGED", "LICENSED"] | 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, @@ -615,6 +628,8 @@ def list( Args: account_id: Account identifier + device_type: Filter connectors by device type. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -629,7 +644,11 @@ def list( path_template("/accounts/{account_id}/magic/connectors", account_id=account_id), page=AsyncSinglePage[ConnectorListResponse], options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform({"device_type": device_type}, connector_list_params.ConnectorListParams), ), model=ConnectorListResponse, ) diff --git a/src/cloudflare/resources/magic_transit/gre_tunnels.py b/src/cloudflare/resources/magic_transit/gre_tunnels.py index e0cf9482bee..96d0d1f6ea7 100644 --- a/src/cloudflare/resources/magic_transit/gre_tunnels.py +++ b/src/cloudflare/resources/magic_transit/gre_tunnels.py @@ -92,7 +92,8 @@ def create( must be 15 characters or less, and cannot share a name with another GRE tunnel. automatic_return_routing: True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. description: An optional description of the GRE tunnel. @@ -199,7 +200,8 @@ def update( must be 15 characters or less, and cannot share a name with another GRE tunnel. automatic_return_routing: True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. description: An optional description of the GRE tunnel. @@ -554,7 +556,8 @@ async def create( must be 15 characters or less, and cannot share a name with another GRE tunnel. automatic_return_routing: True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. description: An optional description of the GRE tunnel. @@ -661,7 +664,8 @@ async def update( must be 15 characters or less, and cannot share a name with another GRE tunnel. automatic_return_routing: True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. description: An optional description of the GRE tunnel. diff --git a/src/cloudflare/resources/magic_transit/ipsec_tunnels.py b/src/cloudflare/resources/magic_transit/ipsec_tunnels.py index 0e3f3ade8bc..776165a6701 100644 --- a/src/cloudflare/resources/magic_transit/ipsec_tunnels.py +++ b/src/cloudflare/resources/magic_transit/ipsec_tunnels.py @@ -97,7 +97,8 @@ def create( name: The name of the IPsec tunnel. The name cannot share a name with other tunnels. automatic_return_routing: True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. customer_endpoint: The IP address assigned to the customer side of the IPsec tunnel. Not required, but must be set for proactive traceroutes to work. @@ -208,7 +209,8 @@ def update( name: The name of the IPsec tunnel. The name cannot share a name with other tunnels. automatic_return_routing: True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. customer_endpoint: The IP address assigned to the customer side of the IPsec tunnel. Not required, but must be set for proactive traceroutes to work. @@ -622,7 +624,8 @@ async def create( name: The name of the IPsec tunnel. The name cannot share a name with other tunnels. automatic_return_routing: True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. customer_endpoint: The IP address assigned to the customer side of the IPsec tunnel. Not required, but must be set for proactive traceroutes to work. @@ -733,7 +736,8 @@ async def update( name: The name of the IPsec tunnel. The name cannot share a name with other tunnels. automatic_return_routing: True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. customer_endpoint: The IP address assigned to the customer side of the IPsec tunnel. Not required, but must be set for proactive traceroutes to work. diff --git a/src/cloudflare/resources/queues/api.md b/src/cloudflare/resources/queues/api.md index 377d7d6186b..59d3863934b 100644 --- a/src/cloudflare/resources/queues/api.md +++ b/src/cloudflare/resources/queues/api.md @@ -3,7 +3,7 @@ Types: ```python -from cloudflare.types.queues import Queue, QueueDeleteResponse +from cloudflare.types.queues import Queue, QueueDeleteResponse, QueueGetMetricsResponse ``` Methods: @@ -14,6 +14,7 @@ Methods: - client.queues.delete(queue_id, \*, account_id) -> QueueDeleteResponse - client.queues.edit(queue_id, \*, account_id, \*\*params) -> Optional[Queue] - client.queues.get(queue_id, \*, account_id) -> Optional[Queue] +- client.queues.get_metrics(queue_id, \*, account_id) -> Optional[QueueGetMetricsResponse] ## Messages diff --git a/src/cloudflare/resources/queues/queues.py b/src/cloudflare/resources/queues/queues.py index 138d47827c4..775e62f2a71 100644 --- a/src/cloudflare/resources/queues/queues.py +++ b/src/cloudflare/resources/queues/queues.py @@ -54,6 +54,7 @@ from ...types.queues import queue_edit_params, queue_create_params, queue_update_params from ...types.queues.queue import Queue from ...types.queues.queue_delete_response import QueueDeleteResponse +from ...types.queues.queue_get_metrics_response import QueueGetMetricsResponse __all__ = ["QueuesResource", "AsyncQueuesResource"] @@ -364,6 +365,52 @@ def get( cast_to=cast(Type[Optional[Queue]], ResultWrapper[Queue]), ) + def get_metrics( + self, + queue_id: str, + *, + account_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, + ) -> Optional[QueueGetMetricsResponse]: + """Return best-effort metrics for a queue. + + Values may be approximate due to the + distributed nature of queues. + + Args: + account_id: A Resource identifier. + + queue_id: A Resource identifier. + + 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 account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not queue_id: + raise ValueError(f"Expected a non-empty value for `queue_id` but received {queue_id!r}") + return self._get( + path_template("/accounts/{account_id}/queues/{queue_id}/metrics", account_id=account_id, queue_id=queue_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[QueueGetMetricsResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[QueueGetMetricsResponse]], ResultWrapper[QueueGetMetricsResponse]), + ) + class AsyncQueuesResource(AsyncAPIResource): @cached_property @@ -671,6 +718,52 @@ async def get( cast_to=cast(Type[Optional[Queue]], ResultWrapper[Queue]), ) + async def get_metrics( + self, + queue_id: str, + *, + account_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, + ) -> Optional[QueueGetMetricsResponse]: + """Return best-effort metrics for a queue. + + Values may be approximate due to the + distributed nature of queues. + + Args: + account_id: A Resource identifier. + + queue_id: A Resource identifier. + + 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 account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not queue_id: + raise ValueError(f"Expected a non-empty value for `queue_id` but received {queue_id!r}") + return await self._get( + path_template("/accounts/{account_id}/queues/{queue_id}/metrics", account_id=account_id, queue_id=queue_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[QueueGetMetricsResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[QueueGetMetricsResponse]], ResultWrapper[QueueGetMetricsResponse]), + ) + class QueuesResourceWithRawResponse: def __init__(self, queues: QueuesResource) -> None: @@ -694,6 +787,9 @@ def __init__(self, queues: QueuesResource) -> None: self.get = to_raw_response_wrapper( queues.get, ) + self.get_metrics = to_raw_response_wrapper( + queues.get_metrics, + ) @cached_property def messages(self) -> MessagesResourceWithRawResponse: @@ -734,6 +830,9 @@ def __init__(self, queues: AsyncQueuesResource) -> None: self.get = async_to_raw_response_wrapper( queues.get, ) + self.get_metrics = async_to_raw_response_wrapper( + queues.get_metrics, + ) @cached_property def messages(self) -> AsyncMessagesResourceWithRawResponse: @@ -774,6 +873,9 @@ def __init__(self, queues: QueuesResource) -> None: self.get = to_streamed_response_wrapper( queues.get, ) + self.get_metrics = to_streamed_response_wrapper( + queues.get_metrics, + ) @cached_property def messages(self) -> MessagesResourceWithStreamingResponse: @@ -814,6 +916,9 @@ def __init__(self, queues: AsyncQueuesResource) -> None: self.get = async_to_streamed_response_wrapper( queues.get, ) + self.get_metrics = async_to_streamed_response_wrapper( + queues.get_metrics, + ) @cached_property def messages(self) -> AsyncMessagesResourceWithStreamingResponse: diff --git a/src/cloudflare/resources/workers/observability/telemetry.py b/src/cloudflare/resources/workers/observability/telemetry.py index 757102e555a..782b8f08f19 100644 --- a/src/cloudflare/resources/workers/observability/telemetry.py +++ b/src/cloudflare/resources/workers/observability/telemetry.py @@ -139,44 +139,53 @@ def query( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TelemetryQueryResponse: - """ - Run a temporary or saved query. + """Run a temporary or saved query. Args: - query_id: Unique identifier for the query to execute + query_id: Identifier for the query. + + When parameters are omitted, this ID is used to load a + previously saved query's parameters. When providing parameters inline, pass any + identifier (e.g. an ad-hoc ID). - timeframe: Timeframe for your query using Unix timestamps in milliseconds. Provide from/to - epoch ms; narrower timeframes provide faster responses and more specific - results. + timeframe: Timeframe for the query using Unix timestamps in milliseconds. Narrower + timeframes produce faster responses and more specific results. - chart: Whether to include timeseties data in the response + chart: When true, includes time-series data in the response. - compare: Whether to include comparison data with previous time periods + compare: When true, includes a comparison dataset from the previous time period of equal + length. - dry: Whether to perform a dry run without saving the results of the query. Useful for - validation + dry: When true, executes the query without persisting the results. Useful for + validation or previewing. - granularity: This is only used when the view is calculations. Leaving it empty lets Workers - Observability detect the correct granularity. + granularity: Number of time-series buckets. Only used when view is 'calculations'. Omit to + let the system auto-detect an appropriate granularity. - ignore_series: Whether to ignore time-series data in the results and return only aggregated - values + ignore_series: When true, omits time-series data from the response and returns only aggregated + values. Reduces response size when series are not needed. - limit: Use this limit to cap the number of events returned when the view is events. + limit: Maximum number of events to return when view is 'events'. Also controls the + number of group-by rows when view is 'calculations'. - offset: Cursor pagination for event/trace/invocation views. Pass the last item's - $metadata.id as the next offset. + offset: Cursor for pagination in event, trace, and invocation views. Pass the + $metadata.id of the last returned item to fetch the next page. - offset_by: Numeric offset for pattern results (top-N list). Use with limit to page pattern - groups; not used by cursor pagination. + offset_by: Numeric offset for paginating grouped/pattern results (top-N lists). Use + together with limit. Not used by cursor-based pagination. - offset_direction: Direction for offset-based pagination (e.g., 'next', 'prev') + offset_direction: Pagination direction: 'next' for forward, 'prev' for backward. - parameters: Optional parameters to pass to the query execution + parameters: Query parameters defining what data to retrieve — filters, calculations, + group-bys, and ordering. In practice this should always be provided for ad-hoc + queries. Only omit when executing a previously saved query by queryId. Use the + keys and values endpoints to discover available fields before building filters. - view: Examples by view type. Events: show errors for a worker in the last 30 minutes. - Calculations: p99 of wall time or count by status code. Invocations: find a - specific request that resulted in a 500. + view: Controls the shape of the response. 'events': individual log lines matching the + query. 'calculations': aggregated metrics (count, avg, p99, etc.) with optional + group-by breakdowns and time-series. 'invocations': events grouped by request + ID. 'traces': distributed trace summaries. 'agents': Durable Object agent + summaries. extra_headers: Send extra headers @@ -245,7 +254,8 @@ def values( filters: Apply filters before listing values. Supports nested groups via kind: 'group'. Maximum nesting depth is 4. - needle: Search for a specific substring in the event. + needle: Full-text search expression to match events containing the specified text or + pattern. extra_headers: Send extra headers @@ -391,44 +401,53 @@ async def query( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TelemetryQueryResponse: - """ - Run a temporary or saved query. + """Run a temporary or saved query. Args: - query_id: Unique identifier for the query to execute + query_id: Identifier for the query. + + When parameters are omitted, this ID is used to load a + previously saved query's parameters. When providing parameters inline, pass any + identifier (e.g. an ad-hoc ID). - timeframe: Timeframe for your query using Unix timestamps in milliseconds. Provide from/to - epoch ms; narrower timeframes provide faster responses and more specific - results. + timeframe: Timeframe for the query using Unix timestamps in milliseconds. Narrower + timeframes produce faster responses and more specific results. - chart: Whether to include timeseties data in the response + chart: When true, includes time-series data in the response. - compare: Whether to include comparison data with previous time periods + compare: When true, includes a comparison dataset from the previous time period of equal + length. - dry: Whether to perform a dry run without saving the results of the query. Useful for - validation + dry: When true, executes the query without persisting the results. Useful for + validation or previewing. - granularity: This is only used when the view is calculations. Leaving it empty lets Workers - Observability detect the correct granularity. + granularity: Number of time-series buckets. Only used when view is 'calculations'. Omit to + let the system auto-detect an appropriate granularity. - ignore_series: Whether to ignore time-series data in the results and return only aggregated - values + ignore_series: When true, omits time-series data from the response and returns only aggregated + values. Reduces response size when series are not needed. - limit: Use this limit to cap the number of events returned when the view is events. + limit: Maximum number of events to return when view is 'events'. Also controls the + number of group-by rows when view is 'calculations'. - offset: Cursor pagination for event/trace/invocation views. Pass the last item's - $metadata.id as the next offset. + offset: Cursor for pagination in event, trace, and invocation views. Pass the + $metadata.id of the last returned item to fetch the next page. - offset_by: Numeric offset for pattern results (top-N list). Use with limit to page pattern - groups; not used by cursor pagination. + offset_by: Numeric offset for paginating grouped/pattern results (top-N lists). Use + together with limit. Not used by cursor-based pagination. - offset_direction: Direction for offset-based pagination (e.g., 'next', 'prev') + offset_direction: Pagination direction: 'next' for forward, 'prev' for backward. - parameters: Optional parameters to pass to the query execution + parameters: Query parameters defining what data to retrieve — filters, calculations, + group-bys, and ordering. In practice this should always be provided for ad-hoc + queries. Only omit when executing a previously saved query by queryId. Use the + keys and values endpoints to discover available fields before building filters. - view: Examples by view type. Events: show errors for a worker in the last 30 minutes. - Calculations: p99 of wall time or count by status code. Invocations: find a - specific request that resulted in a 500. + view: Controls the shape of the response. 'events': individual log lines matching the + query. 'calculations': aggregated metrics (count, avg, p99, etc.) with optional + group-by breakdowns and time-series. 'invocations': events grouped by request + ID. 'traces': distributed trace summaries. 'agents': Durable Object agent + summaries. extra_headers: Send extra headers @@ -497,7 +516,8 @@ def values( filters: Apply filters before listing values. Supports nested groups via kind: 'group'. Maximum nesting depth is 4. - needle: Search for a specific substring in the event. + needle: Full-text search expression to match events containing the specified text or + pattern. extra_headers: Send extra headers diff --git a/src/cloudflare/resources/zero_trust/access/applications/policy_tests/__init__.py b/src/cloudflare/resources/zero_trust/access/applications/policy_tests/__init__.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/resources/zero_trust/access/applications/policy_tests/policy_tests.py b/src/cloudflare/resources/zero_trust/access/applications/policy_tests/policy_tests.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/resources/zero_trust/access/applications/policy_tests/users.py b/src/cloudflare/resources/zero_trust/access/applications/policy_tests/users.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/resources/zero_trust/api.md b/src/cloudflare/resources/zero_trust/api.md index cedf199e090..35c0c1fd0d3 100644 --- a/src/cloudflare/resources/zero_trust/api.md +++ b/src/cloudflare/resources/zero_trust/api.md @@ -103,6 +103,22 @@ Methods: - client.zero_trust.devices.ip_profiles.delete(profile_id, \*, account_id) -> IPProfileDeleteResponse - client.zero_trust.devices.ip_profiles.get(profile_id, \*, account_id) -> IPProfile +### DeploymentGroups + +Types: + +```python +from cloudflare.types.zero_trust.devices import DeploymentGroup, DeploymentGroupDeleteResponse +``` + +Methods: + +- client.zero_trust.devices.deployment_groups.create(\*, account_id, \*\*params) -> DeploymentGroup +- client.zero_trust.devices.deployment_groups.list(\*, account_id, \*\*params) -> SyncV4PagePaginationArray[DeploymentGroup] +- client.zero_trust.devices.deployment_groups.delete(group_id, \*, account_id) -> DeploymentGroupDeleteResponse +- client.zero_trust.devices.deployment_groups.edit(group_id, \*, account_id, \*\*params) -> DeploymentGroup +- client.zero_trust.devices.deployment_groups.get(group_id, \*, account_id) -> DeploymentGroup + ### Networks Types: diff --git a/src/cloudflare/resources/zero_trust/devices/__init__.py b/src/cloudflare/resources/zero_trust/devices/__init__.py index a3579f08c06..45351e0fe62 100644 --- a/src/cloudflare/resources/zero_trust/devices/__init__.py +++ b/src/cloudflare/resources/zero_trust/devices/__init__.py @@ -104,6 +104,14 @@ OverrideCodesResourceWithStreamingResponse, AsyncOverrideCodesResourceWithStreamingResponse, ) +from .deployment_groups import ( + DeploymentGroupsResource, + AsyncDeploymentGroupsResource, + DeploymentGroupsResourceWithRawResponse, + AsyncDeploymentGroupsResourceWithRawResponse, + DeploymentGroupsResourceWithStreamingResponse, + AsyncDeploymentGroupsResourceWithStreamingResponse, +) __all__ = [ "ResilienceResource", @@ -130,6 +138,12 @@ "AsyncIPProfilesResourceWithRawResponse", "IPProfilesResourceWithStreamingResponse", "AsyncIPProfilesResourceWithStreamingResponse", + "DeploymentGroupsResource", + "AsyncDeploymentGroupsResource", + "DeploymentGroupsResourceWithRawResponse", + "AsyncDeploymentGroupsResourceWithRawResponse", + "DeploymentGroupsResourceWithStreamingResponse", + "AsyncDeploymentGroupsResourceWithStreamingResponse", "NetworksResource", "AsyncNetworksResource", "NetworksResourceWithRawResponse", diff --git a/src/cloudflare/resources/zero_trust/devices/deployment_groups.py b/src/cloudflare/resources/zero_trust/devices/deployment_groups.py new file mode 100644 index 00000000000..12df51fa905 --- /dev/null +++ b/src/cloudflare/resources/zero_trust/devices/deployment_groups.py @@ -0,0 +1,668 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Type, Iterable, cast + +import httpx + +from ...._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given +from ...._utils import path_template, maybe_transform, async_maybe_transform +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._wrappers import ResultWrapper +from ....pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray +from ...._base_client import AsyncPaginator, make_request_options +from ....types.zero_trust.devices import ( + deployment_group_edit_params, + deployment_group_list_params, + deployment_group_create_params, +) +from ....types.zero_trust.devices.deployment_group import DeploymentGroup +from ....types.zero_trust.devices.deployment_group_delete_response import DeploymentGroupDeleteResponse + +__all__ = ["DeploymentGroupsResource", "AsyncDeploymentGroupsResource"] + + +class DeploymentGroupsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> DeploymentGroupsResourceWithRawResponse: + """ + 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/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return DeploymentGroupsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> DeploymentGroupsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return DeploymentGroupsResourceWithStreamingResponse(self) + + def create( + self, + *, + account_id: str, + name: str, + version_config: Iterable[deployment_group_create_params.VersionConfig], + policy_ids: SequenceNotStr[str] | 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, + ) -> DeploymentGroup: + """Creates a new deployment group. + + Policy IDs must be unique across all deployment + groups. This endpoint is in Beta. + + Args: + name: A user-friendly name for the deployment group. + + version_config: Contains at least one version configuration. + + policy_ids: Contains an optional list of policy IDs assigned to a group. + + 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 account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._post( + path_template("/accounts/{account_id}/devices/deployment-groups", account_id=account_id), + body=maybe_transform( + { + "name": name, + "version_config": version_config, + "policy_ids": policy_ids, + }, + deployment_group_create_params.DeploymentGroupCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[DeploymentGroup]._unwrapper, + ), + cast_to=cast(Type[DeploymentGroup], ResultWrapper[DeploymentGroup]), + ) + + def list( + self, + *, + account_id: str, + page: int | Omit = omit, + per_page: 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, + ) -> SyncV4PagePaginationArray[DeploymentGroup]: + """Lists all deployment groups for an account. + + Use deployment groups to assign + target WARP client versions to specific devices. This endpoint is in Beta. + + Args: + page: The page number to return. + + per_page: The maximum number of deployment groups to return per page. + + 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 account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/devices/deployment-groups", account_id=account_id), + page=SyncV4PagePaginationArray[DeploymentGroup], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "page": page, + "per_page": per_page, + }, + deployment_group_list_params.DeploymentGroupListParams, + ), + ), + model=DeploymentGroup, + ) + + def delete( + self, + group_id: str, + *, + account_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, + ) -> DeploymentGroupDeleteResponse: + """Deletes a deployment group. + + Associated policies no longer apply and devices stop + receiving version targets. This endpoint is in Beta. + + Args: + 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 account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not group_id: + raise ValueError(f"Expected a non-empty value for `group_id` but received {group_id!r}") + return self._delete( + path_template( + "/accounts/{account_id}/devices/deployment-groups/{group_id}", account_id=account_id, group_id=group_id + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[DeploymentGroupDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[DeploymentGroupDeleteResponse], ResultWrapper[DeploymentGroupDeleteResponse]), + ) + + def edit( + self, + group_id: str, + *, + account_id: str, + name: str | Omit = omit, + policy_ids: SequenceNotStr[str] | Omit = omit, + version_config: Iterable[deployment_group_edit_params.VersionConfig] | 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, + ) -> DeploymentGroup: + """Updates a deployment group. + + Returns 409 if any newly added policy IDs already + belong to another deployment group. This endpoint is in Beta. + + Args: + name: A user-friendly name for the deployment group. + + policy_ids: Replaces the entire list of policy IDs. + + version_config: Replaces the entire version_config array. + + 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 account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not group_id: + raise ValueError(f"Expected a non-empty value for `group_id` but received {group_id!r}") + return self._patch( + path_template( + "/accounts/{account_id}/devices/deployment-groups/{group_id}", account_id=account_id, group_id=group_id + ), + body=maybe_transform( + { + "name": name, + "policy_ids": policy_ids, + "version_config": version_config, + }, + deployment_group_edit_params.DeploymentGroupEditParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[DeploymentGroup]._unwrapper, + ), + cast_to=cast(Type[DeploymentGroup], ResultWrapper[DeploymentGroup]), + ) + + def get( + self, + group_id: str, + *, + account_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, + ) -> DeploymentGroup: + """Fetches a single deployment group by its ID. + + This endpoint is in Beta. + + Args: + 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 account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not group_id: + raise ValueError(f"Expected a non-empty value for `group_id` but received {group_id!r}") + return self._get( + path_template( + "/accounts/{account_id}/devices/deployment-groups/{group_id}", account_id=account_id, group_id=group_id + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[DeploymentGroup]._unwrapper, + ), + cast_to=cast(Type[DeploymentGroup], ResultWrapper[DeploymentGroup]), + ) + + +class AsyncDeploymentGroupsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncDeploymentGroupsResourceWithRawResponse: + """ + 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/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncDeploymentGroupsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncDeploymentGroupsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncDeploymentGroupsResourceWithStreamingResponse(self) + + async def create( + self, + *, + account_id: str, + name: str, + version_config: Iterable[deployment_group_create_params.VersionConfig], + policy_ids: SequenceNotStr[str] | 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, + ) -> DeploymentGroup: + """Creates a new deployment group. + + Policy IDs must be unique across all deployment + groups. This endpoint is in Beta. + + Args: + name: A user-friendly name for the deployment group. + + version_config: Contains at least one version configuration. + + policy_ids: Contains an optional list of policy IDs assigned to a group. + + 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 account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return await self._post( + path_template("/accounts/{account_id}/devices/deployment-groups", account_id=account_id), + body=await async_maybe_transform( + { + "name": name, + "version_config": version_config, + "policy_ids": policy_ids, + }, + deployment_group_create_params.DeploymentGroupCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[DeploymentGroup]._unwrapper, + ), + cast_to=cast(Type[DeploymentGroup], ResultWrapper[DeploymentGroup]), + ) + + def list( + self, + *, + account_id: str, + page: int | Omit = omit, + per_page: 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[DeploymentGroup, AsyncV4PagePaginationArray[DeploymentGroup]]: + """Lists all deployment groups for an account. + + Use deployment groups to assign + target WARP client versions to specific devices. This endpoint is in Beta. + + Args: + page: The page number to return. + + per_page: The maximum number of deployment groups to return per page. + + 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 account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/devices/deployment-groups", account_id=account_id), + page=AsyncV4PagePaginationArray[DeploymentGroup], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "page": page, + "per_page": per_page, + }, + deployment_group_list_params.DeploymentGroupListParams, + ), + ), + model=DeploymentGroup, + ) + + async def delete( + self, + group_id: str, + *, + account_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, + ) -> DeploymentGroupDeleteResponse: + """Deletes a deployment group. + + Associated policies no longer apply and devices stop + receiving version targets. This endpoint is in Beta. + + Args: + 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 account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not group_id: + raise ValueError(f"Expected a non-empty value for `group_id` but received {group_id!r}") + return await self._delete( + path_template( + "/accounts/{account_id}/devices/deployment-groups/{group_id}", account_id=account_id, group_id=group_id + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[DeploymentGroupDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[DeploymentGroupDeleteResponse], ResultWrapper[DeploymentGroupDeleteResponse]), + ) + + async def edit( + self, + group_id: str, + *, + account_id: str, + name: str | Omit = omit, + policy_ids: SequenceNotStr[str] | Omit = omit, + version_config: Iterable[deployment_group_edit_params.VersionConfig] | 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, + ) -> DeploymentGroup: + """Updates a deployment group. + + Returns 409 if any newly added policy IDs already + belong to another deployment group. This endpoint is in Beta. + + Args: + name: A user-friendly name for the deployment group. + + policy_ids: Replaces the entire list of policy IDs. + + version_config: Replaces the entire version_config array. + + 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 account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not group_id: + raise ValueError(f"Expected a non-empty value for `group_id` but received {group_id!r}") + return await self._patch( + path_template( + "/accounts/{account_id}/devices/deployment-groups/{group_id}", account_id=account_id, group_id=group_id + ), + body=await async_maybe_transform( + { + "name": name, + "policy_ids": policy_ids, + "version_config": version_config, + }, + deployment_group_edit_params.DeploymentGroupEditParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[DeploymentGroup]._unwrapper, + ), + cast_to=cast(Type[DeploymentGroup], ResultWrapper[DeploymentGroup]), + ) + + async def get( + self, + group_id: str, + *, + account_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, + ) -> DeploymentGroup: + """Fetches a single deployment group by its ID. + + This endpoint is in Beta. + + Args: + 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 account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not group_id: + raise ValueError(f"Expected a non-empty value for `group_id` but received {group_id!r}") + return await self._get( + path_template( + "/accounts/{account_id}/devices/deployment-groups/{group_id}", account_id=account_id, group_id=group_id + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[DeploymentGroup]._unwrapper, + ), + cast_to=cast(Type[DeploymentGroup], ResultWrapper[DeploymentGroup]), + ) + + +class DeploymentGroupsResourceWithRawResponse: + def __init__(self, deployment_groups: DeploymentGroupsResource) -> None: + self._deployment_groups = deployment_groups + + self.create = to_raw_response_wrapper( + deployment_groups.create, + ) + self.list = to_raw_response_wrapper( + deployment_groups.list, + ) + self.delete = to_raw_response_wrapper( + deployment_groups.delete, + ) + self.edit = to_raw_response_wrapper( + deployment_groups.edit, + ) + self.get = to_raw_response_wrapper( + deployment_groups.get, + ) + + +class AsyncDeploymentGroupsResourceWithRawResponse: + def __init__(self, deployment_groups: AsyncDeploymentGroupsResource) -> None: + self._deployment_groups = deployment_groups + + self.create = async_to_raw_response_wrapper( + deployment_groups.create, + ) + self.list = async_to_raw_response_wrapper( + deployment_groups.list, + ) + self.delete = async_to_raw_response_wrapper( + deployment_groups.delete, + ) + self.edit = async_to_raw_response_wrapper( + deployment_groups.edit, + ) + self.get = async_to_raw_response_wrapper( + deployment_groups.get, + ) + + +class DeploymentGroupsResourceWithStreamingResponse: + def __init__(self, deployment_groups: DeploymentGroupsResource) -> None: + self._deployment_groups = deployment_groups + + self.create = to_streamed_response_wrapper( + deployment_groups.create, + ) + self.list = to_streamed_response_wrapper( + deployment_groups.list, + ) + self.delete = to_streamed_response_wrapper( + deployment_groups.delete, + ) + self.edit = to_streamed_response_wrapper( + deployment_groups.edit, + ) + self.get = to_streamed_response_wrapper( + deployment_groups.get, + ) + + +class AsyncDeploymentGroupsResourceWithStreamingResponse: + def __init__(self, deployment_groups: AsyncDeploymentGroupsResource) -> None: + self._deployment_groups = deployment_groups + + self.create = async_to_streamed_response_wrapper( + deployment_groups.create, + ) + self.list = async_to_streamed_response_wrapper( + deployment_groups.list, + ) + self.delete = async_to_streamed_response_wrapper( + deployment_groups.delete, + ) + self.edit = async_to_streamed_response_wrapper( + deployment_groups.edit, + ) + self.get = async_to_streamed_response_wrapper( + deployment_groups.get, + ) diff --git a/src/cloudflare/resources/zero_trust/devices/devices.py b/src/cloudflare/resources/zero_trust/devices/devices.py index d94495d96a1..efd14729f02 100644 --- a/src/cloudflare/resources/zero_trust/devices/devices.py +++ b/src/cloudflare/resources/zero_trust/devices/devices.py @@ -101,6 +101,14 @@ PostureResourceWithStreamingResponse, AsyncPostureResourceWithStreamingResponse, ) +from .deployment_groups import ( + DeploymentGroupsResource, + AsyncDeploymentGroupsResource, + DeploymentGroupsResourceWithRawResponse, + AsyncDeploymentGroupsResourceWithRawResponse, + DeploymentGroupsResourceWithStreamingResponse, + AsyncDeploymentGroupsResourceWithStreamingResponse, +) from .policies.policies import ( PoliciesResource, AsyncPoliciesResource, @@ -144,6 +152,10 @@ def dex_tests(self) -> DEXTestsResource: def ip_profiles(self) -> IPProfilesResource: return IPProfilesResource(self._client) + @cached_property + def deployment_groups(self) -> DeploymentGroupsResource: + return DeploymentGroupsResource(self._client) + @cached_property def networks(self) -> NetworksResource: return NetworksResource(self._client) @@ -312,6 +324,10 @@ def dex_tests(self) -> AsyncDEXTestsResource: def ip_profiles(self) -> AsyncIPProfilesResource: return AsyncIPProfilesResource(self._client) + @cached_property + def deployment_groups(self) -> AsyncDeploymentGroupsResource: + return AsyncDeploymentGroupsResource(self._client) + @cached_property def networks(self) -> AsyncNetworksResource: return AsyncNetworksResource(self._client) @@ -494,6 +510,10 @@ def dex_tests(self) -> DEXTestsResourceWithRawResponse: def ip_profiles(self) -> IPProfilesResourceWithRawResponse: return IPProfilesResourceWithRawResponse(self._devices.ip_profiles) + @cached_property + def deployment_groups(self) -> DeploymentGroupsResourceWithRawResponse: + return DeploymentGroupsResourceWithRawResponse(self._devices.deployment_groups) + @cached_property def networks(self) -> NetworksResourceWithRawResponse: return NetworksResourceWithRawResponse(self._devices.networks) @@ -562,6 +582,10 @@ def dex_tests(self) -> AsyncDEXTestsResourceWithRawResponse: def ip_profiles(self) -> AsyncIPProfilesResourceWithRawResponse: return AsyncIPProfilesResourceWithRawResponse(self._devices.ip_profiles) + @cached_property + def deployment_groups(self) -> AsyncDeploymentGroupsResourceWithRawResponse: + return AsyncDeploymentGroupsResourceWithRawResponse(self._devices.deployment_groups) + @cached_property def networks(self) -> AsyncNetworksResourceWithRawResponse: return AsyncNetworksResourceWithRawResponse(self._devices.networks) @@ -630,6 +654,10 @@ def dex_tests(self) -> DEXTestsResourceWithStreamingResponse: def ip_profiles(self) -> IPProfilesResourceWithStreamingResponse: return IPProfilesResourceWithStreamingResponse(self._devices.ip_profiles) + @cached_property + def deployment_groups(self) -> DeploymentGroupsResourceWithStreamingResponse: + return DeploymentGroupsResourceWithStreamingResponse(self._devices.deployment_groups) + @cached_property def networks(self) -> NetworksResourceWithStreamingResponse: return NetworksResourceWithStreamingResponse(self._devices.networks) @@ -698,6 +726,10 @@ def dex_tests(self) -> AsyncDEXTestsResourceWithStreamingResponse: def ip_profiles(self) -> AsyncIPProfilesResourceWithStreamingResponse: return AsyncIPProfilesResourceWithStreamingResponse(self._devices.ip_profiles) + @cached_property + def deployment_groups(self) -> AsyncDeploymentGroupsResourceWithStreamingResponse: + return AsyncDeploymentGroupsResourceWithStreamingResponse(self._devices.deployment_groups) + @cached_property def networks(self) -> AsyncNetworksResourceWithStreamingResponse: return AsyncNetworksResourceWithStreamingResponse(self._devices.networks) diff --git a/src/cloudflare/resources/zero_trust/devices/policies/custom/custom.py b/src/cloudflare/resources/zero_trust/devices/policies/custom/custom.py index ae7b27236a8..ee4baacac41 100644 --- a/src/cloudflare/resources/zero_trust/devices/policies/custom/custom.py +++ b/src/cloudflare/resources/zero_trust/devices/policies/custom/custom.py @@ -109,6 +109,7 @@ def create( support_url: str | Omit = omit, switch_locked: bool | Omit = omit, tunnel_protocol: str | Omit = omit, + virtual_networks: Optional[custom_create_params.VirtualNetworks] | 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, @@ -178,6 +179,8 @@ def create( tunnel_protocol: Determines which tunnel protocol to use. + virtual_networks: Virtual network access settings for the device. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -214,6 +217,7 @@ def create( "support_url": support_url, "switch_locked": switch_locked, "tunnel_protocol": tunnel_protocol, + "virtual_networks": virtual_networks, }, custom_create_params.CustomCreateParams, ), @@ -329,6 +333,7 @@ def edit( support_url: str | Omit = omit, switch_locked: bool | Omit = omit, tunnel_protocol: str | Omit = omit, + virtual_networks: Optional[custom_edit_params.VirtualNetworks] | 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, @@ -397,6 +402,8 @@ def edit( tunnel_protocol: Determines which tunnel protocol to use. + virtual_networks: Virtual network access settings for the device. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -437,6 +444,7 @@ def edit( "support_url": support_url, "switch_locked": switch_locked, "tunnel_protocol": tunnel_protocol, + "virtual_networks": virtual_networks, }, custom_edit_params.CustomEditParams, ), @@ -551,6 +559,7 @@ async def create( support_url: str | Omit = omit, switch_locked: bool | Omit = omit, tunnel_protocol: str | Omit = omit, + virtual_networks: Optional[custom_create_params.VirtualNetworks] | 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, @@ -620,6 +629,8 @@ async def create( tunnel_protocol: Determines which tunnel protocol to use. + virtual_networks: Virtual network access settings for the device. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -656,6 +667,7 @@ async def create( "support_url": support_url, "switch_locked": switch_locked, "tunnel_protocol": tunnel_protocol, + "virtual_networks": virtual_networks, }, custom_create_params.CustomCreateParams, ), @@ -771,6 +783,7 @@ async def edit( support_url: str | Omit = omit, switch_locked: bool | Omit = omit, tunnel_protocol: str | Omit = omit, + virtual_networks: Optional[custom_edit_params.VirtualNetworks] | 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, @@ -839,6 +852,8 @@ async def edit( tunnel_protocol: Determines which tunnel protocol to use. + virtual_networks: Virtual network access settings for the device. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -879,6 +894,7 @@ async def edit( "support_url": support_url, "switch_locked": switch_locked, "tunnel_protocol": tunnel_protocol, + "virtual_networks": virtual_networks, }, custom_edit_params.CustomEditParams, ), diff --git a/src/cloudflare/resources/zero_trust/devices/policies/default/default.py b/src/cloudflare/resources/zero_trust/devices/policies/default/default.py index 42273b7fee8..cbe59b3adac 100644 --- a/src/cloudflare/resources/zero_trust/devices/policies/default/default.py +++ b/src/cloudflare/resources/zero_trust/devices/policies/default/default.py @@ -116,6 +116,7 @@ def edit( support_url: str | Omit = omit, switch_locked: bool | Omit = omit, tunnel_protocol: str | Omit = omit, + virtual_networks: Optional[default_edit_params.VirtualNetworks] | 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, @@ -170,6 +171,8 @@ def edit( tunnel_protocol: Determines which tunnel protocol to use. + virtual_networks: Virtual network access settings for the device. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -201,6 +204,7 @@ def edit( "support_url": support_url, "switch_locked": switch_locked, "tunnel_protocol": tunnel_protocol, + "virtual_networks": virtual_networks, }, default_edit_params.DefaultEditParams, ), @@ -309,6 +313,7 @@ async def edit( support_url: str | Omit = omit, switch_locked: bool | Omit = omit, tunnel_protocol: str | Omit = omit, + virtual_networks: Optional[default_edit_params.VirtualNetworks] | 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, @@ -363,6 +368,8 @@ async def edit( tunnel_protocol: Determines which tunnel protocol to use. + virtual_networks: Virtual network access settings for the device. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -394,6 +401,7 @@ async def edit( "support_url": support_url, "switch_locked": switch_locked, "tunnel_protocol": tunnel_protocol, + "virtual_networks": virtual_networks, }, default_edit_params.DefaultEditParams, ), diff --git a/src/cloudflare/resources/zero_trust/dlp/datasets/versions/__init__.py b/src/cloudflare/resources/zero_trust/dlp/datasets/versions/__init__.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/resources/zero_trust/dlp/datasets/versions/entries.py b/src/cloudflare/resources/zero_trust/dlp/datasets/versions/entries.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/resources/zero_trust/dlp/datasets/versions/versions.py b/src/cloudflare/resources/zero_trust/dlp/datasets/versions/versions.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/resources/zero_trust/dlp/limits.py b/src/cloudflare/resources/zero_trust/dlp/limits.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/resources/zero_trust/gateway/configurations/__init__.py b/src/cloudflare/resources/zero_trust/gateway/configurations/__init__.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/resources/zero_trust/gateway/configurations/configurations.py b/src/cloudflare/resources/zero_trust/gateway/configurations/configurations.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/resources/zones/zones.py b/src/cloudflare/resources/zones/zones.py index 290011057ee..ceba8dfd843 100644 --- a/src/cloudflare/resources/zones/zones.py +++ b/src/cloudflare/resources/zones/zones.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Type as TypingType, Optional, cast +from typing import List, Type as TypingType, Optional, cast from typing_extensions import Literal import httpx @@ -209,6 +209,7 @@ def list( page: float | Omit = omit, per_page: float | Omit = omit, status: Literal["initializing", "pending", "active", "moved"] | Omit = omit, + type: List[Literal["full", "partial", "secondary", "internal"]] | 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, @@ -246,6 +247,10 @@ def list( status: Specify a zone status to filter by. + type: Zone types to filter by. Multiple types can be specified as a comma-separated + list (e.g., ?type=full,partial,secondary). When this parameter is not provided, + zones with type "internal" are excluded from the results. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -272,6 +277,7 @@ def list( "page": page, "per_page": per_page, "status": status, + "type": type, }, zone_list_params.ZoneListParams, ), @@ -537,6 +543,7 @@ def list( page: float | Omit = omit, per_page: float | Omit = omit, status: Literal["initializing", "pending", "active", "moved"] | Omit = omit, + type: List[Literal["full", "partial", "secondary", "internal"]] | 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, @@ -574,6 +581,10 @@ def list( status: Specify a zone status to filter by. + type: Zone types to filter by. Multiple types can be specified as a comma-separated + list (e.g., ?type=full,partial,secondary). When this parameter is not provided, + zones with type "internal" are excluded from the results. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -600,6 +611,7 @@ def list( "page": page, "per_page": per_page, "status": status, + "type": type, }, zone_list_params.ZoneListParams, ), diff --git a/src/cloudflare/types/accounts/account_create_params.py b/src/cloudflare/types/accounts/account_create_params.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/types/accounts/account_delete_response.py b/src/cloudflare/types/accounts/account_delete_response.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/types/aisearch/instance_create_params.py b/src/cloudflare/types/aisearch/instance_create_params.py index 74f3cef2703..23246fed684 100644 --- a/src/cloudflare/types/aisearch/instance_create_params.py +++ b/src/cloudflare/types/aisearch/instance_create_params.py @@ -15,7 +15,6 @@ "IndexMethod", "IndexingOptions", "Metadata", - "MetadataSearchForAgents", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -214,19 +213,9 @@ class IndexingOptions(TypedDict, total=False): """ -class MetadataSearchForAgents(TypedDict, total=False): - hostname: Required[str] - - zone_id: Required[str] - - zone_name: Required[str] - - class Metadata(TypedDict, total=False): created_from_aisearch_wizard: bool - search_for_agents: MetadataSearchForAgents - worker_domain: str diff --git a/src/cloudflare/types/aisearch/instance_create_response.py b/src/cloudflare/types/aisearch/instance_create_response.py index a1d955a3e36..9640f00c300 100644 --- a/src/cloudflare/types/aisearch/instance_create_response.py +++ b/src/cloudflare/types/aisearch/instance_create_response.py @@ -15,7 +15,6 @@ "IndexMethod", "IndexingOptions", "Metadata", - "MetadataSearchForAgents", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -62,19 +61,9 @@ class IndexingOptions(BaseModel): """ -class MetadataSearchForAgents(BaseModel): - hostname: str - - zone_id: str - - zone_name: str - - class Metadata(BaseModel): created_from_aisearch_wizard: Optional[bool] = None - search_for_agents: Optional[MetadataSearchForAgents] = None - worker_domain: Optional[str] = None diff --git a/src/cloudflare/types/aisearch/instance_delete_response.py b/src/cloudflare/types/aisearch/instance_delete_response.py index 2d8af06cb64..d58c218ba08 100644 --- a/src/cloudflare/types/aisearch/instance_delete_response.py +++ b/src/cloudflare/types/aisearch/instance_delete_response.py @@ -15,7 +15,6 @@ "IndexMethod", "IndexingOptions", "Metadata", - "MetadataSearchForAgents", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -62,19 +61,9 @@ class IndexingOptions(BaseModel): """ -class MetadataSearchForAgents(BaseModel): - hostname: str - - zone_id: str - - zone_name: str - - class Metadata(BaseModel): created_from_aisearch_wizard: Optional[bool] = None - search_for_agents: Optional[MetadataSearchForAgents] = None - worker_domain: Optional[str] = None diff --git a/src/cloudflare/types/aisearch/instance_list_params.py b/src/cloudflare/types/aisearch/instance_list_params.py index 7c3b1faa18a..f7191795e9b 100644 --- a/src/cloudflare/types/aisearch/instance_list_params.py +++ b/src/cloudflare/types/aisearch/instance_list_params.py @@ -2,7 +2,6 @@ from __future__ import annotations -from typing import Optional from typing_extensions import Literal, Required, TypedDict __all__ = ["InstanceListParams"] @@ -11,17 +10,20 @@ class InstanceListParams(TypedDict, total=False): account_id: Required[str] - namespace: Optional[str] + namespace: str + """Filter by namespace.""" order_by: Literal["created_at"] - """Order By Column Name""" + """Field to order results by.""" order_by_direction: Literal["asc", "desc"] - """Order By Direction""" + """Order direction.""" page: int + """Page number (1-indexed).""" per_page: int + """Number of results per page.""" search: str - """Search by id""" + """Filter instances whose id contains this string (case-insensitive).""" diff --git a/src/cloudflare/types/aisearch/instance_list_response.py b/src/cloudflare/types/aisearch/instance_list_response.py index a18131f83ca..23678ce553e 100644 --- a/src/cloudflare/types/aisearch/instance_list_response.py +++ b/src/cloudflare/types/aisearch/instance_list_response.py @@ -15,7 +15,6 @@ "IndexMethod", "IndexingOptions", "Metadata", - "MetadataSearchForAgents", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -62,19 +61,9 @@ class IndexingOptions(BaseModel): """ -class MetadataSearchForAgents(BaseModel): - hostname: str - - zone_id: str - - zone_name: str - - class Metadata(BaseModel): created_from_aisearch_wizard: Optional[bool] = None - search_for_agents: Optional[MetadataSearchForAgents] = None - worker_domain: Optional[str] = None diff --git a/src/cloudflare/types/aisearch/instance_read_response.py b/src/cloudflare/types/aisearch/instance_read_response.py index f573f989aaa..45eaeae759e 100644 --- a/src/cloudflare/types/aisearch/instance_read_response.py +++ b/src/cloudflare/types/aisearch/instance_read_response.py @@ -15,7 +15,6 @@ "IndexMethod", "IndexingOptions", "Metadata", - "MetadataSearchForAgents", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -62,19 +61,9 @@ class IndexingOptions(BaseModel): """ -class MetadataSearchForAgents(BaseModel): - hostname: str - - zone_id: str - - zone_name: str - - class Metadata(BaseModel): created_from_aisearch_wizard: Optional[bool] = None - search_for_agents: Optional[MetadataSearchForAgents] = None - worker_domain: Optional[str] = None diff --git a/src/cloudflare/types/aisearch/instance_update_params.py b/src/cloudflare/types/aisearch/instance_update_params.py index efdbcbdf308..549194bf577 100644 --- a/src/cloudflare/types/aisearch/instance_update_params.py +++ b/src/cloudflare/types/aisearch/instance_update_params.py @@ -15,7 +15,6 @@ "IndexMethod", "IndexingOptions", "Metadata", - "MetadataSearchForAgents", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -249,19 +248,9 @@ class IndexingOptions(TypedDict, total=False): """ -class MetadataSearchForAgents(TypedDict, total=False): - hostname: Required[str] - - zone_id: Required[str] - - zone_name: Required[str] - - class Metadata(TypedDict, total=False): created_from_aisearch_wizard: bool - search_for_agents: MetadataSearchForAgents - worker_domain: str diff --git a/src/cloudflare/types/aisearch/instance_update_response.py b/src/cloudflare/types/aisearch/instance_update_response.py index ccbbe7cea67..5abc922e677 100644 --- a/src/cloudflare/types/aisearch/instance_update_response.py +++ b/src/cloudflare/types/aisearch/instance_update_response.py @@ -15,7 +15,6 @@ "IndexMethod", "IndexingOptions", "Metadata", - "MetadataSearchForAgents", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -62,19 +61,9 @@ class IndexingOptions(BaseModel): """ -class MetadataSearchForAgents(BaseModel): - hostname: str - - zone_id: str - - zone_name: str - - class Metadata(BaseModel): created_from_aisearch_wizard: Optional[bool] = None - search_for_agents: Optional[MetadataSearchForAgents] = None - worker_domain: Optional[str] = None diff --git a/src/cloudflare/types/aisearch/namespaces/instance_create_params.py b/src/cloudflare/types/aisearch/namespaces/instance_create_params.py index bf78a987478..d8f8a70a6cc 100644 --- a/src/cloudflare/types/aisearch/namespaces/instance_create_params.py +++ b/src/cloudflare/types/aisearch/namespaces/instance_create_params.py @@ -15,7 +15,6 @@ "IndexMethod", "IndexingOptions", "Metadata", - "MetadataSearchForAgents", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -214,19 +213,9 @@ class IndexingOptions(TypedDict, total=False): """ -class MetadataSearchForAgents(TypedDict, total=False): - hostname: Required[str] - - zone_id: Required[str] - - zone_name: Required[str] - - class Metadata(TypedDict, total=False): created_from_aisearch_wizard: bool - search_for_agents: MetadataSearchForAgents - worker_domain: str diff --git a/src/cloudflare/types/aisearch/namespaces/instance_create_response.py b/src/cloudflare/types/aisearch/namespaces/instance_create_response.py index e32256f511e..0dee72d00d8 100644 --- a/src/cloudflare/types/aisearch/namespaces/instance_create_response.py +++ b/src/cloudflare/types/aisearch/namespaces/instance_create_response.py @@ -15,7 +15,6 @@ "IndexMethod", "IndexingOptions", "Metadata", - "MetadataSearchForAgents", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -62,19 +61,9 @@ class IndexingOptions(BaseModel): """ -class MetadataSearchForAgents(BaseModel): - hostname: str - - zone_id: str - - zone_name: str - - class Metadata(BaseModel): created_from_aisearch_wizard: Optional[bool] = None - search_for_agents: Optional[MetadataSearchForAgents] = None - worker_domain: Optional[str] = None diff --git a/src/cloudflare/types/aisearch/namespaces/instance_delete_response.py b/src/cloudflare/types/aisearch/namespaces/instance_delete_response.py index 9854b1bf225..e870f6fc530 100644 --- a/src/cloudflare/types/aisearch/namespaces/instance_delete_response.py +++ b/src/cloudflare/types/aisearch/namespaces/instance_delete_response.py @@ -15,7 +15,6 @@ "IndexMethod", "IndexingOptions", "Metadata", - "MetadataSearchForAgents", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -62,19 +61,9 @@ class IndexingOptions(BaseModel): """ -class MetadataSearchForAgents(BaseModel): - hostname: str - - zone_id: str - - zone_name: str - - class Metadata(BaseModel): created_from_aisearch_wizard: Optional[bool] = None - search_for_agents: Optional[MetadataSearchForAgents] = None - worker_domain: Optional[str] = None diff --git a/src/cloudflare/types/aisearch/namespaces/instance_list_params.py b/src/cloudflare/types/aisearch/namespaces/instance_list_params.py index 7c3b1faa18a..f7191795e9b 100644 --- a/src/cloudflare/types/aisearch/namespaces/instance_list_params.py +++ b/src/cloudflare/types/aisearch/namespaces/instance_list_params.py @@ -2,7 +2,6 @@ from __future__ import annotations -from typing import Optional from typing_extensions import Literal, Required, TypedDict __all__ = ["InstanceListParams"] @@ -11,17 +10,20 @@ class InstanceListParams(TypedDict, total=False): account_id: Required[str] - namespace: Optional[str] + namespace: str + """Filter by namespace.""" order_by: Literal["created_at"] - """Order By Column Name""" + """Field to order results by.""" order_by_direction: Literal["asc", "desc"] - """Order By Direction""" + """Order direction.""" page: int + """Page number (1-indexed).""" per_page: int + """Number of results per page.""" search: str - """Search by id""" + """Filter instances whose id contains this string (case-insensitive).""" diff --git a/src/cloudflare/types/aisearch/namespaces/instance_list_response.py b/src/cloudflare/types/aisearch/namespaces/instance_list_response.py index 0b285ba0e3e..fa59d4b6eaa 100644 --- a/src/cloudflare/types/aisearch/namespaces/instance_list_response.py +++ b/src/cloudflare/types/aisearch/namespaces/instance_list_response.py @@ -15,7 +15,6 @@ "IndexMethod", "IndexingOptions", "Metadata", - "MetadataSearchForAgents", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -62,19 +61,9 @@ class IndexingOptions(BaseModel): """ -class MetadataSearchForAgents(BaseModel): - hostname: str - - zone_id: str - - zone_name: str - - class Metadata(BaseModel): created_from_aisearch_wizard: Optional[bool] = None - search_for_agents: Optional[MetadataSearchForAgents] = None - worker_domain: Optional[str] = None diff --git a/src/cloudflare/types/aisearch/namespaces/instance_read_response.py b/src/cloudflare/types/aisearch/namespaces/instance_read_response.py index 0905449fb17..bf2763a2eeb 100644 --- a/src/cloudflare/types/aisearch/namespaces/instance_read_response.py +++ b/src/cloudflare/types/aisearch/namespaces/instance_read_response.py @@ -15,7 +15,6 @@ "IndexMethod", "IndexingOptions", "Metadata", - "MetadataSearchForAgents", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -62,19 +61,9 @@ class IndexingOptions(BaseModel): """ -class MetadataSearchForAgents(BaseModel): - hostname: str - - zone_id: str - - zone_name: str - - class Metadata(BaseModel): created_from_aisearch_wizard: Optional[bool] = None - search_for_agents: Optional[MetadataSearchForAgents] = None - worker_domain: Optional[str] = None diff --git a/src/cloudflare/types/aisearch/namespaces/instance_update_params.py b/src/cloudflare/types/aisearch/namespaces/instance_update_params.py index cfd6dd5675c..0834d5ab51c 100644 --- a/src/cloudflare/types/aisearch/namespaces/instance_update_params.py +++ b/src/cloudflare/types/aisearch/namespaces/instance_update_params.py @@ -15,7 +15,6 @@ "IndexMethod", "IndexingOptions", "Metadata", - "MetadataSearchForAgents", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -251,19 +250,9 @@ class IndexingOptions(TypedDict, total=False): """ -class MetadataSearchForAgents(TypedDict, total=False): - hostname: Required[str] - - zone_id: Required[str] - - zone_name: Required[str] - - class Metadata(TypedDict, total=False): created_from_aisearch_wizard: bool - search_for_agents: MetadataSearchForAgents - worker_domain: str diff --git a/src/cloudflare/types/aisearch/namespaces/instance_update_response.py b/src/cloudflare/types/aisearch/namespaces/instance_update_response.py index 0f4e80924d1..6410208a0d7 100644 --- a/src/cloudflare/types/aisearch/namespaces/instance_update_response.py +++ b/src/cloudflare/types/aisearch/namespaces/instance_update_response.py @@ -15,7 +15,6 @@ "IndexMethod", "IndexingOptions", "Metadata", - "MetadataSearchForAgents", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -62,19 +61,9 @@ class IndexingOptions(BaseModel): """ -class MetadataSearchForAgents(BaseModel): - hostname: str - - zone_id: str - - zone_name: str - - class Metadata(BaseModel): created_from_aisearch_wizard: Optional[bool] = None - search_for_agents: Optional[MetadataSearchForAgents] = None - worker_domain: Optional[str] = None diff --git a/src/cloudflare/types/aisearch/namespaces/instances/item_create_or_update_params.py b/src/cloudflare/types/aisearch/namespaces/instances/item_create_or_update_params.py index 99ee3a5f635..237cc3acaf5 100644 --- a/src/cloudflare/types/aisearch/namespaces/instances/item_create_or_update_params.py +++ b/src/cloudflare/types/aisearch/namespaces/instances/item_create_or_update_params.py @@ -16,3 +16,12 @@ class ItemCreateOrUpdateParams(TypedDict, total=False): """Item key / filename. Must not exceed 128 characters.""" next_action: Required[Literal["INDEX"]] + + wait_for_completion: bool + """Wait for indexing to fully complete before responding. + + On RAGs with vector indexing enabled, this additionally waits for Vectorize + ingestion confirmation (up to 40s) so the returned item reflects a queryable + state. On timeout the item is returned in `running` state and the background + alarm continues polling. Defaults to false. + """ diff --git a/src/cloudflare/types/aisearch/namespaces/instances/item_sync_params.py b/src/cloudflare/types/aisearch/namespaces/instances/item_sync_params.py index 89a0585b224..6fa679fe3b6 100644 --- a/src/cloudflare/types/aisearch/namespaces/instances/item_sync_params.py +++ b/src/cloudflare/types/aisearch/namespaces/instances/item_sync_params.py @@ -16,3 +16,12 @@ class ItemSyncParams(TypedDict, total=False): """AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.""" next_action: Required[Literal["INDEX"]] + + wait_for_completion: bool + """Wait for indexing to fully complete before responding. + + On RAGs with vector indexing enabled, this additionally waits for Vectorize + ingestion confirmation (up to 40s) so the returned item reflects a queryable + state. On timeout the item is returned in `running` state and the background + alarm continues polling. Defaults to false. + """ diff --git a/src/cloudflare/types/aisearch/namespaces/instances/item_upload_params.py b/src/cloudflare/types/aisearch/namespaces/instances/item_upload_params.py index 96dd49ad951..e7caf691795 100644 --- a/src/cloudflare/types/aisearch/namespaces/instances/item_upload_params.py +++ b/src/cloudflare/types/aisearch/namespaces/instances/item_upload_params.py @@ -25,4 +25,10 @@ class File(TypedDict, total=False): """JSON string of custom metadata key-value pairs.""" wait_for_completion: bool - """Wait for indexing to complete before responding. Defaults to false.""" + """Wait for indexing to fully complete before responding. + + On RAGs with vector indexing enabled, this additionally waits for Vectorize + ingestion confirmation (up to 40s) so the returned item reflects a queryable + state. On timeout the item is returned in `running` state and the background + alarm continues polling. Defaults to false. + """ diff --git a/src/cloudflare/types/api_gateway/operation_create_response.py b/src/cloudflare/types/api_gateway/operation_create_response.py index 3ca28f40890..594a8b7ad83 100644 --- a/src/cloudflare/types/api_gateway/operation_create_response.py +++ b/src/cloudflare/types/api_gateway/operation_create_response.py @@ -1,9 +1,11 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Union, Optional +from typing import Dict, List, Union, Optional from datetime import datetime from typing_extensions import Literal, TypeAlias +from pydantic import Field as FieldInfo + from ..._models import BaseModel __all__ = [ @@ -26,6 +28,9 @@ "FeaturesAPIShieldOperationFeatureSchemaInfo", "FeaturesAPIShieldOperationFeatureSchemaInfoSchemaInfo", "FeaturesAPIShieldOperationFeatureSchemaInfoSchemaInfoActiveSchema", + "Schemas", + "SchemasLearned", + "SchemasUploaded", ] @@ -216,6 +221,50 @@ class FeaturesAPIShieldOperationFeatureSchemaInfo(BaseModel): ] +class SchemasLearned(BaseModel): + """ + An OpenAPI operation object fragment containing schema information for an operation. May include parameter definitions, request body specifications, and a component schema extension. + """ + + parameters: Optional[List[Dict[str, object]]] = None + """OpenAPI parameter objects describing path, query, header, or cookie parameters.""" + + request_body: Optional[Dict[str, object]] = FieldInfo(alias="requestBody", default=None) + """OpenAPI request body object describing the expected request payload.""" + + +class SchemasUploaded(BaseModel): + """ + An OpenAPI operation object fragment containing schema information for an operation. May include parameter definitions, request body specifications, and a component schema extension. + """ + + parameters: Optional[List[Dict[str, object]]] = None + """OpenAPI parameter objects describing path, query, header, or cookie parameters.""" + + request_body: Optional[Dict[str, object]] = FieldInfo(alias="requestBody", default=None) + """OpenAPI request body object describing the expected request payload.""" + + +class Schemas(BaseModel): + """ + OpenAPI JSON schemas for an operation, including both user-uploaded and Cloudflare-learned schemas. + """ + + learned: Optional[SchemasLearned] = None + """ + An OpenAPI operation object fragment containing schema information for an + operation. May include parameter definitions, request body specifications, and a + component schema extension. + """ + + uploaded: Optional[SchemasUploaded] = None + """ + An OpenAPI operation object fragment containing schema information for an + operation. May include parameter definitions, request body specifications, and a + component schema extension. + """ + + class OperationCreateResponse(BaseModel): endpoint: str """ @@ -237,3 +286,9 @@ class OperationCreateResponse(BaseModel): """UUID.""" features: Optional[Features] = None + + schemas: Optional[Schemas] = None + """ + OpenAPI JSON schemas for an operation, including both user-uploaded and + Cloudflare-learned schemas. + """ diff --git a/src/cloudflare/types/api_gateway/operation_get_params.py b/src/cloudflare/types/api_gateway/operation_get_params.py index 80b1e80e724..6fa124ecc14 100644 --- a/src/cloudflare/types/api_gateway/operation_get_params.py +++ b/src/cloudflare/types/api_gateway/operation_get_params.py @@ -19,3 +19,10 @@ class OperationGetParams(TypedDict, total=False): Have a look at the top-level object description for more details on the specific meaning. """ + + with_schemas: bool + """ + When true, includes OpenAPI schemas (both uploaded and learned) for the + operation in the response. Due to the conversion overhead, this parameter is + only supported on single-operation retrieval. + """ diff --git a/src/cloudflare/types/api_gateway/operation_get_response.py b/src/cloudflare/types/api_gateway/operation_get_response.py index 7c45d8d8431..d3407d93057 100644 --- a/src/cloudflare/types/api_gateway/operation_get_response.py +++ b/src/cloudflare/types/api_gateway/operation_get_response.py @@ -1,9 +1,11 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Union, Optional +from typing import Dict, List, Union, Optional from datetime import datetime from typing_extensions import Literal, TypeAlias +from pydantic import Field as FieldInfo + from ..._models import BaseModel __all__ = [ @@ -26,6 +28,9 @@ "FeaturesAPIShieldOperationFeatureSchemaInfo", "FeaturesAPIShieldOperationFeatureSchemaInfoSchemaInfo", "FeaturesAPIShieldOperationFeatureSchemaInfoSchemaInfoActiveSchema", + "Schemas", + "SchemasLearned", + "SchemasUploaded", ] @@ -216,6 +221,50 @@ class FeaturesAPIShieldOperationFeatureSchemaInfo(BaseModel): ] +class SchemasLearned(BaseModel): + """ + An OpenAPI operation object fragment containing schema information for an operation. May include parameter definitions, request body specifications, and a component schema extension. + """ + + parameters: Optional[List[Dict[str, object]]] = None + """OpenAPI parameter objects describing path, query, header, or cookie parameters.""" + + request_body: Optional[Dict[str, object]] = FieldInfo(alias="requestBody", default=None) + """OpenAPI request body object describing the expected request payload.""" + + +class SchemasUploaded(BaseModel): + """ + An OpenAPI operation object fragment containing schema information for an operation. May include parameter definitions, request body specifications, and a component schema extension. + """ + + parameters: Optional[List[Dict[str, object]]] = None + """OpenAPI parameter objects describing path, query, header, or cookie parameters.""" + + request_body: Optional[Dict[str, object]] = FieldInfo(alias="requestBody", default=None) + """OpenAPI request body object describing the expected request payload.""" + + +class Schemas(BaseModel): + """ + OpenAPI JSON schemas for an operation, including both user-uploaded and Cloudflare-learned schemas. + """ + + learned: Optional[SchemasLearned] = None + """ + An OpenAPI operation object fragment containing schema information for an + operation. May include parameter definitions, request body specifications, and a + component schema extension. + """ + + uploaded: Optional[SchemasUploaded] = None + """ + An OpenAPI operation object fragment containing schema information for an + operation. May include parameter definitions, request body specifications, and a + component schema extension. + """ + + class OperationGetResponse(BaseModel): endpoint: str """ @@ -237,3 +286,9 @@ class OperationGetResponse(BaseModel): """UUID.""" features: Optional[Features] = None + + schemas: Optional[Schemas] = None + """ + OpenAPI JSON schemas for an operation, including both user-uploaded and + Cloudflare-learned schemas. + """ diff --git a/src/cloudflare/types/botnet_feed/asn_day_report_params.py b/src/cloudflare/types/botnet_feed/asn_day_report_params.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/types/botnet_feed/asn_day_report_response.py b/src/cloudflare/types/botnet_feed/asn_day_report_response.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/types/botnet_feed/asn_full_report_response.py b/src/cloudflare/types/botnet_feed/asn_full_report_response.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/types/botnet_feed/configs/asn_delete_response.py b/src/cloudflare/types/botnet_feed/configs/asn_delete_response.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/types/botnet_feed/configs/asn_get_response.py b/src/cloudflare/types/botnet_feed/configs/asn_get_response.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/types/browser_rendering/devtools/browser/__init__.py b/src/cloudflare/types/browser_rendering/devtools/browser/__init__.py index 3bc1e83d2e4..7f66285244b 100644 --- a/src/cloudflare/types/browser_rendering/devtools/browser/__init__.py +++ b/src/cloudflare/types/browser_rendering/devtools/browser/__init__.py @@ -5,5 +5,6 @@ from .target_get_response import TargetGetResponse as TargetGetResponse from .target_create_params import TargetCreateParams as TargetCreateParams from .target_list_response import TargetListResponse as TargetListResponse +from .target_close_response import TargetCloseResponse as TargetCloseResponse from .target_create_response import TargetCreateResponse as TargetCreateResponse from .target_activate_response import TargetActivateResponse as TargetActivateResponse diff --git a/src/cloudflare/types/browser_rendering/devtools/browser/target_close_response.py b/src/cloudflare/types/browser_rendering/devtools/browser/target_close_response.py new file mode 100644 index 00000000000..db57120d7d4 --- /dev/null +++ b/src/cloudflare/types/browser_rendering/devtools/browser/target_close_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ....._models import BaseModel + +__all__ = ["TargetCloseResponse"] + + +class TargetCloseResponse(BaseModel): + message: str + """Target is closing.""" diff --git a/src/cloudflare/types/email_security/investigate/__init__.py b/src/cloudflare/types/email_security/investigate/__init__.py index a86e5ccf9aa..e694dd47b9b 100644 --- a/src/cloudflare/types/email_security/investigate/__init__.py +++ b/src/cloudflare/types/email_security/investigate/__init__.py @@ -4,7 +4,6 @@ from .move_bulk_params import MoveBulkParams as MoveBulkParams from .raw_get_response import RawGetResponse as RawGetResponse -from .trace_get_params import TraceGetParams as TraceGetParams from .move_bulk_response import MoveBulkResponse as MoveBulkResponse from .move_create_params import MoveCreateParams as MoveCreateParams from .trace_get_response import TraceGetResponse as TraceGetResponse diff --git a/src/cloudflare/types/email_security/investigate/detection_get_response.py b/src/cloudflare/types/email_security/investigate/detection_get_response.py index 444f1b45083..9d292df5162 100644 --- a/src/cloudflare/types/email_security/investigate/detection_get_response.py +++ b/src/cloudflare/types/email_security/investigate/detection_get_response.py @@ -19,8 +19,10 @@ class Attachment(BaseModel): size: int + """Size of the attachment in bytes""" content_type: Optional[str] = None + """MIME type of the attachment""" detection: Optional[ Literal[ @@ -36,10 +38,25 @@ class Attachment(BaseModel): "NONE", ] ] = None + """Detection result for this attachment""" encrypted: Optional[bool] = None + """Whether the attachment is encrypted""" + + filename: Optional[str] = None + """Name of the attached file""" + + md5: Optional[str] = None + """MD5 hash of the attachment""" name: Optional[str] = None + """Attachment name (alternative to filename)""" + + sha1: Optional[str] = None + """SHA1 hash of the attachment""" + + sha256: Optional[str] = None + """SHA256 hash of the attachment""" class Finding(BaseModel): @@ -102,7 +119,7 @@ class SenderInfo(BaseModel): class ThreatCategory(BaseModel): - id: int + id: Optional[int] = None description: Optional[str] = None @@ -124,7 +141,7 @@ class DetectionGetResponse(BaseModel): attachments: List[Attachment] - findings: List[Finding] + findings: Optional[List[Finding]] = None headers: List[Header] diff --git a/src/cloudflare/types/email_security/investigate/move_bulk_params.py b/src/cloudflare/types/email_security/investigate/move_bulk_params.py index b269132b524..35a0e5ac6d6 100644 --- a/src/cloudflare/types/email_security/investigate/move_bulk_params.py +++ b/src/cloudflare/types/email_security/investigate/move_bulk_params.py @@ -11,14 +11,17 @@ class MoveBulkParams(TypedDict, total=False): account_id: Required[str] - """Account Identifier""" + """Identifier.""" destination: Required[ Literal["Inbox", "JunkEmail", "DeletedItems", "RecoverableItemsDeletions", "RecoverableItemsPurges"] ] ids: SequenceNotStr[str] - """List of message IDs to move.""" + """List of message IDs to move""" postfix_ids: SequenceNotStr[str] - """Deprecated: Use `ids` instead. List of message IDs to move.""" + """Deprecated, use `ids` instead. + + End of life: November 1, 2026. List of message IDs to move. + """ diff --git a/src/cloudflare/types/email_security/investigate/move_bulk_response.py b/src/cloudflare/types/email_security/investigate/move_bulk_response.py index 1d660a890ae..34dec906dd2 100644 --- a/src/cloudflare/types/email_security/investigate/move_bulk_response.py +++ b/src/cloudflare/types/email_security/investigate/move_bulk_response.py @@ -9,21 +9,29 @@ class MoveBulkResponse(BaseModel): - completed_timestamp: datetime - """Deprecated, use `completed_at` instead""" - - item_count: int - success: bool + """Whether the operation succeeded""" completed_at: Optional[datetime] = None + """When the move operation completed (UTC)""" + + completed_timestamp: Optional[datetime] = None + """Deprecated, use `completed_at` instead. End of life: November 1, 2026.""" destination: Optional[str] = None + """Destination folder for the message""" + + item_count: Optional[int] = None + """Number of items moved. End of life: November 1, 2026.""" message_id: Optional[str] = None + """Message identifier""" operation: Optional[str] = None + """Type of operation performed""" recipient: Optional[str] = None + """Recipient email address""" status: Optional[str] = None + """Operation status""" diff --git a/src/cloudflare/types/email_security/investigate/move_create_params.py b/src/cloudflare/types/email_security/investigate/move_create_params.py index c4c977447e5..0e389b2ae93 100644 --- a/src/cloudflare/types/email_security/investigate/move_create_params.py +++ b/src/cloudflare/types/email_security/investigate/move_create_params.py @@ -9,14 +9,8 @@ class MoveCreateParams(TypedDict, total=False): account_id: Required[str] - """Account Identifier""" + """Identifier.""" destination: Required[ Literal["Inbox", "JunkEmail", "DeletedItems", "RecoverableItemsDeletions", "RecoverableItemsPurges"] ] - - submission: bool - """When true, search the submissions datastore only. - - When false or omitted, search the regular datastore only. - """ diff --git a/src/cloudflare/types/email_security/investigate/move_create_response.py b/src/cloudflare/types/email_security/investigate/move_create_response.py index 9dac3bddcd8..2737ff7f476 100644 --- a/src/cloudflare/types/email_security/investigate/move_create_response.py +++ b/src/cloudflare/types/email_security/investigate/move_create_response.py @@ -1,33 +1,37 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import Optional from datetime import datetime -from typing_extensions import TypeAlias from ...._models import BaseModel -__all__ = ["MoveCreateResponse", "MoveCreateResponseItem"] +__all__ = ["MoveCreateResponse"] -class MoveCreateResponseItem(BaseModel): - completed_timestamp: datetime - """Deprecated, use `completed_at` instead""" - - item_count: int - +class MoveCreateResponse(BaseModel): success: bool + """Whether the operation succeeded""" completed_at: Optional[datetime] = None + """When the move operation completed (UTC)""" + + completed_timestamp: Optional[datetime] = None + """Deprecated, use `completed_at` instead. End of life: November 1, 2026.""" destination: Optional[str] = None + """Destination folder for the message""" + + item_count: Optional[int] = None + """Number of items moved. End of life: November 1, 2026.""" message_id: Optional[str] = None + """Message identifier""" operation: Optional[str] = None + """Type of operation performed""" recipient: Optional[str] = None + """Recipient email address""" status: Optional[str] = None - - -MoveCreateResponse: TypeAlias = List[MoveCreateResponseItem] + """Operation status""" diff --git a/src/cloudflare/types/email_security/investigate/preview_create_params.py b/src/cloudflare/types/email_security/investigate/preview_create_params.py index f14b41a6449..58affde473a 100644 --- a/src/cloudflare/types/email_security/investigate/preview_create_params.py +++ b/src/cloudflare/types/email_security/investigate/preview_create_params.py @@ -9,13 +9,7 @@ class PreviewCreateParams(TypedDict, total=False): account_id: Required[str] - """Account Identifier""" + """Identifier.""" postfix_id: Required[str] - """The identifier of the message.""" - - submission: bool - """When true, search the submissions datastore only. - - When false or omitted, search the regular datastore only. - """ + """The identifier of the message""" diff --git a/src/cloudflare/types/email_security/investigate/reclassify_create_params.py b/src/cloudflare/types/email_security/investigate/reclassify_create_params.py index 9bc5a664d51..a35779781ec 100644 --- a/src/cloudflare/types/email_security/investigate/reclassify_create_params.py +++ b/src/cloudflare/types/email_security/investigate/reclassify_create_params.py @@ -9,17 +9,11 @@ class ReclassifyCreateParams(TypedDict, total=False): account_id: Required[str] - """Account Identifier""" + """Identifier.""" expected_disposition: Required[Literal["NONE", "BULK", "MALICIOUS", "SPAM", "SPOOF", "SUSPICIOUS"]] - submission: bool - """When true, search the submissions datastore only. - - When false or omitted, search the regular datastore only. - """ - eml_content: str - """Base64 encoded content of the EML file""" + """Base64 encoded content of the EML file.""" escalated_submission_id: str diff --git a/src/cloudflare/types/email_security/investigate/release_bulk_params.py b/src/cloudflare/types/email_security/investigate/release_bulk_params.py index fa6f4ef65b3..80b195efca0 100644 --- a/src/cloudflare/types/email_security/investigate/release_bulk_params.py +++ b/src/cloudflare/types/email_security/investigate/release_bulk_params.py @@ -11,7 +11,6 @@ class ReleaseBulkParams(TypedDict, total=False): account_id: Required[str] - """Account Identifier""" + """Identifier.""" body: Required[SequenceNotStr[str]] - """A list of messages identfied by their `postfix_id`s that should be released.""" diff --git a/src/cloudflare/types/email_security/investigate/release_bulk_response.py b/src/cloudflare/types/email_security/investigate/release_bulk_response.py index b766ac7b3f0..26dcb001d44 100644 --- a/src/cloudflare/types/email_security/investigate/release_bulk_response.py +++ b/src/cloudflare/types/email_security/investigate/release_bulk_response.py @@ -9,12 +9,13 @@ class ReleaseBulkResponse(BaseModel): id: str - - postfix_id: str - """The identifier of the message.""" + """Unique identifier for a message retrieved from investigation""" delivered: Optional[List[str]] = None failed: Optional[List[str]] = None + postfix_id: Optional[str] = None + """Deprecated, use `id` instead. End of life: November 1, 2026.""" + undelivered: Optional[List[str]] = None diff --git a/src/cloudflare/types/email_security/investigate/trace_get_params.py b/src/cloudflare/types/email_security/investigate/trace_get_params.py deleted file mode 100644 index d4d5cf33670..00000000000 --- a/src/cloudflare/types/email_security/investigate/trace_get_params.py +++ /dev/null @@ -1,18 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, TypedDict - -__all__ = ["TraceGetParams"] - - -class TraceGetParams(TypedDict, total=False): - account_id: Required[str] - """Account Identifier""" - - submission: bool - """When true, search the submissions datastore only. - - When false or omitted, search the regular datastore only. - """ diff --git a/src/cloudflare/types/email_security/investigate/trace_get_response.py b/src/cloudflare/types/email_security/investigate/trace_get_response.py index 98bce7e2bd2..c62405ddd96 100644 --- a/src/cloudflare/types/email_security/investigate/trace_get_response.py +++ b/src/cloudflare/types/email_security/investigate/trace_get_response.py @@ -9,11 +9,15 @@ class InboundLine(BaseModel): - lineno: int + lineno: Optional[int] = None + """Line number in the trace log""" - message: str + logged_at: Optional[datetime] = None - ts: datetime + message: Optional[str] = None + + ts: Optional[str] = None + """Deprecated, use `logged_at` instead. End of life: November 1, 2026.""" class Inbound(BaseModel): @@ -23,11 +27,15 @@ class Inbound(BaseModel): class OutboundLine(BaseModel): - lineno: int + lineno: Optional[int] = None + """Line number in the trace log""" + + logged_at: Optional[datetime] = None - message: str + message: Optional[str] = None - ts: datetime + ts: Optional[str] = None + """Deprecated, use `logged_at` instead. End of life: November 1, 2026.""" class Outbound(BaseModel): diff --git a/src/cloudflare/types/email_security/investigate_get_params.py b/src/cloudflare/types/email_security/investigate_get_params.py index 083388f1cad..bf009131acd 100644 --- a/src/cloudflare/types/email_security/investigate_get_params.py +++ b/src/cloudflare/types/email_security/investigate_get_params.py @@ -9,7 +9,7 @@ class InvestigateGetParams(TypedDict, total=False): account_id: Required[str] - """Account Identifier""" + """Identifier.""" submission: bool """When true, search the submissions datastore only. diff --git a/src/cloudflare/types/email_security/investigate_get_response.py b/src/cloudflare/types/email_security/investigate_get_response.py index 1396753de51..778fe7f2540 100644 --- a/src/cloudflare/types/email_security/investigate_get_response.py +++ b/src/cloudflare/types/email_security/investigate_get_response.py @@ -8,11 +8,41 @@ from ..._models import BaseModel -__all__ = ["InvestigateGetResponse", "Properties", "Finding", "Validation"] +__all__ = ["InvestigateGetResponse", "ActionLog", "ActionLogProperties", "Properties", "Finding", "Validation"] + + +class ActionLogProperties(BaseModel): + """Additional properties for the action""" + + folder: Optional[str] = None + """Target folder for move operations""" + + requested_by: Optional[str] = None + """User who requested the action""" + + +class ActionLog(BaseModel): + completed_at: datetime + """Timestamp when action completed""" + + operation: Literal["MOVE", "RELEASE", "RECLASSIFY", "SUBMISSION", "QUARANTINE_RELEASE", "PREVIEW"] + """Type of action performed""" + + completed_timestamp: Optional[str] = None + """Deprecated, use `completed_at` instead. End of life: November 1, 2026.""" + + properties: Optional[ActionLogProperties] = None + """Additional properties for the action""" + + status: Optional[str] = None + """Status of the action""" class Properties(BaseModel): + """Message processing properties""" + allowlisted_pattern: Optional[str] = None + """Pattern that allowlisted this message""" allowlisted_pattern_type: Optional[ Literal[ @@ -26,10 +56,13 @@ class Properties(BaseModel): "outbound_ndr", ] ] = None + """Type of allowlist pattern""" blocklisted_message: Optional[bool] = None + """Whether message was blocklisted""" blocklisted_pattern: Optional[str] = None + """Pattern that blocklisted this message""" whitelisted_pattern_type: Optional[ Literal[ @@ -43,6 +76,7 @@ class Properties(BaseModel): "outbound_ndr", ] ] = None + """Legacy field for allowlist pattern type""" class Finding(BaseModel): @@ -90,9 +124,13 @@ class Validation(BaseModel): class InvestigateGetResponse(BaseModel): id: str + """Unique identifier for a message retrieved from investigation""" + + action_log: List[ActionLog] + """Deprecated, use `GET /investigate/{investigate_id}/action_log` instead. - action_log: object - """Deprecated: use `/investigate/{id}/action_log` instead.""" + End of life: November 1, 2026. + """ client_recipients: List[str] @@ -103,12 +141,13 @@ class InvestigateGetResponse(BaseModel): is_quarantined: bool postfix_id: str - """The identifier of the message.""" + """The identifier of the message""" properties: Properties + """Message processing properties""" ts: str - """Deprecated, use `scanned_at` instead""" + """Deprecated, use `scanned_at` instead. End of life: November 1, 2026.""" alert_id: Optional[str] = None @@ -154,7 +193,11 @@ class InvestigateGetResponse(BaseModel): ] = None findings: Optional[List[Finding]] = None - """Deprecated: use `/investigate/{id}/detections` instead.""" + """ + Deprecated, use the `findings` field from + `GET /investigate/{investigate_id}/detections` instead. End of life: November + 1, 2026. Detection findings for this message. + """ from_: Optional[str] = FieldInfo(alias="from", default=None) @@ -165,17 +208,19 @@ class InvestigateGetResponse(BaseModel): message_id: Optional[str] = None post_delivery_operations: Optional[List[Literal["PREVIEW", "QUARANTINE_RELEASE", "SUBMISSION", "MOVE"]]] = None + """Post-delivery operations performed on this message""" postfix_id_outbound: Optional[str] = None replyto: Optional[str] = None scanned_at: Optional[datetime] = None + """When the message was scanned (UTC)""" sent_at: Optional[datetime] = None + """When the message was sent (UTC)""" sent_date: Optional[str] = None - """Deprecated, use `sent_at` instead""" subject: Optional[str] = None diff --git a/src/cloudflare/types/email_security/investigate_list_params.py b/src/cloudflare/types/email_security/investigate_list_params.py index 53d42d0d208..6cb7270dabb 100644 --- a/src/cloudflare/types/email_security/investigate_list_params.py +++ b/src/cloudflare/types/email_security/investigate_list_params.py @@ -13,90 +13,48 @@ class InvestigateListParams(TypedDict, total=False): account_id: Required[str] - """Account Identifier""" + """Identifier.""" action_log: bool - """Determines if the message action log is included in the response.""" + """Whether to include the message action log in the response.""" alert_id: str cursor: str detections_only: bool - """Determines if the search results will include detections or not.""" + """Whether to include only detections in search results.""" domain: str - """ - Filter by a domain found in the email: sender domain, recipient domain, or a - domain in a link. - """ + """Sender domains to filter by.""" end: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] - """The end of the search date range. Defaults to `now` if not provided.""" - - exact_subject: str - """Search for messages with an exact subject match.""" + """The end of the search date range. Defaults to `now`.""" final_disposition: Literal["MALICIOUS", "SUSPICIOUS", "SPOOF", "SPAM", "BULK", "NONE"] - """The dispositions the search filters by.""" + """Dispositions to filter by.""" - message_action: Literal["PREVIEW", "QUARANTINE_RELEASED", "MOVED", "SUBMITTED"] - """The message actions the search filters by.""" + message_action: Literal["PREVIEW", "QUARANTINE_RELEASED", "MOVED"] + """Message actions to filter by.""" message_id: str metric: str page: Optional[int] - """Deprecated: Use cursor pagination instead.""" + """Deprecated: Use cursor pagination instead. End of life: November 1, 2026.""" per_page: int """The number of results per page. Maximum value is 1000.""" query: str - """The space-delimited term used in the query. The search is case-insensitive. - - The content of the following email metadata fields are searched: - - - alert_id - - CC - - From (envelope_from) - - From Name - - final_disposition - - md5 hash (of any attachment) - - sha1 hash (of any attachment) - - sha256 hash (of any attachment) - - name (of any attachment) - - Reason - - Received DateTime (yyyy-mm-ddThh:mm:ss) - - Sent DateTime (yyyy-mm-ddThh:mm:ss) - - ReplyTo - - To (envelope_to) - - To Name - - Message-ID - - smtp_helo_server_ip - - smtp_previous_hop_ip - - x_originating_ip - - Subject - """ + """Space-delimited search term. Case-insensitive.""" recipient: str - """Filter by recipient. Matches either an email address or a domain.""" sender: str - """Filter by sender. Matches either an email address or a domain.""" start: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] - """ - The beginning of the search date range. Defaults to `now - 30 days` if not - provided. - """ + """The beginning of the search date range. Defaults to `now - 30 days`.""" subject: str - """ - Search for messages containing individual keywords in any order within the - subject. - """ - - submissions: bool - """Search for submissions instead of original messages""" diff --git a/src/cloudflare/types/email_security/investigate_list_response.py b/src/cloudflare/types/email_security/investigate_list_response.py index 12c5ae7cb75..d13d2fb80dd 100644 --- a/src/cloudflare/types/email_security/investigate_list_response.py +++ b/src/cloudflare/types/email_security/investigate_list_response.py @@ -8,11 +8,41 @@ from ..._models import BaseModel -__all__ = ["InvestigateListResponse", "Properties", "Finding", "Validation"] +__all__ = ["InvestigateListResponse", "ActionLog", "ActionLogProperties", "Properties", "Finding", "Validation"] + + +class ActionLogProperties(BaseModel): + """Additional properties for the action""" + + folder: Optional[str] = None + """Target folder for move operations""" + + requested_by: Optional[str] = None + """User who requested the action""" + + +class ActionLog(BaseModel): + completed_at: datetime + """Timestamp when action completed""" + + operation: Literal["MOVE", "RELEASE", "RECLASSIFY", "SUBMISSION", "QUARANTINE_RELEASE", "PREVIEW"] + """Type of action performed""" + + completed_timestamp: Optional[str] = None + """Deprecated, use `completed_at` instead. End of life: November 1, 2026.""" + + properties: Optional[ActionLogProperties] = None + """Additional properties for the action""" + + status: Optional[str] = None + """Status of the action""" class Properties(BaseModel): + """Message processing properties""" + allowlisted_pattern: Optional[str] = None + """Pattern that allowlisted this message""" allowlisted_pattern_type: Optional[ Literal[ @@ -26,10 +56,13 @@ class Properties(BaseModel): "outbound_ndr", ] ] = None + """Type of allowlist pattern""" blocklisted_message: Optional[bool] = None + """Whether message was blocklisted""" blocklisted_pattern: Optional[str] = None + """Pattern that blocklisted this message""" whitelisted_pattern_type: Optional[ Literal[ @@ -43,6 +76,7 @@ class Properties(BaseModel): "outbound_ndr", ] ] = None + """Legacy field for allowlist pattern type""" class Finding(BaseModel): @@ -90,9 +124,13 @@ class Validation(BaseModel): class InvestigateListResponse(BaseModel): id: str + """Unique identifier for a message retrieved from investigation""" + + action_log: List[ActionLog] + """Deprecated, use `GET /investigate/{investigate_id}/action_log` instead. - action_log: object - """Deprecated: use `/investigate/{id}/action_log` instead.""" + End of life: November 1, 2026. + """ client_recipients: List[str] @@ -103,12 +141,13 @@ class InvestigateListResponse(BaseModel): is_quarantined: bool postfix_id: str - """The identifier of the message.""" + """The identifier of the message""" properties: Properties + """Message processing properties""" ts: str - """Deprecated, use `scanned_at` instead""" + """Deprecated, use `scanned_at` instead. End of life: November 1, 2026.""" alert_id: Optional[str] = None @@ -154,7 +193,11 @@ class InvestigateListResponse(BaseModel): ] = None findings: Optional[List[Finding]] = None - """Deprecated: use `/investigate/{id}/detections` instead.""" + """ + Deprecated, use the `findings` field from + `GET /investigate/{investigate_id}/detections` instead. End of life: November + 1, 2026. Detection findings for this message. + """ from_: Optional[str] = FieldInfo(alias="from", default=None) @@ -165,17 +208,19 @@ class InvestigateListResponse(BaseModel): message_id: Optional[str] = None post_delivery_operations: Optional[List[Literal["PREVIEW", "QUARANTINE_RELEASE", "SUBMISSION", "MOVE"]]] = None + """Post-delivery operations performed on this message""" postfix_id_outbound: Optional[str] = None replyto: Optional[str] = None scanned_at: Optional[datetime] = None + """When the message was scanned (UTC)""" sent_at: Optional[datetime] = None + """When the message was sent (UTC)""" sent_date: Optional[str] = None - """Deprecated, use `sent_at` instead""" subject: Optional[str] = None diff --git a/src/cloudflare/types/email_security/phishguard/report_list_params.py b/src/cloudflare/types/email_security/phishguard/report_list_params.py index d138ab6e96c..7f8fd4a7254 100644 --- a/src/cloudflare/types/email_security/phishguard/report_list_params.py +++ b/src/cloudflare/types/email_security/phishguard/report_list_params.py @@ -13,14 +13,16 @@ class ReportListParams(TypedDict, total=False): account_id: Required[str] - """Account Identifier""" + """Identifier.""" end: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] - """The end of the search date range (RFC3339 format).""" + """End of the time range (RFC3339). Takes precedence over to_date.""" from_date: Annotated[Union[str, date], PropertyInfo(format="iso8601")] + """Deprecated, use `start` instead. Start date in YYYY-MM-DD format.""" start: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] - """The beginning of the search date range (RFC3339 format).""" + """Start of the time range (RFC3339). Takes precedence over from_date.""" to_date: Annotated[Union[str, date], PropertyInfo(format="iso8601")] + """Deprecated, use `end` instead. End date in YYYY-MM-DD format.""" diff --git a/src/cloudflare/types/email_security/phishguard/report_list_response.py b/src/cloudflare/types/email_security/phishguard/report_list_response.py index 2f8b6b21cf2..c97e9941b10 100644 --- a/src/cloudflare/types/email_security/phishguard/report_list_response.py +++ b/src/cloudflare/types/email_security/phishguard/report_list_response.py @@ -14,12 +14,15 @@ class Fields(BaseModel): to: List[str] - ts: datetime - from_: Optional[str] = FieldInfo(alias="from", default=None) + occurred_at: Optional[datetime] = None + postfix_id: Optional[str] = None + ts: Optional[datetime] = None + """Deprecated, use `occurred_at` instead""" + class Tag(BaseModel): category: str @@ -32,8 +35,6 @@ class ReportListResponse(BaseModel): content: str - created_at: datetime - disposition: Literal[ "MALICIOUS", "MALICIOUS-BEC", "SUSPICIOUS", "SPOOF", "SPAM", "BULK", "ENCRYPTED", "EXTERNAL", "UNKNOWN", "NONE" ] @@ -44,8 +45,11 @@ class ReportListResponse(BaseModel): title: str - ts: datetime - - updated_at: datetime + created_at: Optional[datetime] = None tags: Optional[List[Tag]] = None + + ts: Optional[datetime] = None + """Deprecated, use `created_at` instead""" + + updated_at: Optional[datetime] = None diff --git a/src/cloudflare/types/email_security/settings/__init__.py b/src/cloudflare/types/email_security/settings/__init__.py index 26c5fc41f06..3cdacd3f71b 100644 --- a/src/cloudflare/types/email_security/settings/__init__.py +++ b/src/cloudflare/types/email_security/settings/__init__.py @@ -22,7 +22,6 @@ from .block_sender_list_response import BlockSenderListResponse as BlockSenderListResponse from .trusted_domain_edit_params import TrustedDomainEditParams as TrustedDomainEditParams from .trusted_domain_list_params import TrustedDomainListParams as TrustedDomainListParams -from .domain_bulk_delete_response import DomainBulkDeleteResponse as DomainBulkDeleteResponse from .trusted_domain_get_response import TrustedDomainGetResponse as TrustedDomainGetResponse from .allow_policy_create_response import AllowPolicyCreateResponse as AllowPolicyCreateResponse from .allow_policy_delete_response import AllowPolicyDeleteResponse as AllowPolicyDeleteResponse diff --git a/src/cloudflare/types/email_security/settings/allow_policy_create_params.py b/src/cloudflare/types/email_security/settings/allow_policy_create_params.py index 9c0e132e1b2..fed310a2694 100644 --- a/src/cloudflare/types/email_security/settings/allow_policy_create_params.py +++ b/src/cloudflare/types/email_security/settings/allow_policy_create_params.py @@ -10,37 +10,53 @@ class AllowPolicyCreateParams(TypedDict, total=False): account_id: Required[str] - """Account Identifier""" + """Identifier.""" is_acceptable_sender: Required[bool] """ Messages from this sender will be exempted from Spam, Spoof and Bulk - dispositions. Note: This will not exempt messages with Malicious or Suspicious + dispositions. Note - This will not exempt messages with Malicious or Suspicious dispositions. """ is_exempt_recipient: Required[bool] - """Messages to this recipient will bypass all detections.""" + """Messages to this recipient will bypass all detections""" is_regex: Required[bool] is_trusted_sender: Required[bool] - """Messages from this sender will bypass all detections and link following.""" + """Messages from this sender will bypass all detections and link following""" pattern: Required[str] pattern_type: Required[Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"]] + """ + Type of pattern matching. Note: UNKNOWN is deprecated and cannot be used when + creating or updating policies, but may be returned for existing entries. + """ verify_sender: Required[bool] - """ - Enforce DMARC, SPF or DKIM authentication. When on, Email Security only honors - policies that pass authentication. + """Enforce DMARC, SPF or DKIM authentication. + + When on, Email Security only honors policies that pass authentication. """ comments: Optional[str] is_recipient: bool + """Deprecated as of July 1, 2025. + + Use `is_exempt_recipient` instead. End of life: July 1, 2026. + """ is_sender: bool + """Deprecated as of July 1, 2025. + + Use `is_trusted_sender` instead. End of life: July 1, 2026. + """ is_spoof: bool + """Deprecated as of July 1, 2025. + + Use `is_acceptable_sender` instead. End of life: July 1, 2026. + """ diff --git a/src/cloudflare/types/email_security/settings/allow_policy_create_response.py b/src/cloudflare/types/email_security/settings/allow_policy_create_response.py index 312ff7e2a7c..de5da6c4541 100644 --- a/src/cloudflare/types/email_security/settings/allow_policy_create_response.py +++ b/src/cloudflare/types/email_security/settings/allow_policy_create_response.py @@ -10,42 +10,63 @@ class AllowPolicyCreateResponse(BaseModel): - id: int - """The unique identifier for the allow policy.""" + """An email allow policy""" + + id: str + """Allow policy identifier""" created_at: datetime - is_acceptable_sender: bool + last_modified: datetime + """Deprecated, use `modified_at` instead. End of life: November 1, 2026.""" + + comments: Optional[str] = None + + is_acceptable_sender: Optional[bool] = None """ Messages from this sender will be exempted from Spam, Spoof and Bulk - dispositions. Note: This will not exempt messages with Malicious or Suspicious + dispositions. Note - This will not exempt messages with Malicious or Suspicious dispositions. """ - is_exempt_recipient: bool - """Messages to this recipient will bypass all detections.""" - - is_regex: bool + is_exempt_recipient: Optional[bool] = None + """Messages to this recipient will bypass all detections""" - is_trusted_sender: bool - """Messages from this sender will bypass all detections and link following.""" + is_recipient: Optional[bool] = None + """Deprecated as of July 1, 2025. - last_modified: datetime + Use `is_exempt_recipient` instead. End of life: July 1, 2026. + """ - pattern: str + is_regex: Optional[bool] = None - pattern_type: Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"] + is_sender: Optional[bool] = None + """Deprecated as of July 1, 2025. - verify_sender: bool + Use `is_trusted_sender` instead. End of life: July 1, 2026. """ - Enforce DMARC, SPF or DKIM authentication. When on, Email Security only honors - policies that pass authentication. + + is_spoof: Optional[bool] = None + """Deprecated as of July 1, 2025. + + Use `is_acceptable_sender` instead. End of life: July 1, 2026. """ - comments: Optional[str] = None + is_trusted_sender: Optional[bool] = None + """Messages from this sender will bypass all detections and link following""" - is_recipient: Optional[bool] = None + modified_at: Optional[datetime] = None - is_sender: Optional[bool] = None + pattern: Optional[str] = None - is_spoof: Optional[bool] = None + pattern_type: Optional[Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"]] = None + """ + Type of pattern matching. Note: UNKNOWN is deprecated and cannot be used when + creating or updating policies, but may be returned for existing entries. + """ + + verify_sender: Optional[bool] = None + """Enforce DMARC, SPF or DKIM authentication. + + When on, Email Security only honors policies that pass authentication. + """ diff --git a/src/cloudflare/types/email_security/settings/allow_policy_delete_response.py b/src/cloudflare/types/email_security/settings/allow_policy_delete_response.py index 38627fc0c30..d46f059d358 100644 --- a/src/cloudflare/types/email_security/settings/allow_policy_delete_response.py +++ b/src/cloudflare/types/email_security/settings/allow_policy_delete_response.py @@ -6,5 +6,5 @@ class AllowPolicyDeleteResponse(BaseModel): - id: int - """The unique identifier for the allow policy.""" + id: str + """Allow policy identifier""" diff --git a/src/cloudflare/types/email_security/settings/allow_policy_edit_params.py b/src/cloudflare/types/email_security/settings/allow_policy_edit_params.py index 6b4de29a3bb..b9d37e6e6f5 100644 --- a/src/cloudflare/types/email_security/settings/allow_policy_edit_params.py +++ b/src/cloudflare/types/email_security/settings/allow_policy_edit_params.py @@ -10,31 +10,53 @@ class AllowPolicyEditParams(TypedDict, total=False): account_id: Required[str] - """Account Identifier""" + """Identifier.""" comments: Optional[str] - is_acceptable_sender: Optional[bool] + is_acceptable_sender: bool """ Messages from this sender will be exempted from Spam, Spoof and Bulk - dispositions. Note: This will not exempt messages with Malicious or Suspicious + dispositions. Note - This will not exempt messages with Malicious or Suspicious dispositions. """ - is_exempt_recipient: Optional[bool] - """Messages to this recipient will bypass all detections.""" + is_exempt_recipient: bool + """Messages to this recipient will bypass all detections""" - is_regex: Optional[bool] + is_recipient: bool + """Deprecated as of July 1, 2025. - is_trusted_sender: Optional[bool] - """Messages from this sender will bypass all detections and link following.""" + Use `is_exempt_recipient` instead. End of life: July 1, 2026. + """ + + is_regex: bool + + is_sender: bool + """Deprecated as of July 1, 2025. - pattern: Optional[str] + Use `is_trusted_sender` instead. End of life: July 1, 2026. + """ - pattern_type: Optional[Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"]] + is_spoof: bool + """Deprecated as of July 1, 2025. - verify_sender: Optional[bool] + Use `is_acceptable_sender` instead. End of life: July 1, 2026. """ - Enforce DMARC, SPF or DKIM authentication. When on, Email Security only honors - policies that pass authentication. + + is_trusted_sender: bool + """Messages from this sender will bypass all detections and link following""" + + pattern: str + + pattern_type: Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"] + """ + Type of pattern matching. Note: UNKNOWN is deprecated and cannot be used when + creating or updating policies, but may be returned for existing entries. + """ + + verify_sender: bool + """Enforce DMARC, SPF or DKIM authentication. + + When on, Email Security only honors policies that pass authentication. """ diff --git a/src/cloudflare/types/email_security/settings/allow_policy_edit_response.py b/src/cloudflare/types/email_security/settings/allow_policy_edit_response.py index eb66126b593..ed1743f4f0a 100644 --- a/src/cloudflare/types/email_security/settings/allow_policy_edit_response.py +++ b/src/cloudflare/types/email_security/settings/allow_policy_edit_response.py @@ -10,42 +10,63 @@ class AllowPolicyEditResponse(BaseModel): - id: int - """The unique identifier for the allow policy.""" + """An email allow policy""" + + id: str + """Allow policy identifier""" created_at: datetime - is_acceptable_sender: bool + last_modified: datetime + """Deprecated, use `modified_at` instead. End of life: November 1, 2026.""" + + comments: Optional[str] = None + + is_acceptable_sender: Optional[bool] = None """ Messages from this sender will be exempted from Spam, Spoof and Bulk - dispositions. Note: This will not exempt messages with Malicious or Suspicious + dispositions. Note - This will not exempt messages with Malicious or Suspicious dispositions. """ - is_exempt_recipient: bool - """Messages to this recipient will bypass all detections.""" - - is_regex: bool + is_exempt_recipient: Optional[bool] = None + """Messages to this recipient will bypass all detections""" - is_trusted_sender: bool - """Messages from this sender will bypass all detections and link following.""" + is_recipient: Optional[bool] = None + """Deprecated as of July 1, 2025. - last_modified: datetime + Use `is_exempt_recipient` instead. End of life: July 1, 2026. + """ - pattern: str + is_regex: Optional[bool] = None - pattern_type: Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"] + is_sender: Optional[bool] = None + """Deprecated as of July 1, 2025. - verify_sender: bool + Use `is_trusted_sender` instead. End of life: July 1, 2026. """ - Enforce DMARC, SPF or DKIM authentication. When on, Email Security only honors - policies that pass authentication. + + is_spoof: Optional[bool] = None + """Deprecated as of July 1, 2025. + + Use `is_acceptable_sender` instead. End of life: July 1, 2026. """ - comments: Optional[str] = None + is_trusted_sender: Optional[bool] = None + """Messages from this sender will bypass all detections and link following""" - is_recipient: Optional[bool] = None + modified_at: Optional[datetime] = None - is_sender: Optional[bool] = None + pattern: Optional[str] = None - is_spoof: Optional[bool] = None + pattern_type: Optional[Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"]] = None + """ + Type of pattern matching. Note: UNKNOWN is deprecated and cannot be used when + creating or updating policies, but may be returned for existing entries. + """ + + verify_sender: Optional[bool] = None + """Enforce DMARC, SPF or DKIM authentication. + + When on, Email Security only honors policies that pass authentication. + """ diff --git a/src/cloudflare/types/email_security/settings/allow_policy_get_response.py b/src/cloudflare/types/email_security/settings/allow_policy_get_response.py index e9cb0384cf3..c2cb6e12603 100644 --- a/src/cloudflare/types/email_security/settings/allow_policy_get_response.py +++ b/src/cloudflare/types/email_security/settings/allow_policy_get_response.py @@ -10,42 +10,63 @@ class AllowPolicyGetResponse(BaseModel): - id: int - """The unique identifier for the allow policy.""" + """An email allow policy""" + + id: str + """Allow policy identifier""" created_at: datetime - is_acceptable_sender: bool + last_modified: datetime + """Deprecated, use `modified_at` instead. End of life: November 1, 2026.""" + + comments: Optional[str] = None + + is_acceptable_sender: Optional[bool] = None """ Messages from this sender will be exempted from Spam, Spoof and Bulk - dispositions. Note: This will not exempt messages with Malicious or Suspicious + dispositions. Note - This will not exempt messages with Malicious or Suspicious dispositions. """ - is_exempt_recipient: bool - """Messages to this recipient will bypass all detections.""" - - is_regex: bool + is_exempt_recipient: Optional[bool] = None + """Messages to this recipient will bypass all detections""" - is_trusted_sender: bool - """Messages from this sender will bypass all detections and link following.""" + is_recipient: Optional[bool] = None + """Deprecated as of July 1, 2025. - last_modified: datetime + Use `is_exempt_recipient` instead. End of life: July 1, 2026. + """ - pattern: str + is_regex: Optional[bool] = None - pattern_type: Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"] + is_sender: Optional[bool] = None + """Deprecated as of July 1, 2025. - verify_sender: bool + Use `is_trusted_sender` instead. End of life: July 1, 2026. """ - Enforce DMARC, SPF or DKIM authentication. When on, Email Security only honors - policies that pass authentication. + + is_spoof: Optional[bool] = None + """Deprecated as of July 1, 2025. + + Use `is_acceptable_sender` instead. End of life: July 1, 2026. """ - comments: Optional[str] = None + is_trusted_sender: Optional[bool] = None + """Messages from this sender will bypass all detections and link following""" - is_recipient: Optional[bool] = None + modified_at: Optional[datetime] = None - is_sender: Optional[bool] = None + pattern: Optional[str] = None - is_spoof: Optional[bool] = None + pattern_type: Optional[Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"]] = None + """ + Type of pattern matching. Note: UNKNOWN is deprecated and cannot be used when + creating or updating policies, but may be returned for existing entries. + """ + + verify_sender: Optional[bool] = None + """Enforce DMARC, SPF or DKIM authentication. + + When on, Email Security only honors policies that pass authentication. + """ diff --git a/src/cloudflare/types/email_security/settings/allow_policy_list_params.py b/src/cloudflare/types/email_security/settings/allow_policy_list_params.py index 85380271064..5c57fcb71a4 100644 --- a/src/cloudflare/types/email_security/settings/allow_policy_list_params.py +++ b/src/cloudflare/types/email_security/settings/allow_policy_list_params.py @@ -9,41 +9,48 @@ class AllowPolicyListParams(TypedDict, total=False): account_id: Required[str] - """Account Identifier""" + """Identifier.""" direction: Literal["asc", "desc"] """The sorting direction.""" is_acceptable_sender: bool + """ + Filter to show only policies where messages from the sender are exempted from + Spam, Spoof, and Bulk dispositions (not Malicious or Suspicious). + """ is_exempt_recipient: bool - - is_recipient: bool - - is_sender: bool - - is_spoof: bool + """ + Filter to show only policies where messages to the recipient bypass all + detections. + """ is_trusted_sender: bool + """ + Filter to show only policies where messages from the sender bypass all + detections and link following. + """ order: Literal["pattern", "created_at"] - """The field to sort by.""" + """Field to sort by.""" page: int - """The page number of paginated results.""" + """Current page within paginated list of results.""" pattern: str pattern_type: Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"] + """ + Type of pattern matching. Note: UNKNOWN is deprecated and cannot be used when + creating or updating policies, but may be returned for existing entries. + """ per_page: int - """The number of results per page.""" + """The number of results per page. Maximum value is 1000.""" search: str - """ - Allows searching in multiple properties of a record simultaneously. This - parameter is intended for human users, not automation. Its exact behavior is - intentionally left unspecified and is subject to change in the future. - """ + """Search term for filtering records. Behavior may change.""" verify_sender: bool + """Filter to show only policies that enforce DMARC, SPF, or DKIM authentication.""" diff --git a/src/cloudflare/types/email_security/settings/allow_policy_list_response.py b/src/cloudflare/types/email_security/settings/allow_policy_list_response.py index 9b4c57f2a22..9e77c75eccc 100644 --- a/src/cloudflare/types/email_security/settings/allow_policy_list_response.py +++ b/src/cloudflare/types/email_security/settings/allow_policy_list_response.py @@ -10,42 +10,63 @@ class AllowPolicyListResponse(BaseModel): - id: int - """The unique identifier for the allow policy.""" + """An email allow policy""" + + id: str + """Allow policy identifier""" created_at: datetime - is_acceptable_sender: bool + last_modified: datetime + """Deprecated, use `modified_at` instead. End of life: November 1, 2026.""" + + comments: Optional[str] = None + + is_acceptable_sender: Optional[bool] = None """ Messages from this sender will be exempted from Spam, Spoof and Bulk - dispositions. Note: This will not exempt messages with Malicious or Suspicious + dispositions. Note - This will not exempt messages with Malicious or Suspicious dispositions. """ - is_exempt_recipient: bool - """Messages to this recipient will bypass all detections.""" - - is_regex: bool + is_exempt_recipient: Optional[bool] = None + """Messages to this recipient will bypass all detections""" - is_trusted_sender: bool - """Messages from this sender will bypass all detections and link following.""" + is_recipient: Optional[bool] = None + """Deprecated as of July 1, 2025. - last_modified: datetime + Use `is_exempt_recipient` instead. End of life: July 1, 2026. + """ - pattern: str + is_regex: Optional[bool] = None - pattern_type: Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"] + is_sender: Optional[bool] = None + """Deprecated as of July 1, 2025. - verify_sender: bool + Use `is_trusted_sender` instead. End of life: July 1, 2026. """ - Enforce DMARC, SPF or DKIM authentication. When on, Email Security only honors - policies that pass authentication. + + is_spoof: Optional[bool] = None + """Deprecated as of July 1, 2025. + + Use `is_acceptable_sender` instead. End of life: July 1, 2026. """ - comments: Optional[str] = None + is_trusted_sender: Optional[bool] = None + """Messages from this sender will bypass all detections and link following""" - is_recipient: Optional[bool] = None + modified_at: Optional[datetime] = None - is_sender: Optional[bool] = None + pattern: Optional[str] = None - is_spoof: Optional[bool] = None + pattern_type: Optional[Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"]] = None + """ + Type of pattern matching. Note: UNKNOWN is deprecated and cannot be used when + creating or updating policies, but may be returned for existing entries. + """ + + verify_sender: Optional[bool] = None + """Enforce DMARC, SPF or DKIM authentication. + + When on, Email Security only honors policies that pass authentication. + """ diff --git a/src/cloudflare/types/email_security/settings/block_sender_create_params.py b/src/cloudflare/types/email_security/settings/block_sender_create_params.py index dc5290d600f..7b1c5b3a3d0 100644 --- a/src/cloudflare/types/email_security/settings/block_sender_create_params.py +++ b/src/cloudflare/types/email_security/settings/block_sender_create_params.py @@ -10,12 +10,16 @@ class BlockSenderCreateParams(TypedDict, total=False): account_id: Required[str] - """Account Identifier""" + """Identifier.""" is_regex: Required[bool] pattern: Required[str] pattern_type: Required[Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"]] + """ + Type of pattern matching. Note: UNKNOWN is deprecated and cannot be used when + creating or updating policies, but may be returned for existing entries. + """ comments: Optional[str] diff --git a/src/cloudflare/types/email_security/settings/block_sender_create_response.py b/src/cloudflare/types/email_security/settings/block_sender_create_response.py index 615755f8fd7..b3b0d507355 100644 --- a/src/cloudflare/types/email_security/settings/block_sender_create_response.py +++ b/src/cloudflare/types/email_security/settings/block_sender_create_response.py @@ -10,17 +10,26 @@ class BlockSenderCreateResponse(BaseModel): - id: int - """The unique identifier for the allow policy.""" + """A blocked sender pattern""" - created_at: datetime + id: Optional[str] = None + """Blocked sender pattern identifier""" - is_regex: bool + comments: Optional[str] = None - last_modified: datetime + created_at: Optional[datetime] = None - pattern: str + is_regex: Optional[bool] = None - pattern_type: Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"] + last_modified: Optional[datetime] = None + """Deprecated, use `modified_at` instead. End of life: November 1, 2026.""" - comments: Optional[str] = None + modified_at: Optional[datetime] = None + + pattern: Optional[str] = None + + pattern_type: Optional[Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"]] = None + """ + Type of pattern matching. Note: UNKNOWN is deprecated and cannot be used when + creating or updating policies, but may be returned for existing entries. + """ diff --git a/src/cloudflare/types/email_security/settings/block_sender_delete_response.py b/src/cloudflare/types/email_security/settings/block_sender_delete_response.py index ea8337060bf..cf2927b2847 100644 --- a/src/cloudflare/types/email_security/settings/block_sender_delete_response.py +++ b/src/cloudflare/types/email_security/settings/block_sender_delete_response.py @@ -6,5 +6,5 @@ class BlockSenderDeleteResponse(BaseModel): - id: int - """The unique identifier for the allow policy.""" + id: str + """Blocked sender pattern identifier""" diff --git a/src/cloudflare/types/email_security/settings/block_sender_edit_params.py b/src/cloudflare/types/email_security/settings/block_sender_edit_params.py index 19f2d23458a..756f0a1e79e 100644 --- a/src/cloudflare/types/email_security/settings/block_sender_edit_params.py +++ b/src/cloudflare/types/email_security/settings/block_sender_edit_params.py @@ -10,12 +10,16 @@ class BlockSenderEditParams(TypedDict, total=False): account_id: Required[str] - """Account Identifier""" + """Identifier.""" comments: Optional[str] - is_regex: Optional[bool] + is_regex: bool - pattern: Optional[str] + pattern: str - pattern_type: Optional[Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"]] + pattern_type: Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"] + """ + Type of pattern matching. Note: UNKNOWN is deprecated and cannot be used when + creating or updating policies, but may be returned for existing entries. + """ diff --git a/src/cloudflare/types/email_security/settings/block_sender_edit_response.py b/src/cloudflare/types/email_security/settings/block_sender_edit_response.py index 764d9fd5dee..0ade492c40b 100644 --- a/src/cloudflare/types/email_security/settings/block_sender_edit_response.py +++ b/src/cloudflare/types/email_security/settings/block_sender_edit_response.py @@ -10,17 +10,26 @@ class BlockSenderEditResponse(BaseModel): - id: int - """The unique identifier for the allow policy.""" + """A blocked sender pattern""" - created_at: datetime + id: Optional[str] = None + """Blocked sender pattern identifier""" - is_regex: bool + comments: Optional[str] = None - last_modified: datetime + created_at: Optional[datetime] = None - pattern: str + is_regex: Optional[bool] = None - pattern_type: Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"] + last_modified: Optional[datetime] = None + """Deprecated, use `modified_at` instead. End of life: November 1, 2026.""" - comments: Optional[str] = None + modified_at: Optional[datetime] = None + + pattern: Optional[str] = None + + pattern_type: Optional[Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"]] = None + """ + Type of pattern matching. Note: UNKNOWN is deprecated and cannot be used when + creating or updating policies, but may be returned for existing entries. + """ diff --git a/src/cloudflare/types/email_security/settings/block_sender_get_response.py b/src/cloudflare/types/email_security/settings/block_sender_get_response.py index 66f03f3e3f6..9a513f36a76 100644 --- a/src/cloudflare/types/email_security/settings/block_sender_get_response.py +++ b/src/cloudflare/types/email_security/settings/block_sender_get_response.py @@ -10,17 +10,26 @@ class BlockSenderGetResponse(BaseModel): - id: int - """The unique identifier for the allow policy.""" + """A blocked sender pattern""" - created_at: datetime + id: Optional[str] = None + """Blocked sender pattern identifier""" - is_regex: bool + comments: Optional[str] = None - last_modified: datetime + created_at: Optional[datetime] = None - pattern: str + is_regex: Optional[bool] = None - pattern_type: Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"] + last_modified: Optional[datetime] = None + """Deprecated, use `modified_at` instead. End of life: November 1, 2026.""" - comments: Optional[str] = None + modified_at: Optional[datetime] = None + + pattern: Optional[str] = None + + pattern_type: Optional[Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"]] = None + """ + Type of pattern matching. Note: UNKNOWN is deprecated and cannot be used when + creating or updating policies, but may be returned for existing entries. + """ diff --git a/src/cloudflare/types/email_security/settings/block_sender_list_params.py b/src/cloudflare/types/email_security/settings/block_sender_list_params.py index 712ad5932dd..9c1fe7b8850 100644 --- a/src/cloudflare/types/email_security/settings/block_sender_list_params.py +++ b/src/cloudflare/types/email_security/settings/block_sender_list_params.py @@ -9,27 +9,25 @@ class BlockSenderListParams(TypedDict, total=False): account_id: Required[str] - """Account Identifier""" + """Identifier.""" direction: Literal["asc", "desc"] """The sorting direction.""" order: Literal["pattern", "created_at"] - """The field to sort by.""" + """Field to sort by.""" page: int - """The page number of paginated results.""" + """Current page within paginated list of results.""" pattern: str + """Filter by pattern value.""" pattern_type: Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"] + """Filter by pattern type.""" per_page: int - """The number of results per page.""" + """The number of results per page. Maximum value is 1000.""" search: str - """ - Allows searching in multiple properties of a record simultaneously. This - parameter is intended for human users, not automation. Its exact behavior is - intentionally left unspecified and is subject to change in the future. - """ + """Search term for filtering records. Behavior may change.""" diff --git a/src/cloudflare/types/email_security/settings/block_sender_list_response.py b/src/cloudflare/types/email_security/settings/block_sender_list_response.py index 497ae4dc93d..10587592feb 100644 --- a/src/cloudflare/types/email_security/settings/block_sender_list_response.py +++ b/src/cloudflare/types/email_security/settings/block_sender_list_response.py @@ -10,17 +10,26 @@ class BlockSenderListResponse(BaseModel): - id: int - """The unique identifier for the allow policy.""" + """A blocked sender pattern""" - created_at: datetime + id: Optional[str] = None + """Blocked sender pattern identifier""" - is_regex: bool + comments: Optional[str] = None - last_modified: datetime + created_at: Optional[datetime] = None - pattern: str + is_regex: Optional[bool] = None - pattern_type: Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"] + last_modified: Optional[datetime] = None + """Deprecated, use `modified_at` instead. End of life: November 1, 2026.""" - comments: Optional[str] = None + modified_at: Optional[datetime] = None + + pattern: Optional[str] = None + + pattern_type: Optional[Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"]] = None + """ + Type of pattern matching. Note: UNKNOWN is deprecated and cannot be used when + creating or updating policies, but may be returned for existing entries. + """ diff --git a/src/cloudflare/types/email_security/settings/domain_bulk_delete_response.py b/src/cloudflare/types/email_security/settings/domain_bulk_delete_response.py deleted file mode 100644 index 76cb04b1987..00000000000 --- a/src/cloudflare/types/email_security/settings/domain_bulk_delete_response.py +++ /dev/null @@ -1,10 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from ...._models import BaseModel - -__all__ = ["DomainBulkDeleteResponse"] - - -class DomainBulkDeleteResponse(BaseModel): - id: int - """The unique identifier for the domain.""" diff --git a/src/cloudflare/types/email_security/settings/domain_delete_response.py b/src/cloudflare/types/email_security/settings/domain_delete_response.py index ab5ea3c8842..13a307fe1e9 100644 --- a/src/cloudflare/types/email_security/settings/domain_delete_response.py +++ b/src/cloudflare/types/email_security/settings/domain_delete_response.py @@ -6,5 +6,5 @@ class DomainDeleteResponse(BaseModel): - id: int - """The unique identifier for the domain.""" + id: str + """Domain identifier""" diff --git a/src/cloudflare/types/email_security/settings/domain_edit_params.py b/src/cloudflare/types/email_security/settings/domain_edit_params.py index bf6dec63309..f05612d8726 100644 --- a/src/cloudflare/types/email_security/settings/domain_edit_params.py +++ b/src/cloudflare/types/email_security/settings/domain_edit_params.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import List +from typing import List, Optional from typing_extensions import Literal, Required, TypedDict from ...._types import SequenceNotStr @@ -12,9 +12,7 @@ class DomainEditParams(TypedDict, total=False): account_id: Required[str] - """Account Identifier""" - - ip_restrictions: Required[SequenceNotStr[str]] + """Identifier.""" allowed_delivery_modes: List[Literal["DIRECT", "BCC", "JOURNAL", "API", "RETRO_SCAN"]] @@ -37,7 +35,9 @@ class DomainEditParams(TypedDict, total=False): folder: Literal["AllItems", "Inbox"] - integration_id: str + integration_id: Optional[str] + + ip_restrictions: SequenceNotStr[str] lookback_hops: int diff --git a/src/cloudflare/types/email_security/settings/domain_edit_response.py b/src/cloudflare/types/email_security/settings/domain_edit_response.py index 341b48ed16d..60f594792bb 100644 --- a/src/cloudflare/types/email_security/settings/domain_edit_response.py +++ b/src/cloudflare/types/email_security/settings/domain_edit_response.py @@ -26,44 +26,36 @@ class EmailsProcessed(BaseModel): class DomainEditResponse(BaseModel): - id: int - """The unique identifier for the domain.""" - - allowed_delivery_modes: List[Literal["DIRECT", "BCC", "JOURNAL", "API", "RETRO_SCAN"]] - - created_at: datetime - - domain: str - - drop_dispositions: List[ - Literal[ - "MALICIOUS", - "MALICIOUS-BEC", - "SUSPICIOUS", - "SPOOF", - "SPAM", - "BULK", - "ENCRYPTED", - "EXTERNAL", - "UNKNOWN", - "NONE", - ] - ] - - ip_restrictions: List[str] - - last_modified: datetime - - lookback_hops: int + id: Optional[str] = None + """Domain identifier""" - regions: List[Literal["GLOBAL", "AU", "DE", "IN", "US"]] - - transport: str + allowed_delivery_modes: Optional[List[Literal["DIRECT", "BCC", "JOURNAL", "API", "RETRO_SCAN"]]] = None authorization: Optional[Authorization] = None + created_at: Optional[datetime] = None + dmarc_status: Optional[Literal["none", "good", "invalid"]] = None + domain: Optional[str] = None + + drop_dispositions: Optional[ + List[ + Literal[ + "MALICIOUS", + "MALICIOUS-BEC", + "SUSPICIOUS", + "SPOOF", + "SPAM", + "BULK", + "ENCRYPTED", + "EXTERNAL", + "UNKNOWN", + "NONE", + ] + ] + ] = None + emails_processed: Optional[EmailsProcessed] = None folder: Optional[Literal["AllItems", "Inbox"]] = None @@ -72,10 +64,25 @@ class DomainEditResponse(BaseModel): integration_id: Optional[str] = None + ip_restrictions: Optional[List[str]] = None + + last_modified: Optional[datetime] = None + """Deprecated, use `modified_at` instead. End of life: November 1, 2026.""" + + lookback_hops: Optional[int] = None + + modified_at: Optional[datetime] = None + o365_tenant_id: Optional[str] = None + regions: Optional[List[Literal["GLOBAL", "AU", "DE", "IN", "US"]]] = None + require_tls_inbound: Optional[bool] = None require_tls_outbound: Optional[bool] = None spf_status: Optional[Literal["none", "good", "neutral", "open", "invalid"]] = None + + status: Optional[Literal["pending", "active", "failed", "timeout"]] = None + + transport: Optional[str] = None diff --git a/src/cloudflare/types/email_security/settings/domain_get_response.py b/src/cloudflare/types/email_security/settings/domain_get_response.py index 08557681736..d175d364946 100644 --- a/src/cloudflare/types/email_security/settings/domain_get_response.py +++ b/src/cloudflare/types/email_security/settings/domain_get_response.py @@ -26,44 +26,36 @@ class EmailsProcessed(BaseModel): class DomainGetResponse(BaseModel): - id: int - """The unique identifier for the domain.""" - - allowed_delivery_modes: List[Literal["DIRECT", "BCC", "JOURNAL", "API", "RETRO_SCAN"]] - - created_at: datetime - - domain: str - - drop_dispositions: List[ - Literal[ - "MALICIOUS", - "MALICIOUS-BEC", - "SUSPICIOUS", - "SPOOF", - "SPAM", - "BULK", - "ENCRYPTED", - "EXTERNAL", - "UNKNOWN", - "NONE", - ] - ] - - ip_restrictions: List[str] - - last_modified: datetime - - lookback_hops: int + id: Optional[str] = None + """Domain identifier""" - regions: List[Literal["GLOBAL", "AU", "DE", "IN", "US"]] - - transport: str + allowed_delivery_modes: Optional[List[Literal["DIRECT", "BCC", "JOURNAL", "API", "RETRO_SCAN"]]] = None authorization: Optional[Authorization] = None + created_at: Optional[datetime] = None + dmarc_status: Optional[Literal["none", "good", "invalid"]] = None + domain: Optional[str] = None + + drop_dispositions: Optional[ + List[ + Literal[ + "MALICIOUS", + "MALICIOUS-BEC", + "SUSPICIOUS", + "SPOOF", + "SPAM", + "BULK", + "ENCRYPTED", + "EXTERNAL", + "UNKNOWN", + "NONE", + ] + ] + ] = None + emails_processed: Optional[EmailsProcessed] = None folder: Optional[Literal["AllItems", "Inbox"]] = None @@ -72,10 +64,25 @@ class DomainGetResponse(BaseModel): integration_id: Optional[str] = None + ip_restrictions: Optional[List[str]] = None + + last_modified: Optional[datetime] = None + """Deprecated, use `modified_at` instead. End of life: November 1, 2026.""" + + lookback_hops: Optional[int] = None + + modified_at: Optional[datetime] = None + o365_tenant_id: Optional[str] = None + regions: Optional[List[Literal["GLOBAL", "AU", "DE", "IN", "US"]]] = None + require_tls_inbound: Optional[bool] = None require_tls_outbound: Optional[bool] = None spf_status: Optional[Literal["none", "good", "neutral", "open", "invalid"]] = None + + status: Optional[Literal["pending", "active", "failed", "timeout"]] = None + + transport: Optional[str] = None diff --git a/src/cloudflare/types/email_security/settings/domain_list_params.py b/src/cloudflare/types/email_security/settings/domain_list_params.py index 6546a419a74..cccbbee8649 100644 --- a/src/cloudflare/types/email_security/settings/domain_list_params.py +++ b/src/cloudflare/types/email_security/settings/domain_list_params.py @@ -11,35 +11,34 @@ class DomainListParams(TypedDict, total=False): account_id: Required[str] - """Account Identifier""" + """Identifier.""" active_delivery_mode: Literal["DIRECT", "BCC", "JOURNAL", "API", "RETRO_SCAN"] - """Filters response to domains with the currently active delivery mode.""" + """Currently active delivery mode to filter by.""" allowed_delivery_mode: Literal["DIRECT", "BCC", "JOURNAL", "API", "RETRO_SCAN"] - """Filters response to domains with the provided delivery mode.""" + """Delivery mode to filter by.""" direction: Literal["asc", "desc"] """The sorting direction.""" domain: SequenceNotStr[str] - """Filters results by the provided domains, allowing for multiple occurrences.""" + """Domain names to filter by.""" integration_id: str - """Filters response to domains with the provided integration ID.""" + """Integration ID to filter by.""" order: Literal["domain", "created_at"] - """The field to sort by.""" + """Field to sort by.""" page: int - """The page number of paginated results.""" + """Current page within paginated list of results.""" per_page: int - """The number of results per page.""" + """The number of results per page. Maximum value is 1000.""" search: str - """ - Allows searching in multiple properties of a record simultaneously. This - parameter is intended for human users, not automation. Its exact behavior is - intentionally left unspecified and is subject to change in the future. - """ + """Search term for filtering records. Behavior may change.""" + + status: Literal["pending", "active", "failed", "timeout"] + """Filters response to domains with the provided status.""" diff --git a/src/cloudflare/types/email_security/settings/domain_list_response.py b/src/cloudflare/types/email_security/settings/domain_list_response.py index eec5a9fcc9c..cca762dcd41 100644 --- a/src/cloudflare/types/email_security/settings/domain_list_response.py +++ b/src/cloudflare/types/email_security/settings/domain_list_response.py @@ -26,44 +26,36 @@ class EmailsProcessed(BaseModel): class DomainListResponse(BaseModel): - id: int - """The unique identifier for the domain.""" - - allowed_delivery_modes: List[Literal["DIRECT", "BCC", "JOURNAL", "API", "RETRO_SCAN"]] - - created_at: datetime - - domain: str - - drop_dispositions: List[ - Literal[ - "MALICIOUS", - "MALICIOUS-BEC", - "SUSPICIOUS", - "SPOOF", - "SPAM", - "BULK", - "ENCRYPTED", - "EXTERNAL", - "UNKNOWN", - "NONE", - ] - ] - - ip_restrictions: List[str] - - last_modified: datetime - - lookback_hops: int + id: Optional[str] = None + """Domain identifier""" - regions: List[Literal["GLOBAL", "AU", "DE", "IN", "US"]] - - transport: str + allowed_delivery_modes: Optional[List[Literal["DIRECT", "BCC", "JOURNAL", "API", "RETRO_SCAN"]]] = None authorization: Optional[Authorization] = None + created_at: Optional[datetime] = None + dmarc_status: Optional[Literal["none", "good", "invalid"]] = None + domain: Optional[str] = None + + drop_dispositions: Optional[ + List[ + Literal[ + "MALICIOUS", + "MALICIOUS-BEC", + "SUSPICIOUS", + "SPOOF", + "SPAM", + "BULK", + "ENCRYPTED", + "EXTERNAL", + "UNKNOWN", + "NONE", + ] + ] + ] = None + emails_processed: Optional[EmailsProcessed] = None folder: Optional[Literal["AllItems", "Inbox"]] = None @@ -72,10 +64,25 @@ class DomainListResponse(BaseModel): integration_id: Optional[str] = None + ip_restrictions: Optional[List[str]] = None + + last_modified: Optional[datetime] = None + """Deprecated, use `modified_at` instead. End of life: November 1, 2026.""" + + lookback_hops: Optional[int] = None + + modified_at: Optional[datetime] = None + o365_tenant_id: Optional[str] = None + regions: Optional[List[Literal["GLOBAL", "AU", "DE", "IN", "US"]]] = None + require_tls_inbound: Optional[bool] = None require_tls_outbound: Optional[bool] = None spf_status: Optional[Literal["none", "good", "neutral", "open", "invalid"]] = None + + status: Optional[Literal["pending", "active", "failed", "timeout"]] = None + + transport: Optional[str] = None diff --git a/src/cloudflare/types/email_security/settings/impersonation_registry_create_params.py b/src/cloudflare/types/email_security/settings/impersonation_registry_create_params.py index db25db7e746..a2e4c838eac 100644 --- a/src/cloudflare/types/email_security/settings/impersonation_registry_create_params.py +++ b/src/cloudflare/types/email_security/settings/impersonation_registry_create_params.py @@ -2,17 +2,28 @@ from __future__ import annotations -from typing_extensions import Required, TypedDict +from typing import Optional +from typing_extensions import Literal, Required, TypedDict __all__ = ["ImpersonationRegistryCreateParams"] class ImpersonationRegistryCreateParams(TypedDict, total=False): account_id: Required[str] - """Account Identifier""" + """Identifier.""" email: Required[str] is_email_regex: Required[bool] name: Required[str] + + comments: Optional[str] + + directory_id: Optional[int] + + directory_node_id: Optional[int] + + external_directory_node_id: Optional[str] + + provenance: Literal["A1S_INTERNAL", "SNOOPY-CASB_OFFICE_365", "SNOOPY-OFFICE_365", "SNOOPY-GOOGLE_DIRECTORY"] diff --git a/src/cloudflare/types/email_security/settings/impersonation_registry_create_response.py b/src/cloudflare/types/email_security/settings/impersonation_registry_create_response.py index c0dd1f55354..e34f1dab28b 100644 --- a/src/cloudflare/types/email_security/settings/impersonation_registry_create_response.py +++ b/src/cloudflare/types/email_security/settings/impersonation_registry_create_response.py @@ -2,6 +2,7 @@ from typing import Optional from datetime import datetime +from typing_extensions import Literal from ...._models import BaseModel @@ -9,24 +10,32 @@ class ImpersonationRegistryCreateResponse(BaseModel): - id: int + """An impersonation registry entry""" - created_at: datetime - - email: str - - is_email_regex: bool - - last_modified: datetime - - name: str + id: Optional[str] = None + """Impersonation registry entry identifier""" comments: Optional[str] = None + created_at: Optional[datetime] = None + directory_id: Optional[int] = None directory_node_id: Optional[int] = None + email: Optional[str] = None + external_directory_node_id: Optional[str] = None - provenance: Optional[str] = None + is_email_regex: Optional[bool] = None + + last_modified: Optional[datetime] = None + """Deprecated, use `modified_at` instead. End of life: November 1, 2026.""" + + modified_at: Optional[datetime] = None + + name: Optional[str] = None + + provenance: Optional[ + Literal["A1S_INTERNAL", "SNOOPY-CASB_OFFICE_365", "SNOOPY-OFFICE_365", "SNOOPY-GOOGLE_DIRECTORY"] + ] = None diff --git a/src/cloudflare/types/email_security/settings/impersonation_registry_delete_response.py b/src/cloudflare/types/email_security/settings/impersonation_registry_delete_response.py index ba4913c92f1..9f53eea77c2 100644 --- a/src/cloudflare/types/email_security/settings/impersonation_registry_delete_response.py +++ b/src/cloudflare/types/email_security/settings/impersonation_registry_delete_response.py @@ -6,4 +6,5 @@ class ImpersonationRegistryDeleteResponse(BaseModel): - id: int + id: str + """Impersonation registry entry identifier""" diff --git a/src/cloudflare/types/email_security/settings/impersonation_registry_edit_params.py b/src/cloudflare/types/email_security/settings/impersonation_registry_edit_params.py index 8dceb0e75f7..6da26a51e67 100644 --- a/src/cloudflare/types/email_security/settings/impersonation_registry_edit_params.py +++ b/src/cloudflare/types/email_security/settings/impersonation_registry_edit_params.py @@ -3,17 +3,27 @@ from __future__ import annotations from typing import Optional -from typing_extensions import Required, TypedDict +from typing_extensions import Literal, Required, TypedDict __all__ = ["ImpersonationRegistryEditParams"] class ImpersonationRegistryEditParams(TypedDict, total=False): account_id: Required[str] - """Account Identifier""" + """Identifier.""" - email: Optional[str] + comments: Optional[str] - is_email_regex: Optional[bool] + directory_id: Optional[int] - name: Optional[str] + directory_node_id: Optional[int] + + email: str + + external_directory_node_id: Optional[str] + + is_email_regex: bool + + name: str + + provenance: Literal["A1S_INTERNAL", "SNOOPY-CASB_OFFICE_365", "SNOOPY-OFFICE_365", "SNOOPY-GOOGLE_DIRECTORY"] diff --git a/src/cloudflare/types/email_security/settings/impersonation_registry_edit_response.py b/src/cloudflare/types/email_security/settings/impersonation_registry_edit_response.py index 824a0946f7c..f857877c46b 100644 --- a/src/cloudflare/types/email_security/settings/impersonation_registry_edit_response.py +++ b/src/cloudflare/types/email_security/settings/impersonation_registry_edit_response.py @@ -2,6 +2,7 @@ from typing import Optional from datetime import datetime +from typing_extensions import Literal from ...._models import BaseModel @@ -9,24 +10,32 @@ class ImpersonationRegistryEditResponse(BaseModel): - id: int + """An impersonation registry entry""" - created_at: datetime - - email: str - - is_email_regex: bool - - last_modified: datetime - - name: str + id: Optional[str] = None + """Impersonation registry entry identifier""" comments: Optional[str] = None + created_at: Optional[datetime] = None + directory_id: Optional[int] = None directory_node_id: Optional[int] = None + email: Optional[str] = None + external_directory_node_id: Optional[str] = None - provenance: Optional[str] = None + is_email_regex: Optional[bool] = None + + last_modified: Optional[datetime] = None + """Deprecated, use `modified_at` instead. End of life: November 1, 2026.""" + + modified_at: Optional[datetime] = None + + name: Optional[str] = None + + provenance: Optional[ + Literal["A1S_INTERNAL", "SNOOPY-CASB_OFFICE_365", "SNOOPY-OFFICE_365", "SNOOPY-GOOGLE_DIRECTORY"] + ] = None diff --git a/src/cloudflare/types/email_security/settings/impersonation_registry_get_response.py b/src/cloudflare/types/email_security/settings/impersonation_registry_get_response.py index 85a8ab50d71..4a8d99ca5a3 100644 --- a/src/cloudflare/types/email_security/settings/impersonation_registry_get_response.py +++ b/src/cloudflare/types/email_security/settings/impersonation_registry_get_response.py @@ -2,6 +2,7 @@ from typing import Optional from datetime import datetime +from typing_extensions import Literal from ...._models import BaseModel @@ -9,24 +10,32 @@ class ImpersonationRegistryGetResponse(BaseModel): - id: int + """An impersonation registry entry""" - created_at: datetime - - email: str - - is_email_regex: bool - - last_modified: datetime - - name: str + id: Optional[str] = None + """Impersonation registry entry identifier""" comments: Optional[str] = None + created_at: Optional[datetime] = None + directory_id: Optional[int] = None directory_node_id: Optional[int] = None + email: Optional[str] = None + external_directory_node_id: Optional[str] = None - provenance: Optional[str] = None + is_email_regex: Optional[bool] = None + + last_modified: Optional[datetime] = None + """Deprecated, use `modified_at` instead. End of life: November 1, 2026.""" + + modified_at: Optional[datetime] = None + + name: Optional[str] = None + + provenance: Optional[ + Literal["A1S_INTERNAL", "SNOOPY-CASB_OFFICE_365", "SNOOPY-OFFICE_365", "SNOOPY-GOOGLE_DIRECTORY"] + ] = None diff --git a/src/cloudflare/types/email_security/settings/impersonation_registry_list_params.py b/src/cloudflare/types/email_security/settings/impersonation_registry_list_params.py index 49a2b1ddf0a..d652f6012b8 100644 --- a/src/cloudflare/types/email_security/settings/impersonation_registry_list_params.py +++ b/src/cloudflare/types/email_security/settings/impersonation_registry_list_params.py @@ -9,25 +9,21 @@ class ImpersonationRegistryListParams(TypedDict, total=False): account_id: Required[str] - """Account Identifier""" + """Identifier.""" direction: Literal["asc", "desc"] """The sorting direction.""" order: Literal["name", "email", "created_at"] - """The field to sort by.""" + """Field to sort by.""" page: int - """The page number of paginated results.""" + """Current page within paginated list of results.""" per_page: int - """The number of results per page.""" + """The number of results per page. Maximum value is 1000.""" provenance: Literal["A1S_INTERNAL", "SNOOPY-CASB_OFFICE_365", "SNOOPY-OFFICE_365", "SNOOPY-GOOGLE_DIRECTORY"] search: str - """ - Allows searching in multiple properties of a record simultaneously. This - parameter is intended for human users, not automation. Its exact behavior is - intentionally left unspecified and is subject to change in the future. - """ + """Search term for filtering records. Behavior may change.""" diff --git a/src/cloudflare/types/email_security/settings/impersonation_registry_list_response.py b/src/cloudflare/types/email_security/settings/impersonation_registry_list_response.py index 800c8d4bfd7..17299856d1a 100644 --- a/src/cloudflare/types/email_security/settings/impersonation_registry_list_response.py +++ b/src/cloudflare/types/email_security/settings/impersonation_registry_list_response.py @@ -2,6 +2,7 @@ from typing import Optional from datetime import datetime +from typing_extensions import Literal from ...._models import BaseModel @@ -9,24 +10,32 @@ class ImpersonationRegistryListResponse(BaseModel): - id: int + """An impersonation registry entry""" - created_at: datetime - - email: str - - is_email_regex: bool - - last_modified: datetime - - name: str + id: Optional[str] = None + """Impersonation registry entry identifier""" comments: Optional[str] = None + created_at: Optional[datetime] = None + directory_id: Optional[int] = None directory_node_id: Optional[int] = None + email: Optional[str] = None + external_directory_node_id: Optional[str] = None - provenance: Optional[str] = None + is_email_regex: Optional[bool] = None + + last_modified: Optional[datetime] = None + """Deprecated, use `modified_at` instead. End of life: November 1, 2026.""" + + modified_at: Optional[datetime] = None + + name: Optional[str] = None + + provenance: Optional[ + Literal["A1S_INTERNAL", "SNOOPY-CASB_OFFICE_365", "SNOOPY-OFFICE_365", "SNOOPY-GOOGLE_DIRECTORY"] + ] = None diff --git a/src/cloudflare/types/email_security/settings/trusted_domain_create_params.py b/src/cloudflare/types/email_security/settings/trusted_domain_create_params.py index 3159478e22d..0ea1e50ccd5 100644 --- a/src/cloudflare/types/email_security/settings/trusted_domain_create_params.py +++ b/src/cloudflare/types/email_security/settings/trusted_domain_create_params.py @@ -2,15 +2,15 @@ from __future__ import annotations -from typing import Union, Iterable, Optional -from typing_extensions import Required, TypeAlias, TypedDict +from typing import Optional +from typing_extensions import Required, TypedDict -__all__ = ["TrustedDomainCreateParams", "EmailSecurityCreateTrustedDomain", "Variant1", "Variant1Body"] +__all__ = ["TrustedDomainCreateParams"] -class EmailSecurityCreateTrustedDomain(TypedDict, total=False): +class TrustedDomainCreateParams(TypedDict, total=False): account_id: Required[str] - """Account Identifier""" + """Identifier.""" is_recent: Required[bool] """ @@ -29,33 +29,3 @@ class EmailSecurityCreateTrustedDomain(TypedDict, total=False): pattern: Required[str] comments: Optional[str] - - -class Variant1(TypedDict, total=False): - account_id: Required[str] - """Account Identifier""" - - body: Required[Iterable[Variant1Body]] - - -class Variant1Body(TypedDict, total=False): - is_recent: Required[bool] - """ - Select to prevent recently registered domains from triggering a Suspicious or - Malicious disposition. - """ - - is_regex: Required[bool] - - is_similarity: Required[bool] - """ - Select for partner or other approved domains that have similar spelling to your - connected domains. Prevents listed domains from triggering a Spoof disposition. - """ - - pattern: Required[str] - - comments: Optional[str] - - -TrustedDomainCreateParams: TypeAlias = Union[EmailSecurityCreateTrustedDomain, Variant1] diff --git a/src/cloudflare/types/email_security/settings/trusted_domain_create_response.py b/src/cloudflare/types/email_security/settings/trusted_domain_create_response.py index 1dfe56cf075..33b7cc18fdf 100644 --- a/src/cloudflare/types/email_security/settings/trusted_domain_create_response.py +++ b/src/cloudflare/types/email_security/settings/trusted_domain_create_response.py @@ -1,66 +1,40 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Union, Optional +from typing import Optional from datetime import datetime -from typing_extensions import TypeAlias from ...._models import BaseModel -__all__ = ["TrustedDomainCreateResponse", "EmailSecurityTrustedDomain", "UnionMember1"] +__all__ = ["TrustedDomainCreateResponse"] -class EmailSecurityTrustedDomain(BaseModel): - id: int - """The unique identifier for the trusted domain.""" +class TrustedDomainCreateResponse(BaseModel): + """A trusted email domain""" - created_at: datetime - - is_recent: bool - """ - Select to prevent recently registered domains from triggering a Suspicious or - Malicious disposition. - """ - - is_regex: bool - - is_similarity: bool - """ - Select for partner or other approved domains that have similar spelling to your - connected domains. Prevents listed domains from triggering a Spoof disposition. - """ - - last_modified: datetime - - pattern: str + id: Optional[str] = None + """Trusted domain identifier""" comments: Optional[str] = None + created_at: Optional[datetime] = None -class UnionMember1(BaseModel): - id: int - """The unique identifier for the trusted domain.""" - - created_at: datetime - - is_recent: bool + is_recent: Optional[bool] = None """ Select to prevent recently registered domains from triggering a Suspicious or Malicious disposition. """ - is_regex: bool + is_regex: Optional[bool] = None - is_similarity: bool + is_similarity: Optional[bool] = None """ Select for partner or other approved domains that have similar spelling to your connected domains. Prevents listed domains from triggering a Spoof disposition. """ - last_modified: datetime - - pattern: str - - comments: Optional[str] = None + last_modified: Optional[datetime] = None + """Deprecated, use `modified_at` instead. End of life: November 1, 2026.""" + modified_at: Optional[datetime] = None -TrustedDomainCreateResponse: TypeAlias = Union[EmailSecurityTrustedDomain, List[UnionMember1]] + pattern: Optional[str] = None diff --git a/src/cloudflare/types/email_security/settings/trusted_domain_delete_response.py b/src/cloudflare/types/email_security/settings/trusted_domain_delete_response.py index 9c5251946fd..ca3b3afd980 100644 --- a/src/cloudflare/types/email_security/settings/trusted_domain_delete_response.py +++ b/src/cloudflare/types/email_security/settings/trusted_domain_delete_response.py @@ -6,5 +6,5 @@ class TrustedDomainDeleteResponse(BaseModel): - id: int - """The unique identifier for the trusted domain.""" + id: str + """Trusted domain identifier""" diff --git a/src/cloudflare/types/email_security/settings/trusted_domain_edit_params.py b/src/cloudflare/types/email_security/settings/trusted_domain_edit_params.py index 90d1acfc7c0..a96de6dc005 100644 --- a/src/cloudflare/types/email_security/settings/trusted_domain_edit_params.py +++ b/src/cloudflare/types/email_security/settings/trusted_domain_edit_params.py @@ -2,6 +2,7 @@ from __future__ import annotations +from typing import Optional from typing_extensions import Required, TypedDict __all__ = ["TrustedDomainEditParams"] @@ -9,9 +10,9 @@ class TrustedDomainEditParams(TypedDict, total=False): account_id: Required[str] - """Account Identifier""" + """Identifier.""" - comments: str + comments: Optional[str] is_recent: bool """ diff --git a/src/cloudflare/types/email_security/settings/trusted_domain_edit_response.py b/src/cloudflare/types/email_security/settings/trusted_domain_edit_response.py index eb86a0bfebc..2e3b8aa0427 100644 --- a/src/cloudflare/types/email_security/settings/trusted_domain_edit_response.py +++ b/src/cloudflare/types/email_security/settings/trusted_domain_edit_response.py @@ -9,27 +9,32 @@ class TrustedDomainEditResponse(BaseModel): - id: int - """The unique identifier for the trusted domain.""" + """A trusted email domain""" - created_at: datetime + id: Optional[str] = None + """Trusted domain identifier""" - is_recent: bool + comments: Optional[str] = None + + created_at: Optional[datetime] = None + + is_recent: Optional[bool] = None """ Select to prevent recently registered domains from triggering a Suspicious or Malicious disposition. """ - is_regex: bool + is_regex: Optional[bool] = None - is_similarity: bool + is_similarity: Optional[bool] = None """ Select for partner or other approved domains that have similar spelling to your connected domains. Prevents listed domains from triggering a Spoof disposition. """ - last_modified: datetime + last_modified: Optional[datetime] = None + """Deprecated, use `modified_at` instead. End of life: November 1, 2026.""" - pattern: str + modified_at: Optional[datetime] = None - comments: Optional[str] = None + pattern: Optional[str] = None diff --git a/src/cloudflare/types/email_security/settings/trusted_domain_get_response.py b/src/cloudflare/types/email_security/settings/trusted_domain_get_response.py index 23b217fa8d7..dc31ef66b43 100644 --- a/src/cloudflare/types/email_security/settings/trusted_domain_get_response.py +++ b/src/cloudflare/types/email_security/settings/trusted_domain_get_response.py @@ -9,27 +9,32 @@ class TrustedDomainGetResponse(BaseModel): - id: int - """The unique identifier for the trusted domain.""" + """A trusted email domain""" - created_at: datetime + id: Optional[str] = None + """Trusted domain identifier""" - is_recent: bool + comments: Optional[str] = None + + created_at: Optional[datetime] = None + + is_recent: Optional[bool] = None """ Select to prevent recently registered domains from triggering a Suspicious or Malicious disposition. """ - is_regex: bool + is_regex: Optional[bool] = None - is_similarity: bool + is_similarity: Optional[bool] = None """ Select for partner or other approved domains that have similar spelling to your connected domains. Prevents listed domains from triggering a Spoof disposition. """ - last_modified: datetime + last_modified: Optional[datetime] = None + """Deprecated, use `modified_at` instead. End of life: November 1, 2026.""" - pattern: str + modified_at: Optional[datetime] = None - comments: Optional[str] = None + pattern: Optional[str] = None diff --git a/src/cloudflare/types/email_security/settings/trusted_domain_list_params.py b/src/cloudflare/types/email_security/settings/trusted_domain_list_params.py index b9446971853..5036cc37986 100644 --- a/src/cloudflare/types/email_security/settings/trusted_domain_list_params.py +++ b/src/cloudflare/types/email_security/settings/trusted_domain_list_params.py @@ -9,29 +9,33 @@ class TrustedDomainListParams(TypedDict, total=False): account_id: Required[str] - """Account Identifier""" + """Identifier.""" direction: Literal["asc", "desc"] """The sorting direction.""" is_recent: bool + """ + Filter to show only recently registered domains that are trusted to prevent + triggering Suspicious or Malicious dispositions. + """ is_similarity: bool + """ + Filter to show only proximity domains (partner or approved domains with similar + spelling to connected domains) that prevent Spoof dispositions. + """ order: Literal["pattern", "created_at"] - """The field to sort by.""" + """Field to sort by.""" page: int - """The page number of paginated results.""" + """Current page within paginated list of results.""" pattern: str per_page: int - """The number of results per page.""" + """The number of results per page. Maximum value is 1000.""" search: str - """ - Allows searching in multiple properties of a record simultaneously. This - parameter is intended for human users, not automation. Its exact behavior is - intentionally left unspecified and is subject to change in the future. - """ + """Search term for filtering records. Behavior may change.""" diff --git a/src/cloudflare/types/email_security/settings/trusted_domain_list_response.py b/src/cloudflare/types/email_security/settings/trusted_domain_list_response.py index 42e7eec4fed..c7643df7860 100644 --- a/src/cloudflare/types/email_security/settings/trusted_domain_list_response.py +++ b/src/cloudflare/types/email_security/settings/trusted_domain_list_response.py @@ -9,27 +9,32 @@ class TrustedDomainListResponse(BaseModel): - id: int - """The unique identifier for the trusted domain.""" + """A trusted email domain""" - created_at: datetime + id: Optional[str] = None + """Trusted domain identifier""" - is_recent: bool + comments: Optional[str] = None + + created_at: Optional[datetime] = None + + is_recent: Optional[bool] = None """ Select to prevent recently registered domains from triggering a Suspicious or Malicious disposition. """ - is_regex: bool + is_regex: Optional[bool] = None - is_similarity: bool + is_similarity: Optional[bool] = None """ Select for partner or other approved domains that have similar spelling to your connected domains. Prevents listed domains from triggering a Spoof disposition. """ - last_modified: datetime + last_modified: Optional[datetime] = None + """Deprecated, use `modified_at` instead. End of life: November 1, 2026.""" - pattern: str + modified_at: Optional[datetime] = None - comments: Optional[str] = None + pattern: Optional[str] = None diff --git a/src/cloudflare/types/email_security/submission_list_params.py b/src/cloudflare/types/email_security/submission_list_params.py index 225fb097290..b333cbd18b4 100644 --- a/src/cloudflare/types/email_security/submission_list_params.py +++ b/src/cloudflare/types/email_security/submission_list_params.py @@ -13,32 +13,27 @@ class SubmissionListParams(TypedDict, total=False): account_id: Required[str] - """Account Identifier""" - - customer_status: Literal["escalated", "reviewed", "unreviewed"] + """Identifier.""" end: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] - """The end of the search date range. Defaults to `now` if not provided.""" + """The end of the search date range. Defaults to `now`.""" original_disposition: Literal["MALICIOUS", "SUSPICIOUS", "SPOOF", "SPAM", "BULK", "NONE"] outcome_disposition: Literal["MALICIOUS", "SUSPICIOUS", "SPOOF", "SPAM", "BULK", "NONE"] page: int - """The page number of paginated results.""" + """Current page within paginated list of results.""" per_page: int - """The number of results per page.""" + """The number of results per page. Maximum value is 1000.""" query: Optional[str] requested_disposition: Literal["MALICIOUS", "SUSPICIOUS", "SPOOF", "SPAM", "BULK", "NONE"] start: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] - """ - The beginning of the search date range. Defaults to `now - 30 days` if not - provided. - """ + """The beginning of the search date range. Defaults to `now - 30 days`.""" status: str diff --git a/src/cloudflare/types/email_security/submission_list_response.py b/src/cloudflare/types/email_security/submission_list_response.py index 6e48024d27d..d3b3f17014f 100644 --- a/src/cloudflare/types/email_security/submission_list_response.py +++ b/src/cloudflare/types/email_security/submission_list_response.py @@ -10,27 +10,14 @@ class SubmissionListResponse(BaseModel): - requested_ts: datetime - """deprecated as of 2026-04-01, use `requested_at` instead.""" + requested_at: datetime + """When the submission was requested (UTC).""" submission_id: str customer_status: Optional[Literal["escalated", "reviewed", "unreviewed"]] = None - escalated_as: Optional[ - Literal[ - "MALICIOUS", - "MALICIOUS-BEC", - "SUSPICIOUS", - "SPOOF", - "SPAM", - "BULK", - "ENCRYPTED", - "EXTERNAL", - "UNKNOWN", - "NONE", - ] - ] = None + escalated_as: Optional[Literal["MALICIOUS", "SUSPICIOUS", "SPOOF", "SPAM", "BULK", "NONE"]] = None escalated_at: Optional[datetime] = None @@ -38,63 +25,27 @@ class SubmissionListResponse(BaseModel): escalated_submission_id: Optional[str] = None - original_disposition: Optional[ - Literal[ - "MALICIOUS", - "MALICIOUS-BEC", - "SUSPICIOUS", - "SPOOF", - "SPAM", - "BULK", - "ENCRYPTED", - "EXTERNAL", - "UNKNOWN", - "NONE", - ] - ] = None + original_disposition: Optional[Literal["MALICIOUS", "SUSPICIOUS", "SPOOF", "SPAM", "BULK", "NONE"]] = None original_edf_hash: Optional[str] = None original_postfix_id: Optional[str] = None + """The postfix ID of the original message that was submitted""" outcome: Optional[str] = None - outcome_disposition: Optional[ - Literal[ - "MALICIOUS", - "MALICIOUS-BEC", - "SUSPICIOUS", - "SPOOF", - "SPAM", - "BULK", - "ENCRYPTED", - "EXTERNAL", - "UNKNOWN", - "NONE", - ] - ] = None - - requested_at: Optional[datetime] = None + outcome_disposition: Optional[Literal["MALICIOUS", "SUSPICIOUS", "SPOOF", "SPAM", "BULK", "NONE"]] = None requested_by: Optional[str] = None - requested_disposition: Optional[ - Literal[ - "MALICIOUS", - "MALICIOUS-BEC", - "SUSPICIOUS", - "SPOOF", - "SPAM", - "BULK", - "ENCRYPTED", - "EXTERNAL", - "UNKNOWN", - "NONE", - ] - ] = None + requested_disposition: Optional[Literal["MALICIOUS", "SUSPICIOUS", "SPOOF", "SPAM", "BULK", "NONE"]] = None + + requested_ts: Optional[str] = None + """Deprecated, use `requested_at` instead""" status: Optional[str] = None subject: Optional[str] = None - type: Optional[str] = None + type: Optional[Literal["Team", "User"]] = None + """Whether the submission was created by a team member or an end user.""" diff --git a/src/cloudflare/types/fraud/fraud_settings.py b/src/cloudflare/types/fraud/fraud_settings.py index cfd9506fe5c..7392a2b2313 100644 --- a/src/cloudflare/types/fraud/fraud_settings.py +++ b/src/cloudflare/types/fraud/fraud_settings.py @@ -5,10 +5,78 @@ from ..._models import BaseModel -__all__ = ["FraudSettings"] +__all__ = [ + "FraudSettings", + "AuthenticationSettings", + "AuthenticationSettingsFailureCriteria", + "AuthenticationSettingsSuccessCriteria", +] + + +class AuthenticationSettingsFailureCriteria(BaseModel): + """Criterion for identifying failed login responses.""" + + kind: Literal["status_code"] + """The type of criterion. Currently only `status_code` is supported.""" + + status_codes: Optional[List[int]] = None + """HTTP status codes to match against the origin response. + + - Maximum of 10 codes per criterion. + - Each code must be a valid HTTP status code (100-599). + - Codes are deduplicated and sorted on save. + - Omit to leave unchanged on update. + - Provide an empty array `[]` to clear codes on update. + """ + + +class AuthenticationSettingsSuccessCriteria(BaseModel): + """Criterion for identifying successful login responses.""" + + kind: Literal["status_code"] + """The type of criterion. Currently only `status_code` is supported.""" + + status_codes: Optional[List[int]] = None + """HTTP status codes to match against the origin response. + + - Maximum of 10 codes per criterion. + - Each code must be a valid HTTP status code (100-599). + - Codes are deduplicated and sorted on save. + - Omit to leave unchanged on update. + - Provide an empty array `[]` to clear codes on update. + """ + + +class AuthenticationSettings(BaseModel): + """ + Configuration for classifying login authentication outcomes based on the origin response. + Requires `user_profiles` to be enabled. + + - Success and failure criteria are independently updatable — sending only `success_criteria` + leaves failure codes untouched, and vice versa. + - Omit `authentication_settings` entirely to leave both unchanged. + - Status codes must not overlap between success and failure criteria. + """ + + failure_criteria: Optional[AuthenticationSettingsFailureCriteria] = None + """Criterion for identifying failed login responses.""" + + success_criteria: Optional[AuthenticationSettingsSuccessCriteria] = None + """Criterion for identifying successful login responses.""" class FraudSettings(BaseModel): + authentication_settings: Optional[AuthenticationSettings] = None + """ + Configuration for classifying login authentication outcomes based on the origin + response. Requires `user_profiles` to be enabled. + + - Success and failure criteria are independently updatable — sending only + `success_criteria` leaves failure codes untouched, and vice versa. + - Omit `authentication_settings` entirely to leave both unchanged. + - Status codes must not overlap between success and failure criteria. + """ + user_profiles: Optional[Literal["enabled", "disabled"]] = None """Whether Fraud User Profiles is enabled for the zone.""" diff --git a/src/cloudflare/types/fraud/fraud_update_params.py b/src/cloudflare/types/fraud/fraud_update_params.py index 78d59357e8c..4bb2a52b7d1 100644 --- a/src/cloudflare/types/fraud/fraud_update_params.py +++ b/src/cloudflare/types/fraud/fraud_update_params.py @@ -2,17 +2,34 @@ from __future__ import annotations +from typing import Iterable from typing_extensions import Literal, Required, TypedDict from ..._types import SequenceNotStr -__all__ = ["FraudUpdateParams"] +__all__ = [ + "FraudUpdateParams", + "AuthenticationSettings", + "AuthenticationSettingsFailureCriteria", + "AuthenticationSettingsSuccessCriteria", +] class FraudUpdateParams(TypedDict, total=False): zone_id: Required[str] """Identifier.""" + authentication_settings: AuthenticationSettings + """ + Configuration for classifying login authentication outcomes based on the origin + response. Requires `user_profiles` to be enabled. + + - Success and failure criteria are independently updatable — sending only + `success_criteria` leaves failure codes untouched, and vice versa. + - Omit `authentication_settings` entirely to leave both unchanged. + - Status codes must not overlap between success and failure criteria. + """ + user_profiles: Literal["enabled", "disabled"] """Whether Fraud User Profiles is enabled for the zone.""" @@ -25,3 +42,55 @@ class FraudUpdateParams(TypedDict, total=False): - Invalid expressions will result in a 10400 Bad Request with details in the `messages` array. """ + + +class AuthenticationSettingsFailureCriteria(TypedDict, total=False): + """Criterion for identifying failed login responses.""" + + kind: Required[Literal["status_code"]] + """The type of criterion. Currently only `status_code` is supported.""" + + status_codes: Iterable[int] + """HTTP status codes to match against the origin response. + + - Maximum of 10 codes per criterion. + - Each code must be a valid HTTP status code (100-599). + - Codes are deduplicated and sorted on save. + - Omit to leave unchanged on update. + - Provide an empty array `[]` to clear codes on update. + """ + + +class AuthenticationSettingsSuccessCriteria(TypedDict, total=False): + """Criterion for identifying successful login responses.""" + + kind: Required[Literal["status_code"]] + """The type of criterion. Currently only `status_code` is supported.""" + + status_codes: Iterable[int] + """HTTP status codes to match against the origin response. + + - Maximum of 10 codes per criterion. + - Each code must be a valid HTTP status code (100-599). + - Codes are deduplicated and sorted on save. + - Omit to leave unchanged on update. + - Provide an empty array `[]` to clear codes on update. + """ + + +class AuthenticationSettings(TypedDict, total=False): + """ + Configuration for classifying login authentication outcomes based on the origin response. + Requires `user_profiles` to be enabled. + + - Success and failure criteria are independently updatable — sending only `success_criteria` + leaves failure codes untouched, and vice versa. + - Omit `authentication_settings` entirely to leave both unchanged. + - Status codes must not overlap between success and failure criteria. + """ + + failure_criteria: AuthenticationSettingsFailureCriteria + """Criterion for identifying failed login responses.""" + + success_criteria: AuthenticationSettingsSuccessCriteria + """Criterion for identifying successful login responses.""" diff --git a/src/cloudflare/types/magic_transit/__init__.py b/src/cloudflare/types/magic_transit/__init__.py index 700b72f955b..bec3c88a56d 100644 --- a/src/cloudflare/types/magic_transit/__init__.py +++ b/src/cloudflare/types/magic_transit/__init__.py @@ -37,6 +37,7 @@ from .pcap_create_response import PCAPCreateResponse as PCAPCreateResponse from .route_empty_response import RouteEmptyResponse as RouteEmptyResponse from .connector_edit_params import ConnectorEditParams as ConnectorEditParams +from .connector_list_params import ConnectorListParams as ConnectorListParams from .route_create_response import RouteCreateResponse as RouteCreateResponse from .route_delete_response import RouteDeleteResponse as RouteDeleteResponse from .route_update_response import RouteUpdateResponse as RouteUpdateResponse diff --git a/src/cloudflare/types/magic_transit/cf_interconnect_bulk_update_response.py b/src/cloudflare/types/magic_transit/cf_interconnect_bulk_update_response.py index 5ec4fe4087c..2f077f1a996 100644 --- a/src/cloudflare/types/magic_transit/cf_interconnect_bulk_update_response.py +++ b/src/cloudflare/types/magic_transit/cf_interconnect_bulk_update_response.py @@ -26,7 +26,8 @@ class ModifiedInterconnect(BaseModel): automatic_return_routing: Optional[bool] = None """ True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. """ colo_name: Optional[str] = None diff --git a/src/cloudflare/types/magic_transit/cf_interconnect_get_response.py b/src/cloudflare/types/magic_transit/cf_interconnect_get_response.py index 389b0fb12f0..93c01b6d70e 100644 --- a/src/cloudflare/types/magic_transit/cf_interconnect_get_response.py +++ b/src/cloudflare/types/magic_transit/cf_interconnect_get_response.py @@ -26,7 +26,8 @@ class Interconnect(BaseModel): automatic_return_routing: Optional[bool] = None """ True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. """ colo_name: Optional[str] = None diff --git a/src/cloudflare/types/magic_transit/cf_interconnect_list_response.py b/src/cloudflare/types/magic_transit/cf_interconnect_list_response.py index d4e7e7b8745..26eee8fee48 100644 --- a/src/cloudflare/types/magic_transit/cf_interconnect_list_response.py +++ b/src/cloudflare/types/magic_transit/cf_interconnect_list_response.py @@ -26,7 +26,8 @@ class Interconnect(BaseModel): automatic_return_routing: Optional[bool] = None """ True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. """ colo_name: Optional[str] = None diff --git a/src/cloudflare/types/magic_transit/cf_interconnect_update_params.py b/src/cloudflare/types/magic_transit/cf_interconnect_update_params.py index dea0aabfdeb..c57aba4f6e4 100644 --- a/src/cloudflare/types/magic_transit/cf_interconnect_update_params.py +++ b/src/cloudflare/types/magic_transit/cf_interconnect_update_params.py @@ -17,7 +17,8 @@ class CfInterconnectUpdateParams(TypedDict, total=False): automatic_return_routing: bool """ True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. """ description: str diff --git a/src/cloudflare/types/magic_transit/cf_interconnect_update_response.py b/src/cloudflare/types/magic_transit/cf_interconnect_update_response.py index 1e7f379fde1..acf0ec93893 100644 --- a/src/cloudflare/types/magic_transit/cf_interconnect_update_response.py +++ b/src/cloudflare/types/magic_transit/cf_interconnect_update_response.py @@ -26,7 +26,8 @@ class ModifiedInterconnect(BaseModel): automatic_return_routing: Optional[bool] = None """ True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. """ colo_name: Optional[str] = None diff --git a/src/cloudflare/types/magic_transit/connector_create_response.py b/src/cloudflare/types/magic_transit/connector_create_response.py index 74053c83628..57fabb8b537 100644 --- a/src/cloudflare/types/magic_transit/connector_create_response.py +++ b/src/cloudflare/types/magic_transit/connector_create_response.py @@ -13,6 +13,8 @@ class Device(BaseModel): serial_number: Optional[str] = None + type: Optional[Literal["MANAGED", "LICENSED"]] = None + class ConnectorCreateResponse(BaseModel): id: str diff --git a/src/cloudflare/types/magic_transit/connector_delete_response.py b/src/cloudflare/types/magic_transit/connector_delete_response.py index 7dc21b7c70c..e7e20709783 100644 --- a/src/cloudflare/types/magic_transit/connector_delete_response.py +++ b/src/cloudflare/types/magic_transit/connector_delete_response.py @@ -13,6 +13,8 @@ class Device(BaseModel): serial_number: Optional[str] = None + type: Optional[Literal["MANAGED", "LICENSED"]] = None + class ConnectorDeleteResponse(BaseModel): id: str diff --git a/src/cloudflare/types/magic_transit/connector_edit_response.py b/src/cloudflare/types/magic_transit/connector_edit_response.py index e65a54a4c14..25046e5f468 100644 --- a/src/cloudflare/types/magic_transit/connector_edit_response.py +++ b/src/cloudflare/types/magic_transit/connector_edit_response.py @@ -13,6 +13,8 @@ class Device(BaseModel): serial_number: Optional[str] = None + type: Optional[Literal["MANAGED", "LICENSED"]] = None + class ConnectorEditResponse(BaseModel): id: str diff --git a/src/cloudflare/types/magic_transit/connector_get_response.py b/src/cloudflare/types/magic_transit/connector_get_response.py index 00426f9c13b..2c5ab086aee 100644 --- a/src/cloudflare/types/magic_transit/connector_get_response.py +++ b/src/cloudflare/types/magic_transit/connector_get_response.py @@ -13,6 +13,8 @@ class Device(BaseModel): serial_number: Optional[str] = None + type: Optional[Literal["MANAGED", "LICENSED"]] = None + class ConnectorGetResponse(BaseModel): id: str diff --git a/src/cloudflare/types/magic_transit/connector_list_params.py b/src/cloudflare/types/magic_transit/connector_list_params.py new file mode 100644 index 00000000000..385ec3574f5 --- /dev/null +++ b/src/cloudflare/types/magic_transit/connector_list_params.py @@ -0,0 +1,15 @@ +# 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__ = ["ConnectorListParams"] + + +class ConnectorListParams(TypedDict, total=False): + account_id: Required[str] + """Account identifier""" + + device_type: Literal["MANAGED", "LICENSED"] + """Filter connectors by device type.""" diff --git a/src/cloudflare/types/magic_transit/connector_list_response.py b/src/cloudflare/types/magic_transit/connector_list_response.py index bb73ab1bbf3..06079e4a732 100644 --- a/src/cloudflare/types/magic_transit/connector_list_response.py +++ b/src/cloudflare/types/magic_transit/connector_list_response.py @@ -13,6 +13,8 @@ class Device(BaseModel): serial_number: Optional[str] = None + type: Optional[Literal["MANAGED", "LICENSED"]] = None + class ConnectorListResponse(BaseModel): id: str diff --git a/src/cloudflare/types/magic_transit/connector_update_response.py b/src/cloudflare/types/magic_transit/connector_update_response.py index 35d0ee9f20d..17a1543c152 100644 --- a/src/cloudflare/types/magic_transit/connector_update_response.py +++ b/src/cloudflare/types/magic_transit/connector_update_response.py @@ -13,6 +13,8 @@ class Device(BaseModel): serial_number: Optional[str] = None + type: Optional[Literal["MANAGED", "LICENSED"]] = None + class ConnectorUpdateResponse(BaseModel): id: str diff --git a/src/cloudflare/types/magic_transit/gre_tunnel_bulk_update_response.py b/src/cloudflare/types/magic_transit/gre_tunnel_bulk_update_response.py index d98f4e9f5bf..ffacd0ffc74 100644 --- a/src/cloudflare/types/magic_transit/gre_tunnel_bulk_update_response.py +++ b/src/cloudflare/types/magic_transit/gre_tunnel_bulk_update_response.py @@ -151,7 +151,8 @@ class ModifiedGRETunnel(BaseModel): automatic_return_routing: Optional[bool] = None """ True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. """ bgp: Optional[ModifiedGRETunnelBGP] = None diff --git a/src/cloudflare/types/magic_transit/gre_tunnel_create_params.py b/src/cloudflare/types/magic_transit/gre_tunnel_create_params.py index 2e8e4a5b8e8..19e85148542 100644 --- a/src/cloudflare/types/magic_transit/gre_tunnel_create_params.py +++ b/src/cloudflare/types/magic_transit/gre_tunnel_create_params.py @@ -46,7 +46,8 @@ class GRETunnelCreateParams(TypedDict, total=False): automatic_return_routing: bool """ True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. """ bgp: BGP diff --git a/src/cloudflare/types/magic_transit/gre_tunnel_create_response.py b/src/cloudflare/types/magic_transit/gre_tunnel_create_response.py index d9af36faaab..ee95b6fa8b2 100644 --- a/src/cloudflare/types/magic_transit/gre_tunnel_create_response.py +++ b/src/cloudflare/types/magic_transit/gre_tunnel_create_response.py @@ -150,7 +150,8 @@ class GRETunnelCreateResponse(BaseModel): automatic_return_routing: Optional[bool] = None """ True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. """ bgp: Optional[BGP] = None diff --git a/src/cloudflare/types/magic_transit/gre_tunnel_delete_response.py b/src/cloudflare/types/magic_transit/gre_tunnel_delete_response.py index c31aed82b80..2607e9e41bf 100644 --- a/src/cloudflare/types/magic_transit/gre_tunnel_delete_response.py +++ b/src/cloudflare/types/magic_transit/gre_tunnel_delete_response.py @@ -151,7 +151,8 @@ class DeletedGRETunnel(BaseModel): automatic_return_routing: Optional[bool] = None """ True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. """ bgp: Optional[DeletedGRETunnelBGP] = None diff --git a/src/cloudflare/types/magic_transit/gre_tunnel_get_response.py b/src/cloudflare/types/magic_transit/gre_tunnel_get_response.py index 77e2db7f295..ef8eb5cacd8 100644 --- a/src/cloudflare/types/magic_transit/gre_tunnel_get_response.py +++ b/src/cloudflare/types/magic_transit/gre_tunnel_get_response.py @@ -151,7 +151,8 @@ class GRETunnel(BaseModel): automatic_return_routing: Optional[bool] = None """ True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. """ bgp: Optional[GRETunnelBGP] = None diff --git a/src/cloudflare/types/magic_transit/gre_tunnel_list_response.py b/src/cloudflare/types/magic_transit/gre_tunnel_list_response.py index 45d3abf29dd..e4d0cc9ec77 100644 --- a/src/cloudflare/types/magic_transit/gre_tunnel_list_response.py +++ b/src/cloudflare/types/magic_transit/gre_tunnel_list_response.py @@ -151,7 +151,8 @@ class GRETunnel(BaseModel): automatic_return_routing: Optional[bool] = None """ True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. """ bgp: Optional[GRETunnelBGP] = None diff --git a/src/cloudflare/types/magic_transit/gre_tunnel_update_params.py b/src/cloudflare/types/magic_transit/gre_tunnel_update_params.py index 0081115a1d3..003983dcf7d 100644 --- a/src/cloudflare/types/magic_transit/gre_tunnel_update_params.py +++ b/src/cloudflare/types/magic_transit/gre_tunnel_update_params.py @@ -39,7 +39,8 @@ class GRETunnelUpdateParams(TypedDict, total=False): automatic_return_routing: bool """ True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. """ description: str diff --git a/src/cloudflare/types/magic_transit/gre_tunnel_update_response.py b/src/cloudflare/types/magic_transit/gre_tunnel_update_response.py index 637b448d880..a1bba508388 100644 --- a/src/cloudflare/types/magic_transit/gre_tunnel_update_response.py +++ b/src/cloudflare/types/magic_transit/gre_tunnel_update_response.py @@ -151,7 +151,8 @@ class ModifiedGRETunnel(BaseModel): automatic_return_routing: Optional[bool] = None """ True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. """ bgp: Optional[ModifiedGRETunnelBGP] = None diff --git a/src/cloudflare/types/magic_transit/ipsec_tunnel_bulk_update_response.py b/src/cloudflare/types/magic_transit/ipsec_tunnel_bulk_update_response.py index 6fa99f7d723..09d3a3e6bc4 100644 --- a/src/cloudflare/types/magic_transit/ipsec_tunnel_bulk_update_response.py +++ b/src/cloudflare/types/magic_transit/ipsec_tunnel_bulk_update_response.py @@ -166,7 +166,8 @@ class ModifiedIPSECTunnel(BaseModel): automatic_return_routing: Optional[bool] = None """ True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. """ bgp: Optional[ModifiedIPSECTunnelBGP] = None diff --git a/src/cloudflare/types/magic_transit/ipsec_tunnel_create_params.py b/src/cloudflare/types/magic_transit/ipsec_tunnel_create_params.py index 1b6171df8e7..cbfb544cfcf 100644 --- a/src/cloudflare/types/magic_transit/ipsec_tunnel_create_params.py +++ b/src/cloudflare/types/magic_transit/ipsec_tunnel_create_params.py @@ -40,7 +40,8 @@ class IPSECTunnelCreateParams(TypedDict, total=False): automatic_return_routing: bool """ True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. """ bgp: BGP diff --git a/src/cloudflare/types/magic_transit/ipsec_tunnel_create_response.py b/src/cloudflare/types/magic_transit/ipsec_tunnel_create_response.py index 62a8802d687..3dfa6eef0d3 100644 --- a/src/cloudflare/types/magic_transit/ipsec_tunnel_create_response.py +++ b/src/cloudflare/types/magic_transit/ipsec_tunnel_create_response.py @@ -165,7 +165,8 @@ class IPSECTunnelCreateResponse(BaseModel): automatic_return_routing: Optional[bool] = None """ True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. """ bgp: Optional[BGP] = None diff --git a/src/cloudflare/types/magic_transit/ipsec_tunnel_delete_response.py b/src/cloudflare/types/magic_transit/ipsec_tunnel_delete_response.py index 20b73971937..196c7dd3204 100644 --- a/src/cloudflare/types/magic_transit/ipsec_tunnel_delete_response.py +++ b/src/cloudflare/types/magic_transit/ipsec_tunnel_delete_response.py @@ -166,7 +166,8 @@ class DeletedIPSECTunnel(BaseModel): automatic_return_routing: Optional[bool] = None """ True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. """ bgp: Optional[DeletedIPSECTunnelBGP] = None diff --git a/src/cloudflare/types/magic_transit/ipsec_tunnel_get_response.py b/src/cloudflare/types/magic_transit/ipsec_tunnel_get_response.py index 5a01d3e1a75..f8bc64d3ba0 100644 --- a/src/cloudflare/types/magic_transit/ipsec_tunnel_get_response.py +++ b/src/cloudflare/types/magic_transit/ipsec_tunnel_get_response.py @@ -166,7 +166,8 @@ class IPSECTunnel(BaseModel): automatic_return_routing: Optional[bool] = None """ True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. """ bgp: Optional[IPSECTunnelBGP] = None diff --git a/src/cloudflare/types/magic_transit/ipsec_tunnel_list_response.py b/src/cloudflare/types/magic_transit/ipsec_tunnel_list_response.py index a2671697a5a..2b400df722d 100644 --- a/src/cloudflare/types/magic_transit/ipsec_tunnel_list_response.py +++ b/src/cloudflare/types/magic_transit/ipsec_tunnel_list_response.py @@ -166,7 +166,8 @@ class IPSECTunnel(BaseModel): automatic_return_routing: Optional[bool] = None """ True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. """ bgp: Optional[IPSECTunnelBGP] = None diff --git a/src/cloudflare/types/magic_transit/ipsec_tunnel_update_params.py b/src/cloudflare/types/magic_transit/ipsec_tunnel_update_params.py index 459e55c76ed..b8d6325f32e 100644 --- a/src/cloudflare/types/magic_transit/ipsec_tunnel_update_params.py +++ b/src/cloudflare/types/magic_transit/ipsec_tunnel_update_params.py @@ -40,7 +40,8 @@ class IPSECTunnelUpdateParams(TypedDict, total=False): automatic_return_routing: bool """ True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. """ bgp: BGP diff --git a/src/cloudflare/types/magic_transit/ipsec_tunnel_update_response.py b/src/cloudflare/types/magic_transit/ipsec_tunnel_update_response.py index 291befb11e9..9e82141a51d 100644 --- a/src/cloudflare/types/magic_transit/ipsec_tunnel_update_response.py +++ b/src/cloudflare/types/magic_transit/ipsec_tunnel_update_response.py @@ -166,7 +166,8 @@ class ModifiedIPSECTunnel(BaseModel): automatic_return_routing: Optional[bool] = None """ True if automatic stateful return routing should be enabled for a tunnel, false - otherwise. + otherwise. Requires the `coupler_integration` account flag to be enabled; + requests setting this to `true` without that flag will be rejected. """ bgp: Optional[ModifiedIPSECTunnelBGP] = None diff --git a/src/cloudflare/types/magic_transit/sites/dhcp_server.py b/src/cloudflare/types/magic_transit/sites/dhcp_server.py index 51cce549430..55609a201c9 100644 --- a/src/cloudflare/types/magic_transit/sites/dhcp_server.py +++ b/src/cloudflare/types/magic_transit/sites/dhcp_server.py @@ -1,13 +1,43 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Dict, List, Optional +from typing_extensions import Literal from ...._models import BaseModel -__all__ = ["DHCPServer"] +__all__ = ["DHCPServer", "DHCPOption"] + + +class DHCPOption(BaseModel): + """A custom DHCP option to include in DHCP responses.""" + + code: int + """DHCP option number (1-254). + + Options 0 and 255 are reserved by RFC 2132. Options 3, 6, and 51 are not allowed + because they conflict with connector-managed configuration. + """ + + type: Literal["text", "hex", "ip", "byte", "short", "integer"] + """The type of the option value. + + text: a string (max 255 bytes). hex: colon-separated hex bytes (e.g. + "01:04:aa:bb:cc", max 255 bytes). ip: an IPv4 address (e.g. "10.20.30.40"). + byte: an unsigned integer 0-255 (1 byte). short: an unsigned integer 0-65535 (2 + bytes). integer: an unsigned integer 0-4294967295 (4 bytes). + """ + + value: str + """The option value, interpreted according to the type field.""" class DHCPServer(BaseModel): + dhcp_options: Optional[List[DHCPOption]] = None + """Optional list of custom DHCP options to include in DHCP responses. + + Only valid when DHCP server is enabled. + """ + dhcp_pool_end: Optional[str] = None """A valid IPv4 address.""" diff --git a/src/cloudflare/types/magic_transit/sites/dhcp_server_param.py b/src/cloudflare/types/magic_transit/sites/dhcp_server_param.py index 4eecd6a47df..58e8d8983f2 100644 --- a/src/cloudflare/types/magic_transit/sites/dhcp_server_param.py +++ b/src/cloudflare/types/magic_transit/sites/dhcp_server_param.py @@ -2,15 +2,44 @@ from __future__ import annotations -from typing import Dict -from typing_extensions import TypedDict +from typing import Dict, Iterable +from typing_extensions import Literal, Required, TypedDict from ...._types import SequenceNotStr -__all__ = ["DHCPServerParam"] +__all__ = ["DHCPServerParam", "DHCPOption"] + + +class DHCPOption(TypedDict, total=False): + """A custom DHCP option to include in DHCP responses.""" + + code: Required[int] + """DHCP option number (1-254). + + Options 0 and 255 are reserved by RFC 2132. Options 3, 6, and 51 are not allowed + because they conflict with connector-managed configuration. + """ + + type: Required[Literal["text", "hex", "ip", "byte", "short", "integer"]] + """The type of the option value. + + text: a string (max 255 bytes). hex: colon-separated hex bytes (e.g. + "01:04:aa:bb:cc", max 255 bytes). ip: an IPv4 address (e.g. "10.20.30.40"). + byte: an unsigned integer 0-255 (1 byte). short: an unsigned integer 0-65535 (2 + bytes). integer: an unsigned integer 0-4294967295 (4 bytes). + """ + + value: Required[str] + """The option value, interpreted according to the type field.""" class DHCPServerParam(TypedDict, total=False): + dhcp_options: Iterable[DHCPOption] + """Optional list of custom DHCP options to include in DHCP responses. + + Only valid when DHCP server is enabled. + """ + dhcp_pool_end: str """A valid IPv4 address.""" diff --git a/src/cloudflare/types/queues/__init__.py b/src/cloudflare/types/queues/__init__.py index 2d25382356d..af80c330eab 100644 --- a/src/cloudflare/types/queues/__init__.py +++ b/src/cloudflare/types/queues/__init__.py @@ -23,6 +23,7 @@ from .subscription_list_params import SubscriptionListParams as SubscriptionListParams from .subscription_get_response import SubscriptionGetResponse as SubscriptionGetResponse from .message_bulk_push_response import MessageBulkPushResponse as MessageBulkPushResponse +from .queue_get_metrics_response import QueueGetMetricsResponse as QueueGetMetricsResponse from .subscription_create_params import SubscriptionCreateParams as SubscriptionCreateParams from .subscription_list_response import SubscriptionListResponse as SubscriptionListResponse from .subscription_update_params import SubscriptionUpdateParams as SubscriptionUpdateParams diff --git a/src/cloudflare/types/queues/queue_get_metrics_response.py b/src/cloudflare/types/queues/queue_get_metrics_response.py new file mode 100644 index 00000000000..6d60e49a45b --- /dev/null +++ b/src/cloudflare/types/queues/queue_get_metrics_response.py @@ -0,0 +1,25 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ..._models import BaseModel + +__all__ = ["QueueGetMetricsResponse"] + + +class QueueGetMetricsResponse(BaseModel): + """Best-effort metrics for the queue. + + Values may be approximate due to the distributed nature of queues. + """ + + backlog_bytes: float + """The size in bytes of unacknowledged messages in the queue.""" + + backlog_count: float + """The number of unacknowledged messages in the queue.""" + + oldest_message_timestamp_ms: float + """Unix timestamp in milliseconds of the oldest unacknowledged message in the + queue. + + Returns 0 if unknown. + """ diff --git a/src/cloudflare/types/r2/bucket_list_response.py b/src/cloudflare/types/r2/bucket_list_response.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/types/r2/buckets/domains/custom_create_response.py b/src/cloudflare/types/r2/buckets/domains/custom_create_response.py index 88a05be4d0e..9fc563d3f10 100644 --- a/src/cloudflare/types/r2/buckets/domains/custom_create_response.py +++ b/src/cloudflare/types/r2/buckets/domains/custom_create_response.py @@ -17,6 +17,9 @@ class CustomCreateResponse(BaseModel): enabled: bool """Whether this bucket is publicly accessible at the specified custom domain.""" + zone_id: str = FieldInfo(alias="zoneId") + """Zone ID of the custom domain.""" + ciphers: Optional[List[str]] = None """An allowlist of ciphers for TLS termination. diff --git a/src/cloudflare/types/workers/beta/workers/version.py b/src/cloudflare/types/workers/beta/workers/version.py index 708a27dd244..4aaab999555 100644 --- a/src/cloudflare/types/workers/beta/workers/version.py +++ b/src/cloudflare/types/workers/beta/workers/version.py @@ -424,6 +424,13 @@ class BindingWorkersBindingKindRatelimitSimple(BaseModel): period: int """The period in seconds.""" + mitigation_timeout: Optional[int] = None + """ + Duration in seconds to apply the mitigation action after the rate limit is + exceeded. Valid values are 0 (disabled), 10, or multiples of 60 up to 86400. + Must be greater than or equal to the period when non-zero. + """ + class BindingWorkersBindingKindRatelimit(BaseModel): name: str diff --git a/src/cloudflare/types/workers/beta/workers/version_create_params.py b/src/cloudflare/types/workers/beta/workers/version_create_params.py index 9f4b87ffba3..0267fb27bc0 100644 --- a/src/cloudflare/types/workers/beta/workers/version_create_params.py +++ b/src/cloudflare/types/workers/beta/workers/version_create_params.py @@ -509,6 +509,13 @@ class BindingWorkersBindingKindRatelimitSimple(TypedDict, total=False): period: Required[int] """The period in seconds.""" + mitigation_timeout: int + """ + Duration in seconds to apply the mitigation action after the rate limit is + exceeded. Valid values are 0 (disabled), 10, or multiples of 60 up to 86400. + Must be greater than or equal to the period when non-zero. + """ + class BindingWorkersBindingKindRatelimit(TypedDict, total=False): name: Required[str] diff --git a/src/cloudflare/types/workers/observability/telemetry_keys_params.py b/src/cloudflare/types/workers/observability/telemetry_keys_params.py index 275b94b0c97..0f9c75cd0e3 100644 --- a/src/cloudflare/types/workers/observability/telemetry_keys_params.py +++ b/src/cloudflare/types/workers/observability/telemetry_keys_params.py @@ -12,6 +12,9 @@ "TelemetryKeysParams", "Filter", "FilterUnionMember0", + "FilterUnionMember0Filter", + "FilterUnionMember0FilterUnionMember0", + "FilterUnionMember0FilterWorkersObservabilityFilterLeaf", "FilterWorkersObservabilityFilterLeaf", "KeyNeedle", "Needle", @@ -50,7 +53,7 @@ class TelemetryKeysParams(TypedDict, total=False): to: float -class FilterUnionMember0(TypedDict, total=False): +class FilterUnionMember0FilterUnionMember0(TypedDict, total=False): filter_combination: Required[Annotated[Literal["and", "or", "AND", "OR"], PropertyInfo(alias="filterCombination")]] filters: Required[Iterable[object]] @@ -58,17 +61,106 @@ class FilterUnionMember0(TypedDict, total=False): kind: Required[Literal["group"]] -class FilterWorkersObservabilityFilterLeaf(TypedDict, total=False): +class FilterUnionMember0FilterWorkersObservabilityFilterLeaf(TypedDict, total=False): + """A filter condition applied to query results. + + Use the keys and values endpoints to discover available fields and their values before constructing filters. """ - Filtering best practices: use observability_keys and observability_values to confirm available fields and values. If searching for errors, filter for $metadata.error exists. + + key: Required[str] + """Filter field name. + + Use verified keys from previous query results or the keys endpoint. Common keys + include $metadata.service, $metadata.origin, $metadata.trigger, + $metadata.message, and $metadata.error. + """ + + operation: Required[ + Literal[ + "includes", + "not_includes", + "starts_with", + "regex", + "exists", + "is_null", + "in", + "not_in", + "eq", + "neq", + "gt", + "gte", + "lt", + "lte", + "=", + "!=", + ">", + ">=", + "<", + "<=", + "INCLUDES", + "DOES_NOT_INCLUDE", + "MATCH_REGEX", + "EXISTS", + "DOES_NOT_EXIST", + "IN", + "NOT_IN", + "STARTS_WITH", + ] + ] + """Comparison operator. + + String operators: includes, not_includes, starts_with, regex. Existence: exists, + is_null. Set membership: in, not_in (comma-separated values). Numeric: eq, neq, + gt, gte, lt, lte. + """ + + type: Required[Literal["string", "number", "boolean"]] + """Data type of the filter field. + + Must match the actual type of the key being filtered. + """ + + kind: Literal["filter"] + """Discriminator for leaf filter nodes. + + Always 'filter' when present; may be omitted. + """ + + value: Union[str, float, bool] + """Comparison value. + + Must match actual values in your data — verify with the values endpoint. Ensure + the value type (string/number/boolean) matches the field type. String + comparisons are case-sensitive. Regex uses RE2 syntax (no + lookaheads/lookbehinds). + """ + + +FilterUnionMember0Filter: TypeAlias = Union[ + FilterUnionMember0FilterUnionMember0, FilterUnionMember0FilterWorkersObservabilityFilterLeaf +] + + +class FilterUnionMember0(TypedDict, total=False): + filter_combination: Required[Annotated[Literal["and", "or", "AND", "OR"], PropertyInfo(alias="filterCombination")]] + + filters: Required[Iterable[FilterUnionMember0Filter]] + + kind: Required[Literal["group"]] + + +class FilterWorkersObservabilityFilterLeaf(TypedDict, total=False): + """A filter condition applied to query results. + + Use the keys and values endpoints to discover available fields and their values before constructing filters. """ key: Required[str] """Filter field name. - IMPORTANT: do not guess keys. Always use verified keys from previous query - results or the observability_keys response. Preferred keys: $metadata.service, - $metadata.origin, $metadata.trigger, $metadata.message, $metadata.error. + Use verified keys from previous query results or the keys endpoint. Common keys + include $metadata.service, $metadata.origin, $metadata.trigger, + $metadata.message, and $metadata.error. """ operation: Required[ @@ -103,19 +195,32 @@ class FilterWorkersObservabilityFilterLeaf(TypedDict, total=False): "STARTS_WITH", ] ] + """Comparison operator. + + String operators: includes, not_includes, starts_with, regex. Existence: exists, + is_null. Set membership: in, not_in (comma-separated values). Numeric: eq, neq, + gt, gte, lt, lte. + """ type: Required[Literal["string", "number", "boolean"]] + """Data type of the filter field. + + Must match the actual type of the key being filtered. + """ kind: Literal["filter"] + """Discriminator for leaf filter nodes. + + Always 'filter' when present; may be omitted. + """ value: Union[str, float, bool] - """Filter comparison value. + """Comparison value. - IMPORTANT: must match actual values in your logs. Verify using previous query - results or the /values endpoint. Ensure value type matches the field type. - String comparisons are case-sensitive unless using specific operations. Regex - uses ClickHouse RE2 syntax (no lookaheads/lookbehinds); examples: ^5\\dd{2}$ for - HTTP 5xx, \bERROR\b for word boundary. + Must match actual values in your data — verify with the values endpoint. Ensure + the value type (string/number/boolean) matches the field type. String + comparisons are case-sensitive. Regex uses RE2 syntax (no + lookaheads/lookbehinds). """ @@ -129,17 +234,23 @@ class KeyNeedle(TypedDict, total=False): """ value: Required[Union[str, float, bool]] + """The text or pattern to search for.""" is_regex: Annotated[bool, PropertyInfo(alias="isRegex")] + """When true, treats the value as a regular expression (RE2 syntax).""" match_case: Annotated[bool, PropertyInfo(alias="matchCase")] + """When true, performs a case-sensitive search. Defaults to case-insensitive.""" class Needle(TypedDict, total=False): """Search for a specific substring in any of the events""" value: Required[Union[str, float, bool]] + """The text or pattern to search for.""" is_regex: Annotated[bool, PropertyInfo(alias="isRegex")] + """When true, treats the value as a regular expression (RE2 syntax).""" match_case: Annotated[bool, PropertyInfo(alias="matchCase")] + """When true, performs a case-sensitive search. Defaults to case-insensitive.""" diff --git a/src/cloudflare/types/workers/observability/telemetry_query_params.py b/src/cloudflare/types/workers/observability/telemetry_query_params.py index 6430ea3f9fb..c328f89aad2 100644 --- a/src/cloudflare/types/workers/observability/telemetry_query_params.py +++ b/src/cloudflare/types/workers/observability/telemetry_query_params.py @@ -15,6 +15,9 @@ "ParametersCalculation", "ParametersFilter", "ParametersFilterUnionMember0", + "ParametersFilterUnionMember0Filter", + "ParametersFilterUnionMember0FilterUnionMember0", + "ParametersFilterUnionMember0FilterWorkersObservabilityFilterLeaf", "ParametersFilterWorkersObservabilityFilterLeaf", "ParametersGroupBy", "ParametersHaving", @@ -27,66 +30,83 @@ class TelemetryQueryParams(TypedDict, total=False): account_id: Required[str] query_id: Required[Annotated[str, PropertyInfo(alias="queryId")]] - """Unique identifier for the query to execute""" + """Identifier for the query. + + When parameters are omitted, this ID is used to load a previously saved query's + parameters. When providing parameters inline, pass any identifier (e.g. an + ad-hoc ID). + """ timeframe: Required[Timeframe] - """Timeframe for your query using Unix timestamps in milliseconds. + """Timeframe for the query using Unix timestamps in milliseconds. - Provide from/to epoch ms; narrower timeframes provide faster responses and more - specific results. + Narrower timeframes produce faster responses and more specific results. """ chart: bool - """Whether to include timeseties data in the response""" + """When true, includes time-series data in the response.""" compare: bool - """Whether to include comparison data with previous time periods""" + """ + When true, includes a comparison dataset from the previous time period of equal + length. + """ dry: bool - """Whether to perform a dry run without saving the results of the query. + """When true, executes the query without persisting the results. - Useful for validation + Useful for validation or previewing. """ granularity: float - """This is only used when the view is calculations. + """Number of time-series buckets. - Leaving it empty lets Workers Observability detect the correct granularity. + Only used when view is 'calculations'. Omit to let the system auto-detect an + appropriate granularity. """ ignore_series: Annotated[bool, PropertyInfo(alias="ignoreSeries")] """ - Whether to ignore time-series data in the results and return only aggregated - values + When true, omits time-series data from the response and returns only aggregated + values. Reduces response size when series are not needed. """ limit: float - """Use this limit to cap the number of events returned when the view is events.""" + """Maximum number of events to return when view is 'events'. + + Also controls the number of group-by rows when view is 'calculations'. + """ offset: str - """Cursor pagination for event/trace/invocation views. + """Cursor for pagination in event, trace, and invocation views. - Pass the last item's $metadata.id as the next offset. + Pass the $metadata.id of the last returned item to fetch the next page. """ offset_by: Annotated[float, PropertyInfo(alias="offsetBy")] - """Numeric offset for pattern results (top-N list). + """Numeric offset for paginating grouped/pattern results (top-N lists). - Use with limit to page pattern groups; not used by cursor pagination. + Use together with limit. Not used by cursor-based pagination. """ offset_direction: Annotated[str, PropertyInfo(alias="offsetDirection")] - """Direction for offset-based pagination (e.g., 'next', 'prev')""" + """Pagination direction: 'next' for forward, 'prev' for backward.""" parameters: Parameters - """Optional parameters to pass to the query execution""" + """ + Query parameters defining what data to retrieve — filters, calculations, + group-bys, and ordering. In practice this should always be provided for ad-hoc + queries. Only omit when executing a previously saved query by queryId. Use the + keys and values endpoints to discover available fields before building filters. + """ view: Literal["traces", "events", "calculations", "invocations", "requests", "agents"] - """Examples by view type. + """Controls the shape of the response. - Events: show errors for a worker in the last 30 minutes. Calculations: p99 of - wall time or count by status code. Invocations: find a specific request that - resulted in a 500. + 'events': individual log lines matching the query. 'calculations': aggregated + metrics (count, avg, p99, etc.) with optional group-by breakdowns and + time-series. 'invocations': events grouped by request ID. 'traces': distributed + trace summaries. 'agents': Durable Object agent summaries. """ @@ -100,9 +120,9 @@ class TelemetryQueryParams(TypedDict, total=False): class Timeframe(_TimeframeReservedKeywords, total=False): - """Timeframe for your query using Unix timestamps in milliseconds. + """Timeframe for the query using Unix timestamps in milliseconds. - Provide from/to epoch ms; narrower timeframes provide faster responses and more specific results. + Narrower timeframes produce faster responses and more specific results. """ to: Required[float] @@ -152,20 +172,32 @@ class ParametersCalculation(TypedDict, total=False): "VARIANCE", ] ] + """Aggregation operator to apply. + + Examples: count, avg, sum, min, max, p50, p90, p95, p99, uniq, stddev, variance. + """ alias: str + """Custom label for this calculation in the results. + + Useful for distinguishing multiple calculations. + """ key: str - """The key to use for the calculation. + """Field name to calculate over. - This key must exist in the logs. Use the observability_keys response to confirm. - Do not guess keys. + Must exist in the data — verify with the keys endpoint. Omit for operators that + don't require a key (e.g. count). """ key_type: Annotated[Literal["string", "number", "boolean"], PropertyInfo(alias="keyType")] + """Data type of the key. + Required when key is provided to ensure correct aggregation. + """ -class ParametersFilterUnionMember0(TypedDict, total=False): + +class ParametersFilterUnionMember0FilterUnionMember0(TypedDict, total=False): filter_combination: Required[Annotated[Literal["and", "or", "AND", "OR"], PropertyInfo(alias="filterCombination")]] filters: Required[Iterable[object]] @@ -173,17 +205,106 @@ class ParametersFilterUnionMember0(TypedDict, total=False): kind: Required[Literal["group"]] -class ParametersFilterWorkersObservabilityFilterLeaf(TypedDict, total=False): +class ParametersFilterUnionMember0FilterWorkersObservabilityFilterLeaf(TypedDict, total=False): + """A filter condition applied to query results. + + Use the keys and values endpoints to discover available fields and their values before constructing filters. + """ + + key: Required[str] + """Filter field name. + + Use verified keys from previous query results or the keys endpoint. Common keys + include $metadata.service, $metadata.origin, $metadata.trigger, + $metadata.message, and $metadata.error. """ - Filtering best practices: use observability_keys and observability_values to confirm available fields and values. If searching for errors, filter for $metadata.error exists. + + operation: Required[ + Literal[ + "includes", + "not_includes", + "starts_with", + "regex", + "exists", + "is_null", + "in", + "not_in", + "eq", + "neq", + "gt", + "gte", + "lt", + "lte", + "=", + "!=", + ">", + ">=", + "<", + "<=", + "INCLUDES", + "DOES_NOT_INCLUDE", + "MATCH_REGEX", + "EXISTS", + "DOES_NOT_EXIST", + "IN", + "NOT_IN", + "STARTS_WITH", + ] + ] + """Comparison operator. + + String operators: includes, not_includes, starts_with, regex. Existence: exists, + is_null. Set membership: in, not_in (comma-separated values). Numeric: eq, neq, + gt, gte, lt, lte. + """ + + type: Required[Literal["string", "number", "boolean"]] + """Data type of the filter field. + + Must match the actual type of the key being filtered. + """ + + kind: Literal["filter"] + """Discriminator for leaf filter nodes. + + Always 'filter' when present; may be omitted. + """ + + value: Union[str, float, bool] + """Comparison value. + + Must match actual values in your data — verify with the values endpoint. Ensure + the value type (string/number/boolean) matches the field type. String + comparisons are case-sensitive. Regex uses RE2 syntax (no + lookaheads/lookbehinds). + """ + + +ParametersFilterUnionMember0Filter: TypeAlias = Union[ + ParametersFilterUnionMember0FilterUnionMember0, ParametersFilterUnionMember0FilterWorkersObservabilityFilterLeaf +] + + +class ParametersFilterUnionMember0(TypedDict, total=False): + filter_combination: Required[Annotated[Literal["and", "or", "AND", "OR"], PropertyInfo(alias="filterCombination")]] + + filters: Required[Iterable[ParametersFilterUnionMember0Filter]] + + kind: Required[Literal["group"]] + + +class ParametersFilterWorkersObservabilityFilterLeaf(TypedDict, total=False): + """A filter condition applied to query results. + + Use the keys and values endpoints to discover available fields and their values before constructing filters. """ key: Required[str] """Filter field name. - IMPORTANT: do not guess keys. Always use verified keys from previous query - results or the observability_keys response. Preferred keys: $metadata.service, - $metadata.origin, $metadata.trigger, $metadata.message, $metadata.error. + Use verified keys from previous query results or the keys endpoint. Common keys + include $metadata.service, $metadata.origin, $metadata.trigger, + $metadata.message, and $metadata.error. """ operation: Required[ @@ -218,19 +339,32 @@ class ParametersFilterWorkersObservabilityFilterLeaf(TypedDict, total=False): "STARTS_WITH", ] ] + """Comparison operator. + + String operators: includes, not_includes, starts_with, regex. Existence: exists, + is_null. Set membership: in, not_in (comma-separated values). Numeric: eq, neq, + gt, gte, lt, lte. + """ type: Required[Literal["string", "number", "boolean"]] + """Data type of the filter field. + + Must match the actual type of the key being filtered. + """ kind: Literal["filter"] + """Discriminator for leaf filter nodes. + + Always 'filter' when present; may be omitted. + """ value: Union[str, float, bool] - """Filter comparison value. + """Comparison value. - IMPORTANT: must match actual values in your logs. Verify using previous query - results or the /values endpoint. Ensure value type matches the field type. - String comparisons are case-sensitive unless using specific operations. Regex - uses ClickHouse RE2 syntax (no lookaheads/lookbehinds); examples: ^5\\dd{2}$ for - HTTP 5xx, \bERROR\b for word boundary. + Must match actual values in your data — verify with the values endpoint. Ensure + the value type (string/number/boolean) matches the field type. String + comparisons are case-sensitive. Regex uses RE2 syntax (no + lookaheads/lookbehinds). """ @@ -239,67 +373,110 @@ class ParametersFilterWorkersObservabilityFilterLeaf(TypedDict, total=False): class ParametersGroupBy(TypedDict, total=False): type: Required[Literal["string", "number", "boolean"]] + """Data type of the group-by field.""" value: Required[str] + """Field name to group results by (e.g. $metadata.service, $metadata.statusCode).""" class ParametersHaving(TypedDict, total=False): key: Required[str] + """Calculation alias or operator to filter on after aggregation.""" operation: Required[Literal["eq", "neq", "gt", "gte", "lt", "lte"]] + """Numeric comparison operator: eq, neq, gt, gte, lt, lte.""" value: Required[float] + """Threshold value to compare the calculation result against.""" class ParametersNeedle(TypedDict, total=False): - """Define an expression to search using full-text search.""" + """Full-text search expression applied across all event fields. + + Matches events containing the specified text. + """ value: Required[Union[str, float, bool]] + """The text or pattern to search for.""" is_regex: Annotated[bool, PropertyInfo(alias="isRegex")] + """When true, treats the value as a regular expression (RE2 syntax).""" match_case: Annotated[bool, PropertyInfo(alias="matchCase")] + """When true, performs a case-sensitive search. Defaults to case-insensitive.""" class ParametersOrderBy(TypedDict, total=False): - """Configure the order of the results returned by the query.""" + """Ordering for grouped calculation results. + + Only effective when a group-by is present. + """ value: Required[str] - """Configure which Calculation to order the results by.""" + """Alias of the calculation to order results by. + + Must match the alias (or operator) of a calculation in the query. + """ order: Literal["asc", "desc"] - """Set the order of the results""" + """Sort direction: 'asc' for ascending, 'desc' for descending.""" class Parameters(TypedDict, total=False): - """Optional parameters to pass to the query execution""" + """ + Query parameters defining what data to retrieve — filters, calculations, group-bys, and ordering. In practice this should always be provided for ad-hoc queries. Only omit when executing a previously saved query by queryId. Use the keys and values endpoints to discover available fields before building filters. + """ calculations: Iterable[ParametersCalculation] - """Create Calculations to compute as part of the query.""" + """Aggregation calculations to compute (e.g. + + count, avg, p99). Each calculation produces aggregate values and optional + time-series data. + """ datasets: SequenceNotStr[str] - """Set the Datasets to query. Leave it empty to query all the datasets.""" + """Datasets to query. Leave empty to query all available datasets.""" filter_combination: Annotated[Literal["and", "or", "AND", "OR"], PropertyInfo(alias="filterCombination")] - """Set a Flag to describe how to combine the filters on the query.""" + """ + Logical operator for combining top-level filters: 'and' (all must match) or 'or' + (any must match). Defaults to 'and'. + """ filters: Iterable[ParametersFilter] - """Configure the Filters to apply to the query. + """Filters to narrow query results. - Supports nested groups via kind: 'group'. Maximum nesting depth is 4. + Use the keys and values endpoints to discover available fields before building + filters. Supports nested groups via kind: 'group'. Maximum nesting depth is 4. """ group_bys: Annotated[Iterable[ParametersGroupBy], PropertyInfo(alias="groupBys")] - """Define how to group the results of the query.""" + """Fields to group calculation results by. + + Only applicable when the query view is 'calculations'. Produces per-group + aggregate values. + """ havings: Iterable[ParametersHaving] - """Configure the Having clauses that filter on calculations in the query result.""" + """Post-aggregation filters applied to calculation results. + + Use to filter groups after aggregation (e.g. only groups where count > 100). + """ limit: int - """Set a limit on the number of results / records returned by the query""" + """Maximum number of group-by rows to return in calculation results. + + A value of 10 is a sensible default for most use cases. + """ needle: ParametersNeedle - """Define an expression to search using full-text search.""" + """Full-text search expression applied across all event fields. + + Matches events containing the specified text. + """ order_by: Annotated[ParametersOrderBy, PropertyInfo(alias="orderBy")] - """Configure the order of the results returned by the query.""" + """Ordering for grouped calculation results. + + Only effective when a group-by is present. + """ diff --git a/src/cloudflare/types/workers/observability/telemetry_query_response.py b/src/cloudflare/types/workers/observability/telemetry_query_response.py index 27fe10fc78d..6ec793c152f 100644 --- a/src/cloudflare/types/workers/observability/telemetry_query_response.py +++ b/src/cloudflare/types/workers/observability/telemetry_query_response.py @@ -120,16 +120,17 @@ class RunQueryParametersFilterUnionMember0(BaseModel): class RunQueryParametersFilterWorkersObservabilityFilterLeaf(BaseModel): - """ - Filtering best practices: use observability_keys and observability_values to confirm available fields and values. If searching for errors, filter for $metadata.error exists. + """A filter condition applied to query results. + + Use the keys and values endpoints to discover available fields and their values before constructing filters. """ key: str """Filter field name. - IMPORTANT: do not guess keys. Always use verified keys from previous query - results or the observability_keys response. Preferred keys: $metadata.service, - $metadata.origin, $metadata.trigger, $metadata.message, $metadata.error. + Use verified keys from previous query results or the keys endpoint. Common keys + include $metadata.service, $metadata.origin, $metadata.trigger, + $metadata.message, and $metadata.error. """ operation: Literal[ @@ -162,19 +163,32 @@ class RunQueryParametersFilterWorkersObservabilityFilterLeaf(BaseModel): "NOT_IN", "STARTS_WITH", ] + """Comparison operator. + + String operators: includes, not_includes, starts_with, regex. Existence: exists, + is_null. Set membership: in, not_in (comma-separated values). Numeric: eq, neq, + gt, gte, lt, lte. + """ type: Literal["string", "number", "boolean"] + """Data type of the filter field. + + Must match the actual type of the key being filtered. + """ kind: Optional[Literal["filter"]] = None + """Discriminator for leaf filter nodes. + + Always 'filter' when present; may be omitted. + """ value: Union[str, float, bool, None] = None - """Filter comparison value. + """Comparison value. - IMPORTANT: must match actual values in your logs. Verify using previous query - results or the /values endpoint. Ensure value type matches the field type. - String comparisons are case-sensitive unless using specific operations. Regex - uses ClickHouse RE2 syntax (no lookaheads/lookbehinds); examples: ^5\\dd{2}$ for - HTTP 5xx, \bERROR\b for word boundary. + Must match actual values in your data — verify with the values endpoint. Ensure + the value type (string/number/boolean) matches the field type. String + comparisons are case-sensitive. Regex uses RE2 syntax (no + lookaheads/lookbehinds). """ @@ -254,6 +268,10 @@ class RunQueryParameters(BaseModel): class RunQuery(BaseModel): + """ + A saved query definition with its parameters, metadata, and ownership information. + """ + id: str adhoc: bool @@ -286,6 +304,10 @@ class RunTimeframe(BaseModel): class RunStatistics(BaseModel): + """ + Query performance statistics from the database (does not include network latency). + """ + bytes_read: float """Number of uncompressed bytes read from the table.""" @@ -303,35 +325,57 @@ class RunStatistics(BaseModel): class Run(BaseModel): - """A Workers Observability Query Object""" + """ + The query run metadata including the query definition, execution status, and timeframe. + """ id: str + """Unique identifier for this query run.""" account_id: str = FieldInfo(alias="accountId") + """Cloudflare account ID that owns this query run.""" dry: bool + """Whether this was a dry run (results not persisted).""" granularity: float + """Number of time-series buckets used for the query. + + Higher values produce more detailed series data. + """ query: RunQuery + """ + A saved query definition with its parameters, metadata, and ownership + information. + """ status: Literal["STARTED", "COMPLETED"] + """Current execution status of the query run.""" timeframe: RunTimeframe """Time range for the query execution""" user_id: str = FieldInfo(alias="userId") + """ID of the user who initiated the query run.""" created: Optional[str] = None + """ISO-8601 timestamp when the query run was created.""" statistics: Optional[RunStatistics] = None + """ + Query performance statistics from the database (does not include network + latency). + """ updated: Optional[str] = None + """ISO-8601 timestamp when the query run was last updated.""" class Statistics(BaseModel): - """ - The statistics object contains information about query performance from the database, it does not include any network latency + """Query performance statistics from the database. + + Includes execution time, rows scanned, and bytes read. Does not include network latency. """ bytes_read: float @@ -352,20 +396,31 @@ class Statistics(BaseModel): class Agent(BaseModel): agent_class: str = FieldInfo(alias="agentClass") + """Class name of the Durable Object agent.""" event_type_counts: Dict[str, float] = FieldInfo(alias="eventTypeCounts") + """Breakdown of event counts by event type.""" first_event_ms: float = FieldInfo(alias="firstEventMs") + """ + Timestamp of the earliest event from this agent in the queried window (Unix + epoch ms). + """ has_errors: bool = FieldInfo(alias="hasErrors") + """Whether the agent emitted any error events in the queried window.""" last_event_ms: float = FieldInfo(alias="lastEventMs") + """Timestamp of the most recent event from this agent (Unix epoch ms).""" namespace: str + """Durable Object namespace the agent belongs to.""" service: str + """Worker service name that hosts this agent.""" total_events: float = FieldInfo(alias="totalEvents") + """Total number of events emitted by this agent in the queried window.""" class CalculationAggregateGroup(BaseModel): @@ -481,68 +536,103 @@ class Compare(BaseModel): class EventsEventMetadata(BaseModel): + """Structured metadata extracted from the event. + + These fields are indexed and available for filtering and aggregation. + """ + id: str - """Unique event ID. Use as the cursor for offset-based pagination.""" + """Unique event ID. Use as the cursor value for offset-based pagination.""" account: Optional[str] = None + """Cloudflare account identifier.""" cloud_service: Optional[str] = FieldInfo(alias="cloudService", default=None) + """Cloudflare product that generated this event (e.g. workers, pages).""" cold_start: Optional[int] = FieldInfo(alias="coldStart", default=None) + """Whether this was a cold start (1) or warm invocation (0).""" cost: Optional[int] = None + """Estimated cost units for this invocation.""" duration: Optional[int] = None + """Span duration in milliseconds.""" end_time: Optional[int] = FieldInfo(alias="endTime", default=None) + """Span end time as a Unix epoch in milliseconds.""" error: Optional[str] = None + """Error message, present when the log represents an error.""" error_template: Optional[str] = FieldInfo(alias="errorTemplate", default=None) + """Templatized version of the error message used for grouping similar errors.""" fingerprint: Optional[str] = None + """Content-based fingerprint used to group similar events.""" level: Optional[str] = None + """Log level (e.g. log, debug, info, warn, error).""" message: Optional[str] = None + """Log message text.""" message_template: Optional[str] = FieldInfo(alias="messageTemplate", default=None) + """Templatized version of the log message used for grouping similar messages.""" metric_name: Optional[str] = FieldInfo(alias="metricName", default=None) + """Metric name when the event represents a metric data point.""" origin: Optional[str] = None + """Origin of the event (e.g. fetch, scheduled, queue).""" parent_span_id: Optional[str] = FieldInfo(alias="parentSpanId", default=None) + """Span ID of the parent span in the trace hierarchy.""" provider: Optional[str] = None + """Infrastructure provider identifier.""" region: Optional[str] = None + """Cloudflare data center / region that handled the request.""" request_id: Optional[str] = FieldInfo(alias="requestId", default=None) + """Cloudflare request ID that ties all logs from a single invocation together.""" service: Optional[str] = None + """Worker script name that produced this event.""" span_id: Optional[str] = FieldInfo(alias="spanId", default=None) + """Span ID for this individual unit of work within a trace.""" span_name: Optional[str] = FieldInfo(alias="spanName", default=None) + """Human-readable name for this span.""" stack_id: Optional[str] = FieldInfo(alias="stackId", default=None) + """Stack / deployment identifier.""" start_time: Optional[int] = FieldInfo(alias="startTime", default=None) + """Span start time as a Unix epoch in milliseconds.""" status_code: Optional[int] = FieldInfo(alias="statusCode", default=None) + """HTTP response status code returned by the Worker.""" trace_duration: Optional[int] = FieldInfo(alias="traceDuration", default=None) + """Total duration of the entire trace in milliseconds.""" trace_id: Optional[str] = FieldInfo(alias="traceId", default=None) + """Distributed trace ID linking spans across services.""" transaction_name: Optional[str] = FieldInfo(alias="transactionName", default=None) + """Logical transaction name for this request.""" trigger: Optional[str] = None + """What triggered the invocation (e.g. GET /users, POST /orders, queue message).""" type: Optional[str] = None + """Event type classifier (e.g. cf-worker-event, cf-worker-log).""" url: Optional[str] = None + """Request URL that triggered the Worker invocation.""" class EventsEventWorkersUnionMember0ScriptVersion(BaseModel): @@ -576,6 +666,10 @@ class EventsEventWorkersUnionMember0(BaseModel): alias="scriptVersion", default=None ) + span_id: Optional[str] = FieldInfo(alias="spanId", default=None) + + trace_id: Optional[str] = FieldInfo(alias="traceId", default=None) + truncated: Optional[bool] = None @@ -628,6 +722,10 @@ class EventsEventWorkersUnionMember1(BaseModel): alias="scriptVersion", default=None ) + span_id: Optional[str] = FieldInfo(alias="spanId", default=None) + + trace_id: Optional[str] = FieldInfo(alias="traceId", default=None) + truncated: Optional[bool] = None @@ -635,33 +733,47 @@ class EventsEventWorkersUnionMember1(BaseModel): class EventsEvent(BaseModel): - """The data structure of a telemetry event""" + """ + A single telemetry event representing a log line, span, or metric data point emitted by a Worker. + """ metadata: EventsEventMetadata = FieldInfo(alias="$metadata") + """Structured metadata extracted from the event. + + These fields are indexed and available for filtering and aggregation. + """ dataset: str + """The dataset this event belongs to (e.g. cloudflare-workers).""" source: Union[str, object] + """Raw log payload. + + May be a string or a structured object depending on how the log was emitted. + """ timestamp: int + """Event timestamp as a Unix epoch in milliseconds.""" containers: Optional[object] = FieldInfo(alias="$containers", default=None) """ - Cloudflare Containers event information enriches your logs so you can easily - identify and debug issues. + Cloudflare Containers event information that enriches your logs for identifying + and debugging issues. """ workers: Optional[EventsEventWorkers] = FieldInfo(alias="$workers", default=None) """ - Cloudflare Workers event information enriches your logs so you can easily - identify and debug issues. + Cloudflare Workers event information that enriches your logs for identifying and + debugging issues. """ class EventsField(BaseModel): key: str + """Field name present in the matched events.""" type: str + """Data type of the field (string, number, or boolean).""" class EventsSeriesDataAggregates(BaseModel): @@ -698,78 +810,128 @@ class EventsSeries(BaseModel): class Events(BaseModel): + """Individual event results. + + Present when the query view is 'events'. Contains the matching log lines and their metadata. + """ + count: Optional[float] = None + """ + Total number of events matching the query (may exceed the number returned due to + limits). + """ events: Optional[List[EventsEvent]] = None + """List of individual telemetry events matching the query.""" fields: Optional[List[EventsField]] = None + """List of fields discovered in the matched events. + + Useful for building dynamic UIs. + """ series: Optional[List[EventsSeries]] = None + """Time-series data for the matched events, bucketed by the query granularity.""" class InvocationMetadata(BaseModel): + """Structured metadata extracted from the event. + + These fields are indexed and available for filtering and aggregation. + """ + id: str - """Unique event ID. Use as the cursor for offset-based pagination.""" + """Unique event ID. Use as the cursor value for offset-based pagination.""" account: Optional[str] = None + """Cloudflare account identifier.""" cloud_service: Optional[str] = FieldInfo(alias="cloudService", default=None) + """Cloudflare product that generated this event (e.g. workers, pages).""" cold_start: Optional[int] = FieldInfo(alias="coldStart", default=None) + """Whether this was a cold start (1) or warm invocation (0).""" cost: Optional[int] = None + """Estimated cost units for this invocation.""" duration: Optional[int] = None + """Span duration in milliseconds.""" end_time: Optional[int] = FieldInfo(alias="endTime", default=None) + """Span end time as a Unix epoch in milliseconds.""" error: Optional[str] = None + """Error message, present when the log represents an error.""" error_template: Optional[str] = FieldInfo(alias="errorTemplate", default=None) + """Templatized version of the error message used for grouping similar errors.""" fingerprint: Optional[str] = None + """Content-based fingerprint used to group similar events.""" level: Optional[str] = None + """Log level (e.g. log, debug, info, warn, error).""" message: Optional[str] = None + """Log message text.""" message_template: Optional[str] = FieldInfo(alias="messageTemplate", default=None) + """Templatized version of the log message used for grouping similar messages.""" metric_name: Optional[str] = FieldInfo(alias="metricName", default=None) + """Metric name when the event represents a metric data point.""" origin: Optional[str] = None + """Origin of the event (e.g. fetch, scheduled, queue).""" parent_span_id: Optional[str] = FieldInfo(alias="parentSpanId", default=None) + """Span ID of the parent span in the trace hierarchy.""" provider: Optional[str] = None + """Infrastructure provider identifier.""" region: Optional[str] = None + """Cloudflare data center / region that handled the request.""" request_id: Optional[str] = FieldInfo(alias="requestId", default=None) + """Cloudflare request ID that ties all logs from a single invocation together.""" service: Optional[str] = None + """Worker script name that produced this event.""" span_id: Optional[str] = FieldInfo(alias="spanId", default=None) + """Span ID for this individual unit of work within a trace.""" span_name: Optional[str] = FieldInfo(alias="spanName", default=None) + """Human-readable name for this span.""" stack_id: Optional[str] = FieldInfo(alias="stackId", default=None) + """Stack / deployment identifier.""" start_time: Optional[int] = FieldInfo(alias="startTime", default=None) + """Span start time as a Unix epoch in milliseconds.""" status_code: Optional[int] = FieldInfo(alias="statusCode", default=None) + """HTTP response status code returned by the Worker.""" trace_duration: Optional[int] = FieldInfo(alias="traceDuration", default=None) + """Total duration of the entire trace in milliseconds.""" trace_id: Optional[str] = FieldInfo(alias="traceId", default=None) + """Distributed trace ID linking spans across services.""" transaction_name: Optional[str] = FieldInfo(alias="transactionName", default=None) + """Logical transaction name for this request.""" trigger: Optional[str] = None + """What triggered the invocation (e.g. GET /users, POST /orders, queue message).""" type: Optional[str] = None + """Event type classifier (e.g. cf-worker-event, cf-worker-log).""" url: Optional[str] = None + """Request URL that triggered the Worker invocation.""" class InvocationWorkersUnionMember0ScriptVersion(BaseModel): @@ -803,6 +965,10 @@ class InvocationWorkersUnionMember0(BaseModel): alias="scriptVersion", default=None ) + span_id: Optional[str] = FieldInfo(alias="spanId", default=None) + + trace_id: Optional[str] = FieldInfo(alias="traceId", default=None) + truncated: Optional[bool] = None @@ -855,6 +1021,10 @@ class InvocationWorkersUnionMember1(BaseModel): alias="scriptVersion", default=None ) + span_id: Optional[str] = FieldInfo(alias="spanId", default=None) + + trace_id: Optional[str] = FieldInfo(alias="traceId", default=None) + truncated: Optional[bool] = None @@ -862,67 +1032,126 @@ class InvocationWorkersUnionMember1(BaseModel): class Invocation(BaseModel): - """The data structure of a telemetry event""" + """ + A single telemetry event representing a log line, span, or metric data point emitted by a Worker. + """ metadata: InvocationMetadata = FieldInfo(alias="$metadata") + """Structured metadata extracted from the event. + + These fields are indexed and available for filtering and aggregation. + """ dataset: str + """The dataset this event belongs to (e.g. cloudflare-workers).""" source: Union[str, object] + """Raw log payload. + + May be a string or a structured object depending on how the log was emitted. + """ timestamp: int + """Event timestamp as a Unix epoch in milliseconds.""" containers: Optional[object] = FieldInfo(alias="$containers", default=None) """ - Cloudflare Containers event information enriches your logs so you can easily - identify and debug issues. + Cloudflare Containers event information that enriches your logs for identifying + and debugging issues. """ workers: Optional[InvocationWorkers] = FieldInfo(alias="$workers", default=None) """ - Cloudflare Workers event information enriches your logs so you can easily - identify and debug issues. + Cloudflare Workers event information that enriches your logs for identifying and + debugging issues. """ class Trace(BaseModel): root_span_name: str = FieldInfo(alias="rootSpanName") + """Name of the root span that initiated the trace.""" root_transaction_name: str = FieldInfo(alias="rootTransactionName") + """Logical transaction name for the root span.""" service: List[str] + """List of Worker services involved in the trace.""" spans: float + """Total number of spans in the trace.""" trace_duration_ms: float = FieldInfo(alias="traceDurationMs") + """Total duration of the trace in milliseconds.""" trace_end_ms: float = FieldInfo(alias="traceEndMs") + """Trace end time as a Unix epoch in milliseconds.""" trace_id: str = FieldInfo(alias="traceId") + """Unique identifier for the distributed trace.""" trace_start_ms: float = FieldInfo(alias="traceStartMs") + """Trace start time as a Unix epoch in milliseconds.""" errors: Optional[List[str]] = None + """Error messages encountered during the trace, if any.""" class TelemetryQueryResponse(BaseModel): + """Complete results of a query run. + + The populated fields depend on the requested view type (events, calculations, invocations, traces, or agents). + """ + run: Run - """A Workers Observability Query Object""" + """ + The query run metadata including the query definition, execution status, and + timeframe. + """ statistics: Statistics - """ - The statistics object contains information about query performance from the - database, it does not include any network latency + """Query performance statistics from the database. + + Includes execution time, rows scanned, and bytes read. Does not include network + latency. """ agents: Optional[List[Agent]] = None + """Durable Object agent summaries. + + Present when the query view is 'agents'. Each entry represents an agent with its + event counts and status. + """ calculations: Optional[List[Calculation]] = None + """Aggregated calculation results. + + Present when the query view is 'calculations'. Contains computed metrics (count, + avg, p99, etc.) with optional group-by breakdowns and time-series data. + """ compare: Optional[List[Compare]] = None + """Comparison calculation results from the previous time period. + + Present when the compare option is enabled. Same structure as calculations. + """ events: Optional[Events] = None + """Individual event results. + + Present when the query view is 'events'. Contains the matching log lines and + their metadata. + """ invocations: Optional[Dict[str, List[Invocation]]] = None + """Events grouped by invocation (request ID). + + Present when the query view is 'invocations'. Each key is a request ID mapping + to all events from that invocation. + """ traces: Optional[List[Trace]] = None + """Trace summaries matching the query. + + Present when the query view is 'traces'. Each entry represents a distributed + trace with its spans, duration, and services involved. + """ diff --git a/src/cloudflare/types/workers/observability/telemetry_values_params.py b/src/cloudflare/types/workers/observability/telemetry_values_params.py index 9451743e295..a42192593ea 100644 --- a/src/cloudflare/types/workers/observability/telemetry_values_params.py +++ b/src/cloudflare/types/workers/observability/telemetry_values_params.py @@ -13,6 +13,9 @@ "Timeframe", "Filter", "FilterUnionMember0", + "FilterUnionMember0Filter", + "FilterUnionMember0FilterUnionMember0", + "FilterUnionMember0FilterWorkersObservabilityFilterLeaf", "FilterWorkersObservabilityFilterLeaf", "Needle", ] @@ -39,7 +42,10 @@ class TelemetryValuesParams(TypedDict, total=False): limit: float needle: Needle - """Search for a specific substring in the event.""" + """ + Full-text search expression to match events containing the specified text or + pattern. + """ _TimeframeReservedKeywords = TypedDict( @@ -55,7 +61,7 @@ class Timeframe(_TimeframeReservedKeywords, total=False): to: Required[float] -class FilterUnionMember0(TypedDict, total=False): +class FilterUnionMember0FilterUnionMember0(TypedDict, total=False): filter_combination: Required[Annotated[Literal["and", "or", "AND", "OR"], PropertyInfo(alias="filterCombination")]] filters: Required[Iterable[object]] @@ -63,17 +69,106 @@ class FilterUnionMember0(TypedDict, total=False): kind: Required[Literal["group"]] -class FilterWorkersObservabilityFilterLeaf(TypedDict, total=False): +class FilterUnionMember0FilterWorkersObservabilityFilterLeaf(TypedDict, total=False): + """A filter condition applied to query results. + + Use the keys and values endpoints to discover available fields and their values before constructing filters. """ - Filtering best practices: use observability_keys and observability_values to confirm available fields and values. If searching for errors, filter for $metadata.error exists. + + key: Required[str] + """Filter field name. + + Use verified keys from previous query results or the keys endpoint. Common keys + include $metadata.service, $metadata.origin, $metadata.trigger, + $metadata.message, and $metadata.error. + """ + + operation: Required[ + Literal[ + "includes", + "not_includes", + "starts_with", + "regex", + "exists", + "is_null", + "in", + "not_in", + "eq", + "neq", + "gt", + "gte", + "lt", + "lte", + "=", + "!=", + ">", + ">=", + "<", + "<=", + "INCLUDES", + "DOES_NOT_INCLUDE", + "MATCH_REGEX", + "EXISTS", + "DOES_NOT_EXIST", + "IN", + "NOT_IN", + "STARTS_WITH", + ] + ] + """Comparison operator. + + String operators: includes, not_includes, starts_with, regex. Existence: exists, + is_null. Set membership: in, not_in (comma-separated values). Numeric: eq, neq, + gt, gte, lt, lte. + """ + + type: Required[Literal["string", "number", "boolean"]] + """Data type of the filter field. + + Must match the actual type of the key being filtered. + """ + + kind: Literal["filter"] + """Discriminator for leaf filter nodes. + + Always 'filter' when present; may be omitted. + """ + + value: Union[str, float, bool] + """Comparison value. + + Must match actual values in your data — verify with the values endpoint. Ensure + the value type (string/number/boolean) matches the field type. String + comparisons are case-sensitive. Regex uses RE2 syntax (no + lookaheads/lookbehinds). + """ + + +FilterUnionMember0Filter: TypeAlias = Union[ + FilterUnionMember0FilterUnionMember0, FilterUnionMember0FilterWorkersObservabilityFilterLeaf +] + + +class FilterUnionMember0(TypedDict, total=False): + filter_combination: Required[Annotated[Literal["and", "or", "AND", "OR"], PropertyInfo(alias="filterCombination")]] + + filters: Required[Iterable[FilterUnionMember0Filter]] + + kind: Required[Literal["group"]] + + +class FilterWorkersObservabilityFilterLeaf(TypedDict, total=False): + """A filter condition applied to query results. + + Use the keys and values endpoints to discover available fields and their values before constructing filters. """ key: Required[str] """Filter field name. - IMPORTANT: do not guess keys. Always use verified keys from previous query - results or the observability_keys response. Preferred keys: $metadata.service, - $metadata.origin, $metadata.trigger, $metadata.message, $metadata.error. + Use verified keys from previous query results or the keys endpoint. Common keys + include $metadata.service, $metadata.origin, $metadata.trigger, + $metadata.message, and $metadata.error. """ operation: Required[ @@ -108,19 +203,32 @@ class FilterWorkersObservabilityFilterLeaf(TypedDict, total=False): "STARTS_WITH", ] ] + """Comparison operator. + + String operators: includes, not_includes, starts_with, regex. Existence: exists, + is_null. Set membership: in, not_in (comma-separated values). Numeric: eq, neq, + gt, gte, lt, lte. + """ type: Required[Literal["string", "number", "boolean"]] + """Data type of the filter field. + + Must match the actual type of the key being filtered. + """ kind: Literal["filter"] + """Discriminator for leaf filter nodes. + + Always 'filter' when present; may be omitted. + """ value: Union[str, float, bool] - """Filter comparison value. + """Comparison value. - IMPORTANT: must match actual values in your logs. Verify using previous query - results or the /values endpoint. Ensure value type matches the field type. - String comparisons are case-sensitive unless using specific operations. Regex - uses ClickHouse RE2 syntax (no lookaheads/lookbehinds); examples: ^5\\dd{2}$ for - HTTP 5xx, \bERROR\b for word boundary. + Must match actual values in your data — verify with the values endpoint. Ensure + the value type (string/number/boolean) matches the field type. String + comparisons are case-sensitive. Regex uses RE2 syntax (no + lookaheads/lookbehinds). """ @@ -128,10 +236,15 @@ class FilterWorkersObservabilityFilterLeaf(TypedDict, total=False): class Needle(TypedDict, total=False): - """Search for a specific substring in the event.""" + """ + Full-text search expression to match events containing the specified text or pattern. + """ value: Required[Union[str, float, bool]] + """The text or pattern to search for.""" is_regex: Annotated[bool, PropertyInfo(alias="isRegex")] + """When true, treats the value as a regular expression (RE2 syntax).""" match_case: Annotated[bool, PropertyInfo(alias="matchCase")] + """When true, performs a case-sensitive search. Defaults to case-insensitive.""" diff --git a/src/cloudflare/types/workers/script_update_params.py b/src/cloudflare/types/workers/script_update_params.py index fab83dc8675..87d31dee903 100644 --- a/src/cloudflare/types/workers/script_update_params.py +++ b/src/cloudflare/types/workers/script_update_params.py @@ -462,6 +462,13 @@ class MetadataBindingWorkersBindingKindRatelimitSimple(TypedDict, total=False): period: Required[int] """The period in seconds.""" + mitigation_timeout: int + """ + Duration in seconds to apply the mitigation action after the rate limit is + exceeded. Valid values are 0 (disabled), 10, or multiples of 60 up to 86400. + Must be greater than or equal to the period when non-zero. + """ + class MetadataBindingWorkersBindingKindRatelimit(TypedDict, total=False): name: Required[str] diff --git a/src/cloudflare/types/workers/scripts/script_and_version_setting_edit_params.py b/src/cloudflare/types/workers/scripts/script_and_version_setting_edit_params.py index 4307e6a11f3..6429f45ae6e 100644 --- a/src/cloudflare/types/workers/scripts/script_and_version_setting_edit_params.py +++ b/src/cloudflare/types/workers/scripts/script_and_version_setting_edit_params.py @@ -394,6 +394,13 @@ class SettingsBindingWorkersBindingKindRatelimitSimple(TypedDict, total=False): period: Required[int] """The period in seconds.""" + mitigation_timeout: int + """ + Duration in seconds to apply the mitigation action after the rate limit is + exceeded. Valid values are 0 (disabled), 10, or multiples of 60 up to 86400. + Must be greater than or equal to the period when non-zero. + """ + class SettingsBindingWorkersBindingKindRatelimit(TypedDict, total=False): name: Required[str] diff --git a/src/cloudflare/types/workers/scripts/script_and_version_setting_edit_response.py b/src/cloudflare/types/workers/scripts/script_and_version_setting_edit_response.py index 0e750e5f8d3..067b2732892 100644 --- a/src/cloudflare/types/workers/scripts/script_and_version_setting_edit_response.py +++ b/src/cloudflare/types/workers/scripts/script_and_version_setting_edit_response.py @@ -391,6 +391,13 @@ class BindingWorkersBindingKindRatelimitSimple(BaseModel): period: int """The period in seconds.""" + mitigation_timeout: Optional[int] = None + """ + Duration in seconds to apply the mitigation action after the rate limit is + exceeded. Valid values are 0 (disabled), 10, or multiples of 60 up to 86400. + Must be greater than or equal to the period when non-zero. + """ + class BindingWorkersBindingKindRatelimit(BaseModel): name: str diff --git a/src/cloudflare/types/workers/scripts/script_and_version_setting_get_response.py b/src/cloudflare/types/workers/scripts/script_and_version_setting_get_response.py index 5349c407900..0ef9c3aa1d2 100644 --- a/src/cloudflare/types/workers/scripts/script_and_version_setting_get_response.py +++ b/src/cloudflare/types/workers/scripts/script_and_version_setting_get_response.py @@ -391,6 +391,13 @@ class BindingWorkersBindingKindRatelimitSimple(BaseModel): period: int """The period in seconds.""" + mitigation_timeout: Optional[int] = None + """ + Duration in seconds to apply the mitigation action after the rate limit is + exceeded. Valid values are 0 (disabled), 10, or multiples of 60 up to 86400. + Must be greater than or equal to the period when non-zero. + """ + class BindingWorkersBindingKindRatelimit(BaseModel): name: str diff --git a/src/cloudflare/types/workers/scripts/version_create_params.py b/src/cloudflare/types/workers/scripts/version_create_params.py index 1d985b2f937..0e8a9292025 100644 --- a/src/cloudflare/types/workers/scripts/version_create_params.py +++ b/src/cloudflare/types/workers/scripts/version_create_params.py @@ -389,6 +389,13 @@ class MetadataBindingWorkersBindingKindRatelimitSimple(TypedDict, total=False): period: Required[int] """The period in seconds.""" + mitigation_timeout: int + """ + Duration in seconds to apply the mitigation action after the rate limit is + exceeded. Valid values are 0 (disabled), 10, or multiples of 60 up to 86400. + Must be greater than or equal to the period when non-zero. + """ + class MetadataBindingWorkersBindingKindRatelimit(TypedDict, total=False): name: Required[str] diff --git a/src/cloudflare/types/workers/scripts/version_create_response.py b/src/cloudflare/types/workers/scripts/version_create_response.py index 005dc5468ea..19a0770d43f 100644 --- a/src/cloudflare/types/workers/scripts/version_create_response.py +++ b/src/cloudflare/types/workers/scripts/version_create_response.py @@ -356,6 +356,13 @@ class ResourcesBindingWorkersBindingKindRatelimitSimple(BaseModel): period: int """The period in seconds.""" + mitigation_timeout: Optional[int] = None + """ + Duration in seconds to apply the mitigation action after the rate limit is + exceeded. Valid values are 0 (disabled), 10, or multiples of 60 up to 86400. + Must be greater than or equal to the period when non-zero. + """ + class ResourcesBindingWorkersBindingKindRatelimit(BaseModel): name: str diff --git a/src/cloudflare/types/workers/scripts/version_get_response.py b/src/cloudflare/types/workers/scripts/version_get_response.py index 3174e861c13..6dd42eceb0d 100644 --- a/src/cloudflare/types/workers/scripts/version_get_response.py +++ b/src/cloudflare/types/workers/scripts/version_get_response.py @@ -356,6 +356,13 @@ class ResourcesBindingWorkersBindingKindRatelimitSimple(BaseModel): period: int """The period in seconds.""" + mitigation_timeout: Optional[int] = None + """ + Duration in seconds to apply the mitigation action after the rate limit is + exceeded. Valid values are 0 (disabled), 10, or multiples of 60 up to 86400. + Must be greater than or equal to the period when non-zero. + """ + class ResourcesBindingWorkersBindingKindRatelimit(BaseModel): name: str diff --git a/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/script_update_params.py b/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/script_update_params.py index ff2bf226887..1ee5fdc4238 100644 --- a/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/script_update_params.py +++ b/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/script_update_params.py @@ -453,6 +453,13 @@ class MetadataBindingWorkersBindingKindRatelimitSimple(TypedDict, total=False): period: Required[int] """The period in seconds.""" + mitigation_timeout: int + """ + Duration in seconds to apply the mitigation action after the rate limit is + exceeded. Valid values are 0 (disabled), 10, or multiples of 60 up to 86400. + Must be greater than or equal to the period when non-zero. + """ + class MetadataBindingWorkersBindingKindRatelimit(TypedDict, total=False): name: Required[str] diff --git a/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/binding_get_response.py b/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/binding_get_response.py index 6b3ccd16c1b..a6d931b6a1b 100644 --- a/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/binding_get_response.py +++ b/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/binding_get_response.py @@ -349,6 +349,13 @@ class WorkersBindingKindRatelimitSimple(BaseModel): period: int """The period in seconds.""" + mitigation_timeout: Optional[int] = None + """ + Duration in seconds to apply the mitigation action after the rate limit is + exceeded. Valid values are 0 (disabled), 10, or multiples of 60 up to 86400. + Must be greater than or equal to the period when non-zero. + """ + class WorkersBindingKindRatelimit(BaseModel): name: str diff --git a/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/secret_get_response.py b/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/secret_get_response.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/setting_edit_params.py b/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/setting_edit_params.py index f11ee4e853d..949f1600882 100644 --- a/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/setting_edit_params.py +++ b/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/setting_edit_params.py @@ -387,6 +387,13 @@ class SettingsBindingWorkersBindingKindRatelimitSimple(TypedDict, total=False): period: Required[int] """The period in seconds.""" + mitigation_timeout: int + """ + Duration in seconds to apply the mitigation action after the rate limit is + exceeded. Valid values are 0 (disabled), 10, or multiples of 60 up to 86400. + Must be greater than or equal to the period when non-zero. + """ + class SettingsBindingWorkersBindingKindRatelimit(TypedDict, total=False): name: Required[str] diff --git a/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/setting_edit_response.py b/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/setting_edit_response.py index 260a281de41..e6df38c5dce 100644 --- a/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/setting_edit_response.py +++ b/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/setting_edit_response.py @@ -371,6 +371,13 @@ class BindingWorkersBindingKindRatelimitSimple(BaseModel): period: int """The period in seconds.""" + mitigation_timeout: Optional[int] = None + """ + Duration in seconds to apply the mitigation action after the rate limit is + exceeded. Valid values are 0 (disabled), 10, or multiples of 60 up to 86400. + Must be greater than or equal to the period when non-zero. + """ + class BindingWorkersBindingKindRatelimit(BaseModel): name: str diff --git a/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/setting_get_response.py b/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/setting_get_response.py index d4ac77f860a..071d860cc89 100644 --- a/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/setting_get_response.py +++ b/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/setting_get_response.py @@ -371,6 +371,13 @@ class BindingWorkersBindingKindRatelimitSimple(BaseModel): period: int """The period in seconds.""" + mitigation_timeout: Optional[int] = None + """ + Duration in seconds to apply the mitigation action after the rate limit is + exceeded. Valid values are 0 (disabled), 10, or multiples of 60 up to 86400. + Must be greater than or equal to the period when non-zero. + """ + class BindingWorkersBindingKindRatelimit(BaseModel): name: str diff --git a/src/cloudflare/types/zero_trust/access/applications/policy_test_create_params.py b/src/cloudflare/types/zero_trust/access/applications/policy_test_create_params.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/types/zero_trust/access/applications/policy_test_create_response.py b/src/cloudflare/types/zero_trust/access/applications/policy_test_create_response.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/types/zero_trust/access/applications/policy_test_get_response.py b/src/cloudflare/types/zero_trust/access/applications/policy_test_get_response.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/types/zero_trust/access/applications/policy_tests/user_list_response.py b/src/cloudflare/types/zero_trust/access/applications/policy_tests/user_list_response.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/types/zero_trust/devices/__init__.py b/src/cloudflare/types/zero_trust/devices/__init__.py index b8a661717f2..55f3b9bb218 100644 --- a/src/cloudflare/types/zero_trust/devices/__init__.py +++ b/src/cloudflare/types/zero_trust/devices/__init__.py @@ -14,6 +14,7 @@ from .device_settings import DeviceSettings as DeviceSettings from .fallback_domain import FallbackDomain as FallbackDomain from .settings_policy import SettingsPolicy as SettingsPolicy +from .deployment_group import DeploymentGroup as DeploymentGroup from .file_input_param import FileInputParam as FileInputParam from .os_version_input import OSVersionInput as OSVersionInput from .carbonblack_input import CarbonblackInput as CarbonblackInput @@ -80,7 +81,11 @@ from .split_tunnel_include_param import SplitTunnelIncludeParam as SplitTunnelIncludeParam from .disk_encryption_input_param import DiskEncryptionInputParam as DiskEncryptionInputParam from .sentinelone_s2s_input_param import SentineloneS2sInputParam as SentineloneS2sInputParam +from .deployment_group_edit_params import DeploymentGroupEditParams as DeploymentGroupEditParams +from .deployment_group_list_params import DeploymentGroupListParams as DeploymentGroupListParams from .registration_unrevoke_params import RegistrationUnrevokeParams as RegistrationUnrevokeParams from .unique_client_id_input_param import UniqueClientIDInputParam as UniqueClientIDInputParam from .client_certificate_input_param import ClientCertificateInputParam as ClientCertificateInputParam +from .deployment_group_create_params import DeploymentGroupCreateParams as DeploymentGroupCreateParams from .registration_bulk_delete_params import RegistrationBulkDeleteParams as RegistrationBulkDeleteParams +from .deployment_group_delete_response import DeploymentGroupDeleteResponse as DeploymentGroupDeleteResponse diff --git a/src/cloudflare/types/zero_trust/devices/deployment_group.py b/src/cloudflare/types/zero_trust/devices/deployment_group.py new file mode 100644 index 00000000000..e85073b3be9 --- /dev/null +++ b/src/cloudflare/types/zero_trust/devices/deployment_group.py @@ -0,0 +1,35 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from ...._models import BaseModel + +__all__ = ["DeploymentGroup", "VersionConfig"] + + +class VersionConfig(BaseModel): + target_environment: Optional[str] = None + """The target environment for the client version (e.g., windows, macos).""" + + version: str + """The specific client version to deploy.""" + + +class DeploymentGroup(BaseModel): + id: str + """The ID of the deployment group.""" + + created_at: str + """The RFC3339Nano timestamp when the deployment group was created.""" + + name: str + """A user-friendly name for the deployment group.""" + + updated_at: str + """The RFC3339Nano timestamp when the deployment group was last updated.""" + + version_config: List[VersionConfig] + """Contains version configurations for different target environments.""" + + policy_ids: Optional[List[str]] = None + """Contains a list of policy IDs assigned to this deployment group.""" diff --git a/src/cloudflare/types/zero_trust/devices/deployment_group_create_params.py b/src/cloudflare/types/zero_trust/devices/deployment_group_create_params.py new file mode 100644 index 00000000000..3cacec4ffe9 --- /dev/null +++ b/src/cloudflare/types/zero_trust/devices/deployment_group_create_params.py @@ -0,0 +1,31 @@ +# 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 Required, TypedDict + +from ...._types import SequenceNotStr + +__all__ = ["DeploymentGroupCreateParams", "VersionConfig"] + + +class DeploymentGroupCreateParams(TypedDict, total=False): + account_id: Required[str] + + name: Required[str] + """A user-friendly name for the deployment group.""" + + version_config: Required[Iterable[VersionConfig]] + """Contains at least one version configuration.""" + + policy_ids: SequenceNotStr[str] + """Contains an optional list of policy IDs assigned to a group.""" + + +class VersionConfig(TypedDict, total=False): + target_environment: Required[Optional[str]] + """The target environment for the client version (e.g., windows, macos).""" + + version: Required[str] + """The specific client version to deploy.""" diff --git a/src/cloudflare/types/zero_trust/devices/deployment_group_delete_response.py b/src/cloudflare/types/zero_trust/devices/deployment_group_delete_response.py new file mode 100644 index 00000000000..39c4b672b0f --- /dev/null +++ b/src/cloudflare/types/zero_trust/devices/deployment_group_delete_response.py @@ -0,0 +1,12 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from ...._models import BaseModel + +__all__ = ["DeploymentGroupDeleteResponse"] + + +class DeploymentGroupDeleteResponse(BaseModel): + id: Optional[str] = None + """The ID of a deleted deployment group.""" diff --git a/src/cloudflare/types/zero_trust/devices/deployment_group_edit_params.py b/src/cloudflare/types/zero_trust/devices/deployment_group_edit_params.py new file mode 100644 index 00000000000..843dab242f1 --- /dev/null +++ b/src/cloudflare/types/zero_trust/devices/deployment_group_edit_params.py @@ -0,0 +1,31 @@ +# 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 Required, TypedDict + +from ...._types import SequenceNotStr + +__all__ = ["DeploymentGroupEditParams", "VersionConfig"] + + +class DeploymentGroupEditParams(TypedDict, total=False): + account_id: Required[str] + + name: str + """A user-friendly name for the deployment group.""" + + policy_ids: SequenceNotStr[str] + """Replaces the entire list of policy IDs.""" + + version_config: Iterable[VersionConfig] + """Replaces the entire version_config array.""" + + +class VersionConfig(TypedDict, total=False): + target_environment: Required[Optional[str]] + """The target environment for the client version (e.g., windows, macos).""" + + version: Required[str] + """The specific client version to deploy.""" diff --git a/src/cloudflare/types/zero_trust/devices/deployment_group_list_params.py b/src/cloudflare/types/zero_trust/devices/deployment_group_list_params.py new file mode 100644 index 00000000000..4c0295b4169 --- /dev/null +++ b/src/cloudflare/types/zero_trust/devices/deployment_group_list_params.py @@ -0,0 +1,17 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["DeploymentGroupListParams"] + + +class DeploymentGroupListParams(TypedDict, total=False): + account_id: Required[str] + + page: int + """The page number to return.""" + + per_page: int + """The maximum number of deployment groups to return per page.""" diff --git a/src/cloudflare/types/zero_trust/devices/kolide_input.py b/src/cloudflare/types/zero_trust/devices/kolide_input.py index a18da6e1fcc..34f8b1534a0 100644 --- a/src/cloudflare/types/zero_trust/devices/kolide_input.py +++ b/src/cloudflare/types/zero_trust/devices/kolide_input.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import Optional from typing_extensions import Literal from pydantic import Field as FieldInfo @@ -14,12 +14,6 @@ class KolideInput(BaseModel): connection_id: str """Posture Integration ID.""" - auth_state: Optional[List[Literal["Good", "Notified", "Will Block", "Blocked"]]] = None - """The set of Kolide device authentication states that pass the posture check. - - Device must match one of the specified states. - """ - count_operator: Optional[Literal["<", "<=", ">", ">=", "=="]] = FieldInfo(alias="countOperator", default=None) """Count Operator.""" diff --git a/src/cloudflare/types/zero_trust/devices/kolide_input_param.py b/src/cloudflare/types/zero_trust/devices/kolide_input_param.py index 85990a105bb..2876e3bc9b6 100644 --- a/src/cloudflare/types/zero_trust/devices/kolide_input_param.py +++ b/src/cloudflare/types/zero_trust/devices/kolide_input_param.py @@ -2,7 +2,6 @@ from __future__ import annotations -from typing import List from typing_extensions import Literal, Required, Annotated, TypedDict from ...._utils import PropertyInfo @@ -14,12 +13,6 @@ class KolideInputParam(TypedDict, total=False): connection_id: Required[str] """Posture Integration ID.""" - auth_state: List[Literal["Good", "Notified", "Will Block", "Blocked"]] - """The set of Kolide device authentication states that pass the posture check. - - Device must match one of the specified states. - """ - count_operator: Annotated[Literal["<", "<=", ">", ">=", "=="], PropertyInfo(alias="countOperator")] """Count Operator.""" diff --git a/src/cloudflare/types/zero_trust/devices/policies/custom_create_params.py b/src/cloudflare/types/zero_trust/devices/policies/custom_create_params.py index d2302201175..2712f2391aa 100644 --- a/src/cloudflare/types/zero_trust/devices/policies/custom_create_params.py +++ b/src/cloudflare/types/zero_trust/devices/policies/custom_create_params.py @@ -2,13 +2,14 @@ from __future__ import annotations -from typing import Iterable +from typing import Iterable, Optional from typing_extensions import Required, TypedDict +from ....._types import SequenceNotStr from ..split_tunnel_exclude_param import SplitTunnelExcludeParam from ..split_tunnel_include_param import SplitTunnelIncludeParam -__all__ = ["CustomCreateParams", "ServiceModeV2"] +__all__ = ["CustomCreateParams", "ServiceModeV2", "VirtualNetworks"] class CustomCreateParams(TypedDict, total=False): @@ -117,6 +118,9 @@ class CustomCreateParams(TypedDict, total=False): tunnel_protocol: str """Determines which tunnel protocol to use.""" + virtual_networks: Optional[VirtualNetworks] + """Virtual network access settings for the device.""" + class ServiceModeV2(TypedDict, total=False): mode: str @@ -124,3 +128,16 @@ class ServiceModeV2(TypedDict, total=False): port: float """The port number when used with proxy mode.""" + + +class VirtualNetworks(TypedDict, total=False): + """Virtual network access settings for the device.""" + + allowed: Required[SequenceNotStr[str]] + """List of virtual network IDs the device is allowed to access. + + When virtual_networks is set, at least one entry is required. + """ + + default: Required[str] + """The default virtual network ID. Must be included in the `allowed` list.""" diff --git a/src/cloudflare/types/zero_trust/devices/policies/custom_edit_params.py b/src/cloudflare/types/zero_trust/devices/policies/custom_edit_params.py index 85e7e19bd3c..004fb5454bd 100644 --- a/src/cloudflare/types/zero_trust/devices/policies/custom_edit_params.py +++ b/src/cloudflare/types/zero_trust/devices/policies/custom_edit_params.py @@ -2,13 +2,14 @@ from __future__ import annotations -from typing import Iterable +from typing import Iterable, Optional from typing_extensions import Required, TypedDict +from ....._types import SequenceNotStr from ..split_tunnel_exclude_param import SplitTunnelExcludeParam from ..split_tunnel_include_param import SplitTunnelIncludeParam -__all__ = ["CustomEditParams", "ServiceModeV2"] +__all__ = ["CustomEditParams", "ServiceModeV2", "VirtualNetworks"] class CustomEditParams(TypedDict, total=False): @@ -117,6 +118,9 @@ class CustomEditParams(TypedDict, total=False): tunnel_protocol: str """Determines which tunnel protocol to use.""" + virtual_networks: Optional[VirtualNetworks] + """Virtual network access settings for the device.""" + class ServiceModeV2(TypedDict, total=False): mode: str @@ -124,3 +128,16 @@ class ServiceModeV2(TypedDict, total=False): port: float """The port number when used with proxy mode.""" + + +class VirtualNetworks(TypedDict, total=False): + """Virtual network access settings for the device.""" + + allowed: Required[SequenceNotStr[str]] + """List of virtual network IDs the device is allowed to access. + + When virtual_networks is set, at least one entry is required. + """ + + default: Required[str] + """The default virtual network ID. Must be included in the `allowed` list.""" diff --git a/src/cloudflare/types/zero_trust/devices/policies/default_edit_params.py b/src/cloudflare/types/zero_trust/devices/policies/default_edit_params.py index 9a6b533464c..74eb2e3ce42 100644 --- a/src/cloudflare/types/zero_trust/devices/policies/default_edit_params.py +++ b/src/cloudflare/types/zero_trust/devices/policies/default_edit_params.py @@ -2,13 +2,14 @@ from __future__ import annotations -from typing import Iterable +from typing import Iterable, Optional from typing_extensions import Required, TypedDict +from ....._types import SequenceNotStr from ..split_tunnel_exclude_param import SplitTunnelExcludeParam from ..split_tunnel_include_param import SplitTunnelIncludeParam -__all__ = ["DefaultEditParams", "ServiceModeV2"] +__all__ = ["DefaultEditParams", "ServiceModeV2", "VirtualNetworks"] class DefaultEditParams(TypedDict, total=False): @@ -93,6 +94,9 @@ class DefaultEditParams(TypedDict, total=False): tunnel_protocol: str """Determines which tunnel protocol to use.""" + virtual_networks: Optional[VirtualNetworks] + """Virtual network access settings for the device.""" + class ServiceModeV2(TypedDict, total=False): mode: str @@ -100,3 +104,16 @@ class ServiceModeV2(TypedDict, total=False): port: float """The port number when used with proxy mode.""" + + +class VirtualNetworks(TypedDict, total=False): + """Virtual network access settings for the device.""" + + allowed: Required[SequenceNotStr[str]] + """List of virtual network IDs the device is allowed to access. + + When virtual_networks is set, at least one entry is required. + """ + + default: Required[str] + """The default virtual network ID. Must be included in the `allowed` list.""" diff --git a/src/cloudflare/types/zero_trust/devices/policies/default_edit_response.py b/src/cloudflare/types/zero_trust/devices/policies/default_edit_response.py index 4e512a63abc..d1eb4dca9d1 100644 --- a/src/cloudflare/types/zero_trust/devices/policies/default_edit_response.py +++ b/src/cloudflare/types/zero_trust/devices/policies/default_edit_response.py @@ -7,7 +7,7 @@ from ..split_tunnel_exclude import SplitTunnelExclude from ..split_tunnel_include import SplitTunnelInclude -__all__ = ["DefaultEditResponse", "ServiceModeV2"] +__all__ = ["DefaultEditResponse", "ServiceModeV2", "VirtualNetworks"] class ServiceModeV2(BaseModel): @@ -18,6 +18,19 @@ class ServiceModeV2(BaseModel): """The port number when used with proxy mode.""" +class VirtualNetworks(BaseModel): + """Virtual network access settings for the device.""" + + allowed: List[str] + """List of virtual network IDs the device is allowed to access. + + When virtual_networks is set, at least one entry is required. + """ + + default: str + """The default virtual network ID. Must be included in the `allowed` list.""" + + class DefaultEditResponse(BaseModel): allow_mode_switch: Optional[bool] = None """Whether to allow the user to switch WARP between modes.""" @@ -89,3 +102,6 @@ class DefaultEditResponse(BaseModel): tunnel_protocol: Optional[str] = None """Determines which tunnel protocol to use.""" + + virtual_networks: Optional[VirtualNetworks] = None + """Virtual network access settings for the device.""" diff --git a/src/cloudflare/types/zero_trust/devices/policies/default_get_response.py b/src/cloudflare/types/zero_trust/devices/policies/default_get_response.py index acdfa643df3..4fe0811461d 100644 --- a/src/cloudflare/types/zero_trust/devices/policies/default_get_response.py +++ b/src/cloudflare/types/zero_trust/devices/policies/default_get_response.py @@ -7,7 +7,7 @@ from ..split_tunnel_exclude import SplitTunnelExclude from ..split_tunnel_include import SplitTunnelInclude -__all__ = ["DefaultGetResponse", "ServiceModeV2"] +__all__ = ["DefaultGetResponse", "ServiceModeV2", "VirtualNetworks"] class ServiceModeV2(BaseModel): @@ -18,6 +18,19 @@ class ServiceModeV2(BaseModel): """The port number when used with proxy mode.""" +class VirtualNetworks(BaseModel): + """Virtual network access settings for the device.""" + + allowed: List[str] + """List of virtual network IDs the device is allowed to access. + + When virtual_networks is set, at least one entry is required. + """ + + default: str + """The default virtual network ID. Must be included in the `allowed` list.""" + + class DefaultGetResponse(BaseModel): allow_mode_switch: Optional[bool] = None """Whether to allow the user to switch WARP between modes.""" @@ -89,3 +102,6 @@ class DefaultGetResponse(BaseModel): tunnel_protocol: Optional[str] = None """Determines which tunnel protocol to use.""" + + virtual_networks: Optional[VirtualNetworks] = None + """Virtual network access settings for the device.""" diff --git a/src/cloudflare/types/zero_trust/devices/setting_edit_params.py b/src/cloudflare/types/zero_trust/devices/setting_edit_params.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/types/zero_trust/devices/settings_policy.py b/src/cloudflare/types/zero_trust/devices/settings_policy.py index dfc7f7ae559..0dbbe0ea2e2 100644 --- a/src/cloudflare/types/zero_trust/devices/settings_policy.py +++ b/src/cloudflare/types/zero_trust/devices/settings_policy.py @@ -7,7 +7,7 @@ from .split_tunnel_exclude import SplitTunnelExclude from .split_tunnel_include import SplitTunnelInclude -__all__ = ["SettingsPolicy", "ServiceModeV2", "TargetTest"] +__all__ = ["SettingsPolicy", "ServiceModeV2", "TargetTest", "VirtualNetworks"] class ServiceModeV2(BaseModel): @@ -26,6 +26,19 @@ class TargetTest(BaseModel): """The name of the DEX test targeting this policy.""" +class VirtualNetworks(BaseModel): + """Virtual network access settings for the device.""" + + allowed: List[str] + """List of virtual network IDs the device is allowed to access. + + When virtual_networks is set, at least one entry is required. + """ + + default: str + """The default virtual network ID. Must be included in the `allowed` list.""" + + class SettingsPolicy(BaseModel): allow_mode_switch: Optional[bool] = None """Whether to allow the user to switch WARP between modes.""" @@ -134,3 +147,6 @@ class SettingsPolicy(BaseModel): tunnel_protocol: Optional[str] = None """Determines which tunnel protocol to use.""" + + virtual_networks: Optional[VirtualNetworks] = None + """Virtual network access settings for the device.""" diff --git a/src/cloudflare/types/zero_trust/dlp/datasets/version_create_params.py b/src/cloudflare/types/zero_trust/dlp/datasets/version_create_params.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/types/zero_trust/dlp/datasets/version_create_response.py b/src/cloudflare/types/zero_trust/dlp/datasets/version_create_response.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/types/zero_trust/dlp/datasets/versions/entry_create_params.py b/src/cloudflare/types/zero_trust/dlp/datasets/versions/entry_create_params.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/types/zero_trust/dlp/datasets/versions/entry_create_response.py b/src/cloudflare/types/zero_trust/dlp/datasets/versions/entry_create_response.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/types/zero_trust/dlp/entries/custom_get_response.py b/src/cloudflare/types/zero_trust/dlp/entries/custom_get_response.py index 0643a73c554..d0af2de6213 100644 --- a/src/cloudflare/types/zero_trust/dlp/entries/custom_get_response.py +++ b/src/cloudflare/types/zero_trust/dlp/entries/custom_get_response.py @@ -15,6 +15,8 @@ "UnionMember1Confidence", "UnionMember1Profile", "UnionMember1Variant", + "UnionMember1VariantUnionMember0", + "UnionMember1VariantUnionMember1", "UnionMember2", "UnionMember2Profile", "UnionMember3", @@ -77,12 +79,30 @@ class UnionMember1Profile(BaseModel): name: str -class UnionMember1Variant(BaseModel): +class UnionMember1VariantUnionMember0(BaseModel): + """A Predefined AI prompt classification topic entry.""" + topic_type: Literal["Intent", "Content"] type: Literal["PromptTopic"] description: Optional[str] = None + """ + A customer-facing explanation of what this predefined AI prompt topic + represents. + """ + + +class UnionMember1VariantUnionMember1(BaseModel): + """A general predefined entry.""" + + type: Literal["General"] + + description: Optional[str] = None + """A customer-facing explanation of what this predefined entry represents.""" + + +UnionMember1Variant: TypeAlias = Union[UnionMember1VariantUnionMember0, UnionMember1VariantUnionMember1] class UnionMember1(BaseModel): @@ -103,6 +123,7 @@ class UnionMember1(BaseModel): upload_status: Optional[Literal["empty", "uploading", "pending", "processing", "failed", "complete"]] = None variant: Optional[UnionMember1Variant] = None + """A Predefined AI prompt classification topic entry.""" class UnionMember2Profile(BaseModel): diff --git a/src/cloudflare/types/zero_trust/dlp/entries/custom_list_response.py b/src/cloudflare/types/zero_trust/dlp/entries/custom_list_response.py index af4e3334fbc..c8c47ce738d 100644 --- a/src/cloudflare/types/zero_trust/dlp/entries/custom_list_response.py +++ b/src/cloudflare/types/zero_trust/dlp/entries/custom_list_response.py @@ -13,6 +13,8 @@ "UnionMember1", "UnionMember1Confidence", "UnionMember1Variant", + "UnionMember1VariantUnionMember0", + "UnionMember1VariantUnionMember1", "UnionMember2", "UnionMember3", "UnionMember4", @@ -53,12 +55,30 @@ class UnionMember1Confidence(BaseModel): """ -class UnionMember1Variant(BaseModel): +class UnionMember1VariantUnionMember0(BaseModel): + """A Predefined AI prompt classification topic entry.""" + topic_type: Literal["Intent", "Content"] type: Literal["PromptTopic"] description: Optional[str] = None + """ + A customer-facing explanation of what this predefined AI prompt topic + represents. + """ + + +class UnionMember1VariantUnionMember1(BaseModel): + """A general predefined entry.""" + + type: Literal["General"] + + description: Optional[str] = None + """A customer-facing explanation of what this predefined entry represents.""" + + +UnionMember1Variant: TypeAlias = Union[UnionMember1VariantUnionMember0, UnionMember1VariantUnionMember1] class UnionMember1(BaseModel): @@ -77,6 +97,7 @@ class UnionMember1(BaseModel): upload_status: Optional[Literal["empty", "uploading", "pending", "processing", "failed", "complete"]] = None variant: Optional[UnionMember1Variant] = None + """A Predefined AI prompt classification topic entry.""" class UnionMember2(BaseModel): diff --git a/src/cloudflare/types/zero_trust/dlp/entries/integration_get_response.py b/src/cloudflare/types/zero_trust/dlp/entries/integration_get_response.py index da9028d38d6..28c992d2143 100644 --- a/src/cloudflare/types/zero_trust/dlp/entries/integration_get_response.py +++ b/src/cloudflare/types/zero_trust/dlp/entries/integration_get_response.py @@ -15,6 +15,8 @@ "UnionMember1Confidence", "UnionMember1Profile", "UnionMember1Variant", + "UnionMember1VariantUnionMember0", + "UnionMember1VariantUnionMember1", "UnionMember2", "UnionMember2Profile", "UnionMember3", @@ -77,12 +79,30 @@ class UnionMember1Profile(BaseModel): name: str -class UnionMember1Variant(BaseModel): +class UnionMember1VariantUnionMember0(BaseModel): + """A Predefined AI prompt classification topic entry.""" + topic_type: Literal["Intent", "Content"] type: Literal["PromptTopic"] description: Optional[str] = None + """ + A customer-facing explanation of what this predefined AI prompt topic + represents. + """ + + +class UnionMember1VariantUnionMember1(BaseModel): + """A general predefined entry.""" + + type: Literal["General"] + + description: Optional[str] = None + """A customer-facing explanation of what this predefined entry represents.""" + + +UnionMember1Variant: TypeAlias = Union[UnionMember1VariantUnionMember0, UnionMember1VariantUnionMember1] class UnionMember1(BaseModel): @@ -103,6 +123,7 @@ class UnionMember1(BaseModel): upload_status: Optional[Literal["empty", "uploading", "pending", "processing", "failed", "complete"]] = None variant: Optional[UnionMember1Variant] = None + """A Predefined AI prompt classification topic entry.""" class UnionMember2Profile(BaseModel): diff --git a/src/cloudflare/types/zero_trust/dlp/entries/integration_list_response.py b/src/cloudflare/types/zero_trust/dlp/entries/integration_list_response.py index ea7214a2153..f757267e68e 100644 --- a/src/cloudflare/types/zero_trust/dlp/entries/integration_list_response.py +++ b/src/cloudflare/types/zero_trust/dlp/entries/integration_list_response.py @@ -13,6 +13,8 @@ "UnionMember1", "UnionMember1Confidence", "UnionMember1Variant", + "UnionMember1VariantUnionMember0", + "UnionMember1VariantUnionMember1", "UnionMember2", "UnionMember3", "UnionMember4", @@ -53,12 +55,30 @@ class UnionMember1Confidence(BaseModel): """ -class UnionMember1Variant(BaseModel): +class UnionMember1VariantUnionMember0(BaseModel): + """A Predefined AI prompt classification topic entry.""" + topic_type: Literal["Intent", "Content"] type: Literal["PromptTopic"] description: Optional[str] = None + """ + A customer-facing explanation of what this predefined AI prompt topic + represents. + """ + + +class UnionMember1VariantUnionMember1(BaseModel): + """A general predefined entry.""" + + type: Literal["General"] + + description: Optional[str] = None + """A customer-facing explanation of what this predefined entry represents.""" + + +UnionMember1Variant: TypeAlias = Union[UnionMember1VariantUnionMember0, UnionMember1VariantUnionMember1] class UnionMember1(BaseModel): @@ -77,6 +97,7 @@ class UnionMember1(BaseModel): upload_status: Optional[Literal["empty", "uploading", "pending", "processing", "failed", "complete"]] = None variant: Optional[UnionMember1Variant] = None + """A Predefined AI prompt classification topic entry.""" class UnionMember2(BaseModel): diff --git a/src/cloudflare/types/zero_trust/dlp/entries/predefined_create_response.py b/src/cloudflare/types/zero_trust/dlp/entries/predefined_create_response.py index 60864076dca..21f28b21f3f 100644 --- a/src/cloudflare/types/zero_trust/dlp/entries/predefined_create_response.py +++ b/src/cloudflare/types/zero_trust/dlp/entries/predefined_create_response.py @@ -1,11 +1,11 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional -from typing_extensions import Literal +from typing import Union, Optional +from typing_extensions import Literal, TypeAlias from ....._models import BaseModel -__all__ = ["PredefinedCreateResponse", "Confidence", "Variant"] +__all__ = ["PredefinedCreateResponse", "Confidence", "Variant", "VariantUnionMember0", "VariantUnionMember1"] class Confidence(BaseModel): @@ -19,12 +19,30 @@ class Confidence(BaseModel): """ -class Variant(BaseModel): +class VariantUnionMember0(BaseModel): + """A Predefined AI prompt classification topic entry.""" + topic_type: Literal["Intent", "Content"] type: Literal["PromptTopic"] description: Optional[str] = None + """ + A customer-facing explanation of what this predefined AI prompt topic + represents. + """ + + +class VariantUnionMember1(BaseModel): + """A general predefined entry.""" + + type: Literal["General"] + + description: Optional[str] = None + """A customer-facing explanation of what this predefined entry represents.""" + + +Variant: TypeAlias = Union[VariantUnionMember0, VariantUnionMember1] class PredefinedCreateResponse(BaseModel): @@ -39,3 +57,4 @@ class PredefinedCreateResponse(BaseModel): profile_id: Optional[str] = None variant: Optional[Variant] = None + """A Predefined AI prompt classification topic entry.""" diff --git a/src/cloudflare/types/zero_trust/dlp/entries/predefined_get_response.py b/src/cloudflare/types/zero_trust/dlp/entries/predefined_get_response.py index 975c433ccf9..8d7479e52b7 100644 --- a/src/cloudflare/types/zero_trust/dlp/entries/predefined_get_response.py +++ b/src/cloudflare/types/zero_trust/dlp/entries/predefined_get_response.py @@ -15,6 +15,8 @@ "UnionMember1Confidence", "UnionMember1Profile", "UnionMember1Variant", + "UnionMember1VariantUnionMember0", + "UnionMember1VariantUnionMember1", "UnionMember2", "UnionMember2Profile", "UnionMember3", @@ -77,12 +79,30 @@ class UnionMember1Profile(BaseModel): name: str -class UnionMember1Variant(BaseModel): +class UnionMember1VariantUnionMember0(BaseModel): + """A Predefined AI prompt classification topic entry.""" + topic_type: Literal["Intent", "Content"] type: Literal["PromptTopic"] description: Optional[str] = None + """ + A customer-facing explanation of what this predefined AI prompt topic + represents. + """ + + +class UnionMember1VariantUnionMember1(BaseModel): + """A general predefined entry.""" + + type: Literal["General"] + + description: Optional[str] = None + """A customer-facing explanation of what this predefined entry represents.""" + + +UnionMember1Variant: TypeAlias = Union[UnionMember1VariantUnionMember0, UnionMember1VariantUnionMember1] class UnionMember1(BaseModel): @@ -103,6 +123,7 @@ class UnionMember1(BaseModel): upload_status: Optional[Literal["empty", "uploading", "pending", "processing", "failed", "complete"]] = None variant: Optional[UnionMember1Variant] = None + """A Predefined AI prompt classification topic entry.""" class UnionMember2Profile(BaseModel): diff --git a/src/cloudflare/types/zero_trust/dlp/entries/predefined_list_response.py b/src/cloudflare/types/zero_trust/dlp/entries/predefined_list_response.py index 2dcfabd8dc1..177f70b1745 100644 --- a/src/cloudflare/types/zero_trust/dlp/entries/predefined_list_response.py +++ b/src/cloudflare/types/zero_trust/dlp/entries/predefined_list_response.py @@ -13,6 +13,8 @@ "UnionMember1", "UnionMember1Confidence", "UnionMember1Variant", + "UnionMember1VariantUnionMember0", + "UnionMember1VariantUnionMember1", "UnionMember2", "UnionMember3", "UnionMember4", @@ -53,12 +55,30 @@ class UnionMember1Confidence(BaseModel): """ -class UnionMember1Variant(BaseModel): +class UnionMember1VariantUnionMember0(BaseModel): + """A Predefined AI prompt classification topic entry.""" + topic_type: Literal["Intent", "Content"] type: Literal["PromptTopic"] description: Optional[str] = None + """ + A customer-facing explanation of what this predefined AI prompt topic + represents. + """ + + +class UnionMember1VariantUnionMember1(BaseModel): + """A general predefined entry.""" + + type: Literal["General"] + + description: Optional[str] = None + """A customer-facing explanation of what this predefined entry represents.""" + + +UnionMember1Variant: TypeAlias = Union[UnionMember1VariantUnionMember0, UnionMember1VariantUnionMember1] class UnionMember1(BaseModel): @@ -77,6 +97,7 @@ class UnionMember1(BaseModel): upload_status: Optional[Literal["empty", "uploading", "pending", "processing", "failed", "complete"]] = None variant: Optional[UnionMember1Variant] = None + """A Predefined AI prompt classification topic entry.""" class UnionMember2(BaseModel): diff --git a/src/cloudflare/types/zero_trust/dlp/entries/predefined_update_response.py b/src/cloudflare/types/zero_trust/dlp/entries/predefined_update_response.py index 178470ad0a2..f72509d654d 100644 --- a/src/cloudflare/types/zero_trust/dlp/entries/predefined_update_response.py +++ b/src/cloudflare/types/zero_trust/dlp/entries/predefined_update_response.py @@ -1,11 +1,11 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional -from typing_extensions import Literal +from typing import Union, Optional +from typing_extensions import Literal, TypeAlias from ....._models import BaseModel -__all__ = ["PredefinedUpdateResponse", "Confidence", "Variant"] +__all__ = ["PredefinedUpdateResponse", "Confidence", "Variant", "VariantUnionMember0", "VariantUnionMember1"] class Confidence(BaseModel): @@ -19,12 +19,30 @@ class Confidence(BaseModel): """ -class Variant(BaseModel): +class VariantUnionMember0(BaseModel): + """A Predefined AI prompt classification topic entry.""" + topic_type: Literal["Intent", "Content"] type: Literal["PromptTopic"] description: Optional[str] = None + """ + A customer-facing explanation of what this predefined AI prompt topic + represents. + """ + + +class VariantUnionMember1(BaseModel): + """A general predefined entry.""" + + type: Literal["General"] + + description: Optional[str] = None + """A customer-facing explanation of what this predefined entry represents.""" + + +Variant: TypeAlias = Union[VariantUnionMember0, VariantUnionMember1] class PredefinedUpdateResponse(BaseModel): @@ -39,3 +57,4 @@ class PredefinedUpdateResponse(BaseModel): profile_id: Optional[str] = None variant: Optional[Variant] = None + """A Predefined AI prompt classification topic entry.""" diff --git a/src/cloudflare/types/zero_trust/dlp/entry_get_response.py b/src/cloudflare/types/zero_trust/dlp/entry_get_response.py index b14a69946d9..1ee40f14fd5 100644 --- a/src/cloudflare/types/zero_trust/dlp/entry_get_response.py +++ b/src/cloudflare/types/zero_trust/dlp/entry_get_response.py @@ -15,6 +15,8 @@ "UnionMember1Confidence", "UnionMember1Profile", "UnionMember1Variant", + "UnionMember1VariantUnionMember0", + "UnionMember1VariantUnionMember1", "UnionMember2", "UnionMember2Profile", "UnionMember3", @@ -77,12 +79,30 @@ class UnionMember1Profile(BaseModel): name: str -class UnionMember1Variant(BaseModel): +class UnionMember1VariantUnionMember0(BaseModel): + """A Predefined AI prompt classification topic entry.""" + topic_type: Literal["Intent", "Content"] type: Literal["PromptTopic"] description: Optional[str] = None + """ + A customer-facing explanation of what this predefined AI prompt topic + represents. + """ + + +class UnionMember1VariantUnionMember1(BaseModel): + """A general predefined entry.""" + + type: Literal["General"] + + description: Optional[str] = None + """A customer-facing explanation of what this predefined entry represents.""" + + +UnionMember1Variant: TypeAlias = Union[UnionMember1VariantUnionMember0, UnionMember1VariantUnionMember1] class UnionMember1(BaseModel): @@ -103,6 +123,7 @@ class UnionMember1(BaseModel): upload_status: Optional[Literal["empty", "uploading", "pending", "processing", "failed", "complete"]] = None variant: Optional[UnionMember1Variant] = None + """A Predefined AI prompt classification topic entry.""" class UnionMember2Profile(BaseModel): diff --git a/src/cloudflare/types/zero_trust/dlp/entry_list_response.py b/src/cloudflare/types/zero_trust/dlp/entry_list_response.py index c0e6b250d00..d6661bd90df 100644 --- a/src/cloudflare/types/zero_trust/dlp/entry_list_response.py +++ b/src/cloudflare/types/zero_trust/dlp/entry_list_response.py @@ -13,6 +13,8 @@ "UnionMember1", "UnionMember1Confidence", "UnionMember1Variant", + "UnionMember1VariantUnionMember0", + "UnionMember1VariantUnionMember1", "UnionMember2", "UnionMember3", "UnionMember4", @@ -53,12 +55,30 @@ class UnionMember1Confidence(BaseModel): """ -class UnionMember1Variant(BaseModel): +class UnionMember1VariantUnionMember0(BaseModel): + """A Predefined AI prompt classification topic entry.""" + topic_type: Literal["Intent", "Content"] type: Literal["PromptTopic"] description: Optional[str] = None + """ + A customer-facing explanation of what this predefined AI prompt topic + represents. + """ + + +class UnionMember1VariantUnionMember1(BaseModel): + """A general predefined entry.""" + + type: Literal["General"] + + description: Optional[str] = None + """A customer-facing explanation of what this predefined entry represents.""" + + +UnionMember1Variant: TypeAlias = Union[UnionMember1VariantUnionMember0, UnionMember1VariantUnionMember1] class UnionMember1(BaseModel): @@ -77,6 +97,7 @@ class UnionMember1(BaseModel): upload_status: Optional[Literal["empty", "uploading", "pending", "processing", "failed", "complete"]] = None variant: Optional[UnionMember1Variant] = None + """A Predefined AI prompt classification topic entry.""" class UnionMember2(BaseModel): diff --git a/src/cloudflare/types/zero_trust/dlp/entry_update_response.py b/src/cloudflare/types/zero_trust/dlp/entry_update_response.py index 0e256a22386..3b569087412 100644 --- a/src/cloudflare/types/zero_trust/dlp/entry_update_response.py +++ b/src/cloudflare/types/zero_trust/dlp/entry_update_response.py @@ -13,6 +13,8 @@ "PredefinedEntry", "PredefinedEntryConfidence", "PredefinedEntryVariant", + "PredefinedEntryVariantUnionMember0", + "PredefinedEntryVariantUnionMember1", "IntegrationEntry", "ExactDataEntry", "DocumentFingerprintEntry", @@ -51,12 +53,30 @@ class PredefinedEntryConfidence(BaseModel): """ -class PredefinedEntryVariant(BaseModel): +class PredefinedEntryVariantUnionMember0(BaseModel): + """A Predefined AI prompt classification topic entry.""" + topic_type: Literal["Intent", "Content"] type: Literal["PromptTopic"] description: Optional[str] = None + """ + A customer-facing explanation of what this predefined AI prompt topic + represents. + """ + + +class PredefinedEntryVariantUnionMember1(BaseModel): + """A general predefined entry.""" + + type: Literal["General"] + + description: Optional[str] = None + """A customer-facing explanation of what this predefined entry represents.""" + + +PredefinedEntryVariant: TypeAlias = Union[PredefinedEntryVariantUnionMember0, PredefinedEntryVariantUnionMember1] class PredefinedEntry(BaseModel): @@ -73,6 +93,7 @@ class PredefinedEntry(BaseModel): profile_id: Optional[str] = None variant: Optional[PredefinedEntryVariant] = None + """A Predefined AI prompt classification topic entry.""" class IntegrationEntry(BaseModel): diff --git a/src/cloudflare/types/zero_trust/dlp/limit_list_response.py b/src/cloudflare/types/zero_trust/dlp/limit_list_response.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/types/zero_trust/dlp/profile.py b/src/cloudflare/types/zero_trust/dlp/profile.py index 96d6a05976b..869b45315df 100644 --- a/src/cloudflare/types/zero_trust/dlp/profile.py +++ b/src/cloudflare/types/zero_trust/dlp/profile.py @@ -19,6 +19,8 @@ "CustomProfileEntryPredefinedEntry", "CustomProfileEntryPredefinedEntryConfidence", "CustomProfileEntryPredefinedEntryVariant", + "CustomProfileEntryPredefinedEntryVariantUnionMember0", + "CustomProfileEntryPredefinedEntryVariantUnionMember1", "CustomProfileEntryIntegrationEntry", "CustomProfileEntryExactDataEntry", "CustomProfileEntryDocumentFingerprintEntry", @@ -29,6 +31,8 @@ "CustomProfileSharedEntryPredefinedEntry", "CustomProfileSharedEntryPredefinedEntryConfidence", "CustomProfileSharedEntryPredefinedEntryVariant", + "CustomProfileSharedEntryPredefinedEntryVariantUnionMember0", + "CustomProfileSharedEntryPredefinedEntryVariantUnionMember1", "CustomProfileSharedEntryIntegrationEntry", "CustomProfileSharedEntryExactDataEntry", "CustomProfileSharedEntryDocumentFingerprintEntry", @@ -39,6 +43,8 @@ "PredefinedProfileEntryPredefinedEntry", "PredefinedProfileEntryPredefinedEntryConfidence", "PredefinedProfileEntryPredefinedEntryVariant", + "PredefinedProfileEntryPredefinedEntryVariantUnionMember0", + "PredefinedProfileEntryPredefinedEntryVariantUnionMember1", "PredefinedProfileEntryIntegrationEntry", "PredefinedProfileEntryExactDataEntry", "PredefinedProfileEntryDocumentFingerprintEntry", @@ -49,6 +55,8 @@ "IntegrationProfileEntryPredefinedEntry", "IntegrationProfileEntryPredefinedEntryConfidence", "IntegrationProfileEntryPredefinedEntryVariant", + "IntegrationProfileEntryPredefinedEntryVariantUnionMember0", + "IntegrationProfileEntryPredefinedEntryVariantUnionMember1", "IntegrationProfileEntryIntegrationEntry", "IntegrationProfileEntryExactDataEntry", "IntegrationProfileEntryDocumentFingerprintEntry", @@ -58,6 +66,8 @@ "IntegrationProfileSharedEntryPredefinedEntry", "IntegrationProfileSharedEntryPredefinedEntryConfidence", "IntegrationProfileSharedEntryPredefinedEntryVariant", + "IntegrationProfileSharedEntryPredefinedEntryVariantUnionMember0", + "IntegrationProfileSharedEntryPredefinedEntryVariantUnionMember1", "IntegrationProfileSharedEntryIntegrationEntry", "IntegrationProfileSharedEntryExactDataEntry", "IntegrationProfileSharedEntryDocumentFingerprintEntry", @@ -96,12 +106,32 @@ class CustomProfileEntryPredefinedEntryConfidence(BaseModel): """ -class CustomProfileEntryPredefinedEntryVariant(BaseModel): +class CustomProfileEntryPredefinedEntryVariantUnionMember0(BaseModel): + """A Predefined AI prompt classification topic entry.""" + topic_type: Literal["Intent", "Content"] type: Literal["PromptTopic"] description: Optional[str] = None + """ + A customer-facing explanation of what this predefined AI prompt topic + represents. + """ + + +class CustomProfileEntryPredefinedEntryVariantUnionMember1(BaseModel): + """A general predefined entry.""" + + type: Literal["General"] + + description: Optional[str] = None + """A customer-facing explanation of what this predefined entry represents.""" + + +CustomProfileEntryPredefinedEntryVariant: TypeAlias = Union[ + CustomProfileEntryPredefinedEntryVariantUnionMember0, CustomProfileEntryPredefinedEntryVariantUnionMember1 +] class CustomProfileEntryPredefinedEntry(BaseModel): @@ -118,6 +148,7 @@ class CustomProfileEntryPredefinedEntry(BaseModel): profile_id: Optional[str] = None variant: Optional[CustomProfileEntryPredefinedEntryVariant] = None + """A Predefined AI prompt classification topic entry.""" class CustomProfileEntryIntegrationEntry(BaseModel): @@ -241,12 +272,33 @@ class CustomProfileSharedEntryPredefinedEntryConfidence(BaseModel): """ -class CustomProfileSharedEntryPredefinedEntryVariant(BaseModel): +class CustomProfileSharedEntryPredefinedEntryVariantUnionMember0(BaseModel): + """A Predefined AI prompt classification topic entry.""" + topic_type: Literal["Intent", "Content"] type: Literal["PromptTopic"] description: Optional[str] = None + """ + A customer-facing explanation of what this predefined AI prompt topic + represents. + """ + + +class CustomProfileSharedEntryPredefinedEntryVariantUnionMember1(BaseModel): + """A general predefined entry.""" + + type: Literal["General"] + + description: Optional[str] = None + """A customer-facing explanation of what this predefined entry represents.""" + + +CustomProfileSharedEntryPredefinedEntryVariant: TypeAlias = Union[ + CustomProfileSharedEntryPredefinedEntryVariantUnionMember0, + CustomProfileSharedEntryPredefinedEntryVariantUnionMember1, +] class CustomProfileSharedEntryPredefinedEntry(BaseModel): @@ -263,6 +315,7 @@ class CustomProfileSharedEntryPredefinedEntry(BaseModel): profile_id: Optional[str] = None variant: Optional[CustomProfileSharedEntryPredefinedEntryVariant] = None + """A Predefined AI prompt classification topic entry.""" class CustomProfileSharedEntryIntegrationEntry(BaseModel): @@ -423,12 +476,32 @@ class PredefinedProfileEntryPredefinedEntryConfidence(BaseModel): """ -class PredefinedProfileEntryPredefinedEntryVariant(BaseModel): +class PredefinedProfileEntryPredefinedEntryVariantUnionMember0(BaseModel): + """A Predefined AI prompt classification topic entry.""" + topic_type: Literal["Intent", "Content"] type: Literal["PromptTopic"] description: Optional[str] = None + """ + A customer-facing explanation of what this predefined AI prompt topic + represents. + """ + + +class PredefinedProfileEntryPredefinedEntryVariantUnionMember1(BaseModel): + """A general predefined entry.""" + + type: Literal["General"] + + description: Optional[str] = None + """A customer-facing explanation of what this predefined entry represents.""" + + +PredefinedProfileEntryPredefinedEntryVariant: TypeAlias = Union[ + PredefinedProfileEntryPredefinedEntryVariantUnionMember0, PredefinedProfileEntryPredefinedEntryVariantUnionMember1 +] class PredefinedProfileEntryPredefinedEntry(BaseModel): @@ -445,6 +518,7 @@ class PredefinedProfileEntryPredefinedEntry(BaseModel): profile_id: Optional[str] = None variant: Optional[PredefinedProfileEntryPredefinedEntryVariant] = None + """A Predefined AI prompt classification topic entry.""" class PredefinedProfileEntryIntegrationEntry(BaseModel): @@ -587,12 +661,32 @@ class IntegrationProfileEntryPredefinedEntryConfidence(BaseModel): """ -class IntegrationProfileEntryPredefinedEntryVariant(BaseModel): +class IntegrationProfileEntryPredefinedEntryVariantUnionMember0(BaseModel): + """A Predefined AI prompt classification topic entry.""" + topic_type: Literal["Intent", "Content"] type: Literal["PromptTopic"] description: Optional[str] = None + """ + A customer-facing explanation of what this predefined AI prompt topic + represents. + """ + + +class IntegrationProfileEntryPredefinedEntryVariantUnionMember1(BaseModel): + """A general predefined entry.""" + + type: Literal["General"] + + description: Optional[str] = None + """A customer-facing explanation of what this predefined entry represents.""" + + +IntegrationProfileEntryPredefinedEntryVariant: TypeAlias = Union[ + IntegrationProfileEntryPredefinedEntryVariantUnionMember0, IntegrationProfileEntryPredefinedEntryVariantUnionMember1 +] class IntegrationProfileEntryPredefinedEntry(BaseModel): @@ -609,6 +703,7 @@ class IntegrationProfileEntryPredefinedEntry(BaseModel): profile_id: Optional[str] = None variant: Optional[IntegrationProfileEntryPredefinedEntryVariant] = None + """A Predefined AI prompt classification topic entry.""" class IntegrationProfileEntryIntegrationEntry(BaseModel): @@ -722,12 +817,33 @@ class IntegrationProfileSharedEntryPredefinedEntryConfidence(BaseModel): """ -class IntegrationProfileSharedEntryPredefinedEntryVariant(BaseModel): +class IntegrationProfileSharedEntryPredefinedEntryVariantUnionMember0(BaseModel): + """A Predefined AI prompt classification topic entry.""" + topic_type: Literal["Intent", "Content"] type: Literal["PromptTopic"] description: Optional[str] = None + """ + A customer-facing explanation of what this predefined AI prompt topic + represents. + """ + + +class IntegrationProfileSharedEntryPredefinedEntryVariantUnionMember1(BaseModel): + """A general predefined entry.""" + + type: Literal["General"] + + description: Optional[str] = None + """A customer-facing explanation of what this predefined entry represents.""" + + +IntegrationProfileSharedEntryPredefinedEntryVariant: TypeAlias = Union[ + IntegrationProfileSharedEntryPredefinedEntryVariantUnionMember0, + IntegrationProfileSharedEntryPredefinedEntryVariantUnionMember1, +] class IntegrationProfileSharedEntryPredefinedEntry(BaseModel): @@ -744,6 +860,7 @@ class IntegrationProfileSharedEntryPredefinedEntry(BaseModel): profile_id: Optional[str] = None variant: Optional[IntegrationProfileSharedEntryPredefinedEntryVariant] = None + """A Predefined AI prompt classification topic entry.""" class IntegrationProfileSharedEntryIntegrationEntry(BaseModel): diff --git a/src/cloudflare/types/zero_trust/dlp/profile_list_params.py b/src/cloudflare/types/zero_trust/dlp/profile_list_params.py old mode 100755 new mode 100644 diff --git a/src/cloudflare/types/zero_trust/dlp/profiles/predefined_profile.py b/src/cloudflare/types/zero_trust/dlp/profiles/predefined_profile.py index b3c97b85ffc..234339358d1 100644 --- a/src/cloudflare/types/zero_trust/dlp/profiles/predefined_profile.py +++ b/src/cloudflare/types/zero_trust/dlp/profiles/predefined_profile.py @@ -14,6 +14,8 @@ "EntryPredefinedEntry", "EntryPredefinedEntryConfidence", "EntryPredefinedEntryVariant", + "EntryPredefinedEntryVariantUnionMember0", + "EntryPredefinedEntryVariantUnionMember1", "EntryIntegrationEntry", "EntryExactDataEntry", "EntryDocumentFingerprintEntry", @@ -52,12 +54,32 @@ class EntryPredefinedEntryConfidence(BaseModel): """ -class EntryPredefinedEntryVariant(BaseModel): +class EntryPredefinedEntryVariantUnionMember0(BaseModel): + """A Predefined AI prompt classification topic entry.""" + topic_type: Literal["Intent", "Content"] type: Literal["PromptTopic"] description: Optional[str] = None + """ + A customer-facing explanation of what this predefined AI prompt topic + represents. + """ + + +class EntryPredefinedEntryVariantUnionMember1(BaseModel): + """A general predefined entry.""" + + type: Literal["General"] + + description: Optional[str] = None + """A customer-facing explanation of what this predefined entry represents.""" + + +EntryPredefinedEntryVariant: TypeAlias = Union[ + EntryPredefinedEntryVariantUnionMember0, EntryPredefinedEntryVariantUnionMember1 +] class EntryPredefinedEntry(BaseModel): @@ -74,6 +96,7 @@ class EntryPredefinedEntry(BaseModel): profile_id: Optional[str] = None variant: Optional[EntryPredefinedEntryVariant] = None + """A Predefined AI prompt classification topic entry.""" class EntryIntegrationEntry(BaseModel): diff --git a/src/cloudflare/types/zones/setting_edit_response.py b/src/cloudflare/types/zones/setting_edit_response.py index 9fd2e3ef777..e1107566376 100644 --- a/src/cloudflare/types/zones/setting_edit_response.py +++ b/src/cloudflare/types/zones/setting_edit_response.py @@ -63,6 +63,7 @@ "ZonesSchemasResponseBuffering", "ZonesSchemasRocketLoader", "ZonesSchemasAutomaticPlatformOptimization", + "ZonesSearchForAgents", "ZonesSchemasSecurityLevel", "ZonesSha1Support", "ZonesSchemasSortQueryStringForCache", @@ -616,6 +617,30 @@ class ZonesSchemasAutomaticPlatformOptimization(BaseModel): """last time this setting was modified.""" +class ZonesSearchForAgents(BaseModel): + """ + When enabled, Cloudflare provisions an AI Search instance for the zone + and exposes a /.well-known/ai-search endpoint that AI agents can query. + Markdown responses also receive an agent: YAML capability block advertising + the search endpoint. + """ + + id: Literal["search_for_agents"] + """ID of the zone setting.""" + + value: Literal["off", "on"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + class ZonesSchemasSecurityLevel(BaseModel): """ Choose the appropriate security profile for your website, which will automatically adjust each of the security settings. If you choose to customize an individual security setting, the profile will become Custom. (https://support.cloudflare.com/hc/en-us/articles/200170056). @@ -855,6 +880,7 @@ class ZonesSchemasWAF(BaseModel): ZonesSchemasResponseBuffering, ZonesSchemasRocketLoader, ZonesSchemasAutomaticPlatformOptimization, + ZonesSearchForAgents, SecurityHeaders, ZonesSchemasSecurityLevel, ServerSideExcludes, diff --git a/src/cloudflare/types/zones/setting_get_response.py b/src/cloudflare/types/zones/setting_get_response.py index ac20c206eb1..3b66fbf3293 100644 --- a/src/cloudflare/types/zones/setting_get_response.py +++ b/src/cloudflare/types/zones/setting_get_response.py @@ -63,6 +63,7 @@ "ZonesSchemasResponseBuffering", "ZonesSchemasRocketLoader", "ZonesSchemasAutomaticPlatformOptimization", + "ZonesSearchForAgents", "ZonesSchemasSecurityLevel", "ZonesSha1Support", "ZonesSchemasSortQueryStringForCache", @@ -616,6 +617,30 @@ class ZonesSchemasAutomaticPlatformOptimization(BaseModel): """last time this setting was modified.""" +class ZonesSearchForAgents(BaseModel): + """ + When enabled, Cloudflare provisions an AI Search instance for the zone + and exposes a /.well-known/ai-search endpoint that AI agents can query. + Markdown responses also receive an agent: YAML capability block advertising + the search endpoint. + """ + + id: Literal["search_for_agents"] + """ID of the zone setting.""" + + value: Literal["off", "on"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + class ZonesSchemasSecurityLevel(BaseModel): """ Choose the appropriate security profile for your website, which will automatically adjust each of the security settings. If you choose to customize an individual security setting, the profile will become Custom. (https://support.cloudflare.com/hc/en-us/articles/200170056). @@ -855,6 +880,7 @@ class ZonesSchemasWAF(BaseModel): ZonesSchemasResponseBuffering, ZonesSchemasRocketLoader, ZonesSchemasAutomaticPlatformOptimization, + ZonesSearchForAgents, SecurityHeaders, ZonesSchemasSecurityLevel, ServerSideExcludes, diff --git a/src/cloudflare/types/zones/zone_list_params.py b/src/cloudflare/types/zones/zone_list_params.py index 8e6985ebfe1..706077d2171 100644 --- a/src/cloudflare/types/zones/zone_list_params.py +++ b/src/cloudflare/types/zones/zone_list_params.py @@ -2,6 +2,7 @@ from __future__ import annotations +from typing import List from typing_extensions import Literal, TypedDict __all__ = ["ZoneListParams", "Account"] @@ -43,6 +44,14 @@ class ZoneListParams(TypedDict, total=False): status: Literal["initializing", "pending", "active", "moved"] """Specify a zone status to filter by.""" + type: List[Literal["full", "partial", "secondary", "internal"]] + """Zone types to filter by. + + Multiple types can be specified as a comma-separated list (e.g., + ?type=full,partial,secondary). When this parameter is not provided, zones with + type "internal" are excluded from the results. + """ + class Account(TypedDict, total=False): id: str diff --git a/tests/api_resources/aisearch/namespaces/instances/test_items.py b/tests/api_resources/aisearch/namespaces/instances/test_items.py index d7a6b9b7bed..6753ef60196 100644 --- a/tests/api_resources/aisearch/namespaces/instances/test_items.py +++ b/tests/api_resources/aisearch/namespaces/instances/test_items.py @@ -283,6 +283,18 @@ def test_method_create_or_update(self, client: Cloudflare) -> None: ) assert_matches_type(ItemCreateOrUpdateResponse, item, path=["response"]) + @parametrize + def test_method_create_or_update_with_all_params(self, client: Cloudflare) -> None: + item = client.aisearch.namespaces.instances.items.create_or_update( + id="my-ai-search", + account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", + name="my-namespace", + key="key", + next_action="INDEX", + wait_for_completion=True, + ) + assert_matches_type(ItemCreateOrUpdateResponse, item, path=["response"]) + @parametrize def test_raw_response_create_or_update(self, client: Cloudflare) -> None: response = client.aisearch.namespaces.instances.items.with_raw_response.create_or_update( @@ -607,6 +619,18 @@ def test_method_sync(self, client: Cloudflare) -> None: ) assert_matches_type(ItemSyncResponse, item, path=["response"]) + @parametrize + def test_method_sync_with_all_params(self, client: Cloudflare) -> None: + item = client.aisearch.namespaces.instances.items.sync( + item_id="item_id", + account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", + name="my-namespace", + id="my-ai-search", + next_action="INDEX", + wait_for_completion=True, + ) + assert_matches_type(ItemSyncResponse, item, path=["response"]) + @parametrize def test_raw_response_sync(self, client: Cloudflare) -> None: response = client.aisearch.namespaces.instances.items.with_raw_response.sync( @@ -1011,6 +1035,18 @@ async def test_method_create_or_update(self, async_client: AsyncCloudflare) -> N ) assert_matches_type(ItemCreateOrUpdateResponse, item, path=["response"]) + @parametrize + async def test_method_create_or_update_with_all_params(self, async_client: AsyncCloudflare) -> None: + item = await async_client.aisearch.namespaces.instances.items.create_or_update( + id="my-ai-search", + account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", + name="my-namespace", + key="key", + next_action="INDEX", + wait_for_completion=True, + ) + assert_matches_type(ItemCreateOrUpdateResponse, item, path=["response"]) + @parametrize async def test_raw_response_create_or_update(self, async_client: AsyncCloudflare) -> None: response = await async_client.aisearch.namespaces.instances.items.with_raw_response.create_or_update( @@ -1335,6 +1371,18 @@ async def test_method_sync(self, async_client: AsyncCloudflare) -> None: ) assert_matches_type(ItemSyncResponse, item, path=["response"]) + @parametrize + async def test_method_sync_with_all_params(self, async_client: AsyncCloudflare) -> None: + item = await async_client.aisearch.namespaces.instances.items.sync( + item_id="item_id", + account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", + name="my-namespace", + id="my-ai-search", + next_action="INDEX", + wait_for_completion=True, + ) + assert_matches_type(ItemSyncResponse, item, path=["response"]) + @parametrize async def test_raw_response_sync(self, async_client: AsyncCloudflare) -> None: response = await async_client.aisearch.namespaces.instances.items.with_raw_response.sync( diff --git a/tests/api_resources/aisearch/namespaces/test_instances.py b/tests/api_resources/aisearch/namespaces/test_instances.py index 3aab8040ce6..ceaff00d4be 100644 --- a/tests/api_resources/aisearch/namespaces/test_instances.py +++ b/tests/api_resources/aisearch/namespaces/test_instances.py @@ -66,11 +66,6 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: max_num_results=1, metadata={ "created_from_aisearch_wizard": True, - "search_for_agents": { - "hostname": "hostname", - "zone_id": "zone_id", - "zone_name": "zone_name", - }, "worker_domain": "worker_domain", }, public_endpoint_params={ @@ -227,11 +222,6 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: max_num_results=1, metadata={ "created_from_aisearch_wizard": True, - "search_for_agents": { - "hostname": "hostname", - "zone_id": "zone_id", - "zone_name": "zone_name", - }, "worker_domain": "worker_domain", }, paused=True, @@ -378,7 +368,7 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: order_by="created_at", order_by_direction="asc", page=1, - per_page=1, + per_page=20, search="search", ) assert_matches_type(SyncV4PagePaginationArray[InstanceListResponse], instance, path=["response"]) @@ -901,11 +891,6 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare max_num_results=1, metadata={ "created_from_aisearch_wizard": True, - "search_for_agents": { - "hostname": "hostname", - "zone_id": "zone_id", - "zone_name": "zone_name", - }, "worker_domain": "worker_domain", }, public_endpoint_params={ @@ -1062,11 +1047,6 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare max_num_results=1, metadata={ "created_from_aisearch_wizard": True, - "search_for_agents": { - "hostname": "hostname", - "zone_id": "zone_id", - "zone_name": "zone_name", - }, "worker_domain": "worker_domain", }, paused=True, @@ -1213,7 +1193,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) order_by="created_at", order_by_direction="asc", page=1, - per_page=1, + per_page=20, search="search", ) assert_matches_type(AsyncV4PagePaginationArray[InstanceListResponse], instance, path=["response"]) diff --git a/tests/api_resources/aisearch/test_instances.py b/tests/api_resources/aisearch/test_instances.py index 80bd18541ba..033ed5e4825 100644 --- a/tests/api_resources/aisearch/test_instances.py +++ b/tests/api_resources/aisearch/test_instances.py @@ -64,11 +64,6 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: max_num_results=1, metadata={ "created_from_aisearch_wizard": True, - "search_for_agents": { - "hostname": "hostname", - "zone_id": "zone_id", - "zone_name": "zone_name", - }, "worker_domain": "worker_domain", }, public_endpoint_params={ @@ -213,11 +208,6 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: max_num_results=1, metadata={ "created_from_aisearch_wizard": True, - "search_for_agents": { - "hostname": "hostname", - "zone_id": "zone_id", - "zone_name": "zone_name", - }, "worker_domain": "worker_domain", }, paused=True, @@ -351,7 +341,7 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: order_by="created_at", order_by_direction="asc", page=1, - per_page=1, + per_page=20, search="search", ) assert_matches_type(SyncV4PagePaginationArray[InstanceListResponse], instance, path=["response"]) @@ -795,11 +785,6 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare max_num_results=1, metadata={ "created_from_aisearch_wizard": True, - "search_for_agents": { - "hostname": "hostname", - "zone_id": "zone_id", - "zone_name": "zone_name", - }, "worker_domain": "worker_domain", }, public_endpoint_params={ @@ -944,11 +929,6 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare max_num_results=1, metadata={ "created_from_aisearch_wizard": True, - "search_for_agents": { - "hostname": "hostname", - "zone_id": "zone_id", - "zone_name": "zone_name", - }, "worker_domain": "worker_domain", }, paused=True, @@ -1082,7 +1062,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) order_by="created_at", order_by_direction="asc", page=1, - per_page=1, + per_page=20, search="search", ) assert_matches_type(AsyncV4PagePaginationArray[InstanceListResponse], instance, path=["response"]) diff --git a/tests/api_resources/api_gateway/test_operations.py b/tests/api_resources/api_gateway/test_operations.py index aab5d1b4997..03ad915d493 100644 --- a/tests/api_resources/api_gateway/test_operations.py +++ b/tests/api_resources/api_gateway/test_operations.py @@ -294,6 +294,7 @@ def test_method_get_with_all_params(self, client: Cloudflare) -> None: operation_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", zone_id="023e105f4ecef8ad9ca31a8372d0c353", feature=["thresholds"], + with_schemas=True, ) assert_matches_type(OperationGetResponse, operation, path=["response"]) @@ -612,6 +613,7 @@ async def test_method_get_with_all_params(self, async_client: AsyncCloudflare) - operation_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", zone_id="023e105f4ecef8ad9ca31a8372d0c353", feature=["thresholds"], + with_schemas=True, ) assert_matches_type(OperationGetResponse, operation, path=["response"]) diff --git a/tests/api_resources/botnet_feed/configs/__init__.py b/tests/api_resources/botnet_feed/configs/__init__.py old mode 100755 new mode 100644 diff --git a/tests/api_resources/botnet_feed/configs/test_asn.py b/tests/api_resources/botnet_feed/configs/test_asn.py old mode 100755 new mode 100644 diff --git a/tests/api_resources/botnet_feed/test_asn.py b/tests/api_resources/botnet_feed/test_asn.py old mode 100755 new mode 100644 diff --git a/tests/api_resources/browser_rendering/devtools/browser/test_targets.py b/tests/api_resources/browser_rendering/devtools/browser/test_targets.py index f574b31673c..ca56261b925 100644 --- a/tests/api_resources/browser_rendering/devtools/browser/test_targets.py +++ b/tests/api_resources/browser_rendering/devtools/browser/test_targets.py @@ -12,6 +12,7 @@ from cloudflare.types.browser_rendering.devtools.browser import ( TargetGetResponse, TargetListResponse, + TargetCloseResponse, TargetCreateResponse, TargetActivateResponse, ) @@ -187,6 +188,66 @@ def test_path_params_activate(self, client: Cloudflare) -> None: session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) + @parametrize + def test_method_close(self, client: Cloudflare) -> None: + target = client.browser_rendering.devtools.browser.targets.close( + target_id="target_id", + account_id="account_id", + session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(TargetCloseResponse, target, path=["response"]) + + @parametrize + def test_raw_response_close(self, client: Cloudflare) -> None: + response = client.browser_rendering.devtools.browser.targets.with_raw_response.close( + target_id="target_id", + account_id="account_id", + session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + target = response.parse() + assert_matches_type(TargetCloseResponse, target, path=["response"]) + + @parametrize + def test_streaming_response_close(self, client: Cloudflare) -> None: + with client.browser_rendering.devtools.browser.targets.with_streaming_response.close( + target_id="target_id", + account_id="account_id", + session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + target = response.parse() + assert_matches_type(TargetCloseResponse, target, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_close(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.browser_rendering.devtools.browser.targets.with_raw_response.close( + target_id="target_id", + account_id="", + session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"): + client.browser_rendering.devtools.browser.targets.with_raw_response.close( + target_id="target_id", + account_id="account_id", + session_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `target_id` but received ''"): + client.browser_rendering.devtools.browser.targets.with_raw_response.close( + target_id="", + account_id="account_id", + session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + @parametrize def test_method_get(self, client: Cloudflare) -> None: target = client.browser_rendering.devtools.browser.targets.get( @@ -418,6 +479,66 @@ async def test_path_params_activate(self, async_client: AsyncCloudflare) -> None session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) + @parametrize + async def test_method_close(self, async_client: AsyncCloudflare) -> None: + target = await async_client.browser_rendering.devtools.browser.targets.close( + target_id="target_id", + account_id="account_id", + session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(TargetCloseResponse, target, path=["response"]) + + @parametrize + async def test_raw_response_close(self, async_client: AsyncCloudflare) -> None: + response = await async_client.browser_rendering.devtools.browser.targets.with_raw_response.close( + target_id="target_id", + account_id="account_id", + session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + target = await response.parse() + assert_matches_type(TargetCloseResponse, target, path=["response"]) + + @parametrize + async def test_streaming_response_close(self, async_client: AsyncCloudflare) -> None: + async with async_client.browser_rendering.devtools.browser.targets.with_streaming_response.close( + target_id="target_id", + account_id="account_id", + session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + target = await response.parse() + assert_matches_type(TargetCloseResponse, target, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_close(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.browser_rendering.devtools.browser.targets.with_raw_response.close( + target_id="target_id", + account_id="", + session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"): + await async_client.browser_rendering.devtools.browser.targets.with_raw_response.close( + target_id="target_id", + account_id="account_id", + session_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `target_id` but received ''"): + await async_client.browser_rendering.devtools.browser.targets.with_raw_response.close( + target_id="", + account_id="account_id", + session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + @parametrize async def test_method_get(self, async_client: AsyncCloudflare) -> None: target = await async_client.browser_rendering.devtools.browser.targets.get( diff --git a/tests/api_resources/browser_rendering/test_content.py b/tests/api_resources/browser_rendering/test_content.py index c702e1e2c05..42a1a8708b0 100644 --- a/tests/api_resources/browser_rendering/test_content.py +++ b/tests/api_resources/browser_rendering/test_content.py @@ -29,7 +29,7 @@ def test_method_create_with_all_params_overload_1(self, client: Cloudflare) -> N content = client.browser_rendering.content.create( account_id="account_id", url="https://example.com/", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { @@ -147,7 +147,7 @@ def test_method_create_with_all_params_overload_2(self, client: Cloudflare) -> N content = client.browser_rendering.content.create( account_id="account_id", html="

Hello World!

", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { @@ -271,7 +271,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn content = await async_client.browser_rendering.content.create( account_id="account_id", url="https://example.com/", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { @@ -389,7 +389,7 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn content = await async_client.browser_rendering.content.create( account_id="account_id", html="

Hello World!

", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { diff --git a/tests/api_resources/browser_rendering/test_crawl.py b/tests/api_resources/browser_rendering/test_crawl.py index 3a282e1e8f6..5ee643874a0 100644 --- a/tests/api_resources/browser_rendering/test_crawl.py +++ b/tests/api_resources/browser_rendering/test_crawl.py @@ -33,7 +33,7 @@ def test_method_create_with_all_params_overload_1(self, client: Cloudflare) -> N crawl = client.browser_rendering.crawl.create( account_id="account_id", url="https://example.com", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { @@ -179,7 +179,7 @@ def test_method_create_with_all_params_overload_2(self, client: Cloudflare) -> N account_id="account_id", render=False, url="https://example.com", - cache_ttl=86400, + cache_ttl=0, crawl_purposes=["search"], depth=1, formats=["html"], @@ -307,7 +307,7 @@ def test_method_get_with_all_params(self, client: Cloudflare) -> None: crawl = client.browser_rendering.crawl.get( job_id="x", account_id="account_id", - cache_ttl=86400, + cache_ttl=0, cursor=0, limit=0, status="queued", @@ -373,7 +373,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn crawl = await async_client.browser_rendering.crawl.create( account_id="account_id", url="https://example.com", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { @@ -519,7 +519,7 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn account_id="account_id", render=False, url="https://example.com", - cache_ttl=86400, + cache_ttl=0, crawl_purposes=["search"], depth=1, formats=["html"], @@ -647,7 +647,7 @@ async def test_method_get_with_all_params(self, async_client: AsyncCloudflare) - crawl = await async_client.browser_rendering.crawl.get( job_id="x", account_id="account_id", - cache_ttl=86400, + cache_ttl=0, cursor=0, limit=0, status="queued", diff --git a/tests/api_resources/browser_rendering/test_json.py b/tests/api_resources/browser_rendering/test_json.py index 1243f04ab7e..8c4f282a60f 100644 --- a/tests/api_resources/browser_rendering/test_json.py +++ b/tests/api_resources/browser_rendering/test_json.py @@ -30,7 +30,7 @@ def test_method_create_with_all_params_overload_1(self, client: Cloudflare) -> N json = client.browser_rendering.json.create( account_id="account_id", html="

Hello World!

", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { @@ -159,7 +159,7 @@ def test_method_create_with_all_params_overload_2(self, client: Cloudflare) -> N json = client.browser_rendering.json.create( account_id="account_id", url="https://example.com/", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { @@ -294,7 +294,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn json = await async_client.browser_rendering.json.create( account_id="account_id", html="

Hello World!

", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { @@ -423,7 +423,7 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn json = await async_client.browser_rendering.json.create( account_id="account_id", url="https://example.com/", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { diff --git a/tests/api_resources/browser_rendering/test_links.py b/tests/api_resources/browser_rendering/test_links.py index 6609f2a3586..8e78e893b56 100644 --- a/tests/api_resources/browser_rendering/test_links.py +++ b/tests/api_resources/browser_rendering/test_links.py @@ -30,7 +30,7 @@ def test_method_create_with_all_params_overload_1(self, client: Cloudflare) -> N link = client.browser_rendering.links.create( account_id="account_id", html="

Hello World!

", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { @@ -150,7 +150,7 @@ def test_method_create_with_all_params_overload_2(self, client: Cloudflare) -> N link = client.browser_rendering.links.create( account_id="account_id", url="https://example.com/", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { @@ -276,7 +276,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn link = await async_client.browser_rendering.links.create( account_id="account_id", html="

Hello World!

", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { @@ -396,7 +396,7 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn link = await async_client.browser_rendering.links.create( account_id="account_id", url="https://example.com/", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { diff --git a/tests/api_resources/browser_rendering/test_markdown.py b/tests/api_resources/browser_rendering/test_markdown.py index b62b9643e4b..dc637f583ca 100644 --- a/tests/api_resources/browser_rendering/test_markdown.py +++ b/tests/api_resources/browser_rendering/test_markdown.py @@ -29,7 +29,7 @@ def test_method_create_with_all_params_overload_1(self, client: Cloudflare) -> N markdown = client.browser_rendering.markdown.create( account_id="account_id", url="https://example.com/", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { @@ -147,7 +147,7 @@ def test_method_create_with_all_params_overload_2(self, client: Cloudflare) -> N markdown = client.browser_rendering.markdown.create( account_id="account_id", html="

Hello World!

", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { @@ -271,7 +271,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn markdown = await async_client.browser_rendering.markdown.create( account_id="account_id", url="https://example.com/", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { @@ -389,7 +389,7 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn markdown = await async_client.browser_rendering.markdown.create( account_id="account_id", html="

Hello World!

", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { diff --git a/tests/api_resources/browser_rendering/test_pdf.py b/tests/api_resources/browser_rendering/test_pdf.py index 4c9e90a46d2..1e0b6fde88c 100644 --- a/tests/api_resources/browser_rendering/test_pdf.py +++ b/tests/api_resources/browser_rendering/test_pdf.py @@ -47,7 +47,7 @@ def test_method_create_with_all_params_overload_1(self, client: Cloudflare, resp pdf = client.browser_rendering.pdf.create( account_id="account_id", html="

Hello World!

", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { @@ -213,7 +213,7 @@ def test_method_create_with_all_params_overload_2(self, client: Cloudflare, resp pdf = client.browser_rendering.pdf.create( account_id="account_id", url="https://example.com/", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { @@ -387,7 +387,7 @@ async def test_method_create_with_all_params_overload_1( pdf = await async_client.browser_rendering.pdf.create( account_id="account_id", html="

Hello World!

", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { @@ -557,7 +557,7 @@ async def test_method_create_with_all_params_overload_2( pdf = await async_client.browser_rendering.pdf.create( account_id="account_id", url="https://example.com/", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { diff --git a/tests/api_resources/browser_rendering/test_scrape.py b/tests/api_resources/browser_rendering/test_scrape.py index e02f2924895..42800beed80 100644 --- a/tests/api_resources/browser_rendering/test_scrape.py +++ b/tests/api_resources/browser_rendering/test_scrape.py @@ -32,7 +32,7 @@ def test_method_create_with_all_params_overload_1(self, client: Cloudflare) -> N account_id="account_id", elements=[{"selector": "selector"}], html="

Hello World!

", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { @@ -155,7 +155,7 @@ def test_method_create_with_all_params_overload_2(self, client: Cloudflare) -> N account_id="account_id", elements=[{"selector": "selector"}], url="https://example.com/", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { @@ -284,7 +284,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn account_id="account_id", elements=[{"selector": "selector"}], html="

Hello World!

", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { @@ -407,7 +407,7 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn account_id="account_id", elements=[{"selector": "selector"}], url="https://example.com/", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { diff --git a/tests/api_resources/browser_rendering/test_screenshot.py b/tests/api_resources/browser_rendering/test_screenshot.py index 98d09071930..0f1147cedad 100644 --- a/tests/api_resources/browser_rendering/test_screenshot.py +++ b/tests/api_resources/browser_rendering/test_screenshot.py @@ -30,7 +30,7 @@ def test_method_create_with_all_params_overload_1(self, client: Cloudflare) -> N screenshot = client.browser_rendering.screenshot.create( account_id="account_id", html="

Hello World!

", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { @@ -167,7 +167,7 @@ def test_method_create_with_all_params_overload_2(self, client: Cloudflare) -> N screenshot = client.browser_rendering.screenshot.create( account_id="account_id", url="https://example.com/", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { @@ -310,7 +310,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn screenshot = await async_client.browser_rendering.screenshot.create( account_id="account_id", html="

Hello World!

", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { @@ -447,7 +447,7 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn screenshot = await async_client.browser_rendering.screenshot.create( account_id="account_id", url="https://example.com/", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { diff --git a/tests/api_resources/browser_rendering/test_snapshot.py b/tests/api_resources/browser_rendering/test_snapshot.py index 4c342c1d5eb..c19d9794baa 100644 --- a/tests/api_resources/browser_rendering/test_snapshot.py +++ b/tests/api_resources/browser_rendering/test_snapshot.py @@ -30,7 +30,7 @@ def test_method_create_with_all_params_overload_1(self, client: Cloudflare) -> N snapshot = client.browser_rendering.snapshot.create( account_id="account_id", html="

Hello World!

", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { @@ -164,7 +164,7 @@ def test_method_create_with_all_params_overload_2(self, client: Cloudflare) -> N snapshot = client.browser_rendering.snapshot.create( account_id="account_id", url="https://example.com/", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { @@ -304,7 +304,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn snapshot = await async_client.browser_rendering.snapshot.create( account_id="account_id", html="

Hello World!

", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { @@ -438,7 +438,7 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn snapshot = await async_client.browser_rendering.snapshot.create( account_id="account_id", url="https://example.com/", - cache_ttl=86400, + cache_ttl=0, action_timeout=120000, add_script_tag=[ { diff --git a/tests/api_resources/dns/test_records.py b/tests/api_resources/dns/test_records.py index 947da97ff7c..9c213e26706 100644 --- a/tests/api_resources/dns/test_records.py +++ b/tests/api_resources/dns/test_records.py @@ -5866,6 +5866,7 @@ def test_path_params_scan(self, client: Cloudflare) -> None: body={}, ) + @pytest.mark.skip(reason="mock server returns invalid data") @parametrize def test_method_scan_list(self, client: Cloudflare) -> None: record = client.dns.records.scan_list( @@ -5873,6 +5874,7 @@ def test_method_scan_list(self, client: Cloudflare) -> None: ) assert_matches_type(SyncSinglePage[RecordResponse], record, path=["response"]) + @pytest.mark.skip(reason="mock server returns invalid data") @parametrize def test_raw_response_scan_list(self, client: Cloudflare) -> None: response = client.dns.records.with_raw_response.scan_list( @@ -5884,6 +5886,7 @@ def test_raw_response_scan_list(self, client: Cloudflare) -> None: record = response.parse() assert_matches_type(SyncSinglePage[RecordResponse], record, path=["response"]) + @pytest.mark.skip(reason="mock server returns invalid data") @parametrize def test_streaming_response_scan_list(self, client: Cloudflare) -> None: with client.dns.records.with_streaming_response.scan_list( @@ -5897,6 +5900,7 @@ def test_streaming_response_scan_list(self, client: Cloudflare) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="mock server returns invalid data") @parametrize def test_path_params_scan_list(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): @@ -5904,6 +5908,7 @@ def test_path_params_scan_list(self, client: Cloudflare) -> None: zone_id="", ) + @pytest.mark.skip(reason="mock server returns invalid data") @parametrize def test_method_scan_review(self, client: Cloudflare) -> None: record = client.dns.records.scan_review( @@ -5911,6 +5916,7 @@ def test_method_scan_review(self, client: Cloudflare) -> None: ) assert_matches_type(Optional[RecordScanReviewResponse], record, path=["response"]) + @pytest.mark.skip(reason="mock server returns invalid data") @parametrize def test_method_scan_review_with_all_params(self, client: Cloudflare) -> None: record = client.dns.records.scan_review( @@ -5935,6 +5941,7 @@ def test_method_scan_review_with_all_params(self, client: Cloudflare) -> None: ) assert_matches_type(Optional[RecordScanReviewResponse], record, path=["response"]) + @pytest.mark.skip(reason="mock server returns invalid data") @parametrize def test_raw_response_scan_review(self, client: Cloudflare) -> None: response = client.dns.records.with_raw_response.scan_review( @@ -5946,6 +5953,7 @@ def test_raw_response_scan_review(self, client: Cloudflare) -> None: record = response.parse() assert_matches_type(Optional[RecordScanReviewResponse], record, path=["response"]) + @pytest.mark.skip(reason="mock server returns invalid data") @parametrize def test_streaming_response_scan_review(self, client: Cloudflare) -> None: with client.dns.records.with_streaming_response.scan_review( @@ -5959,6 +5967,7 @@ def test_streaming_response_scan_review(self, client: Cloudflare) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="mock server returns invalid data") @parametrize def test_path_params_scan_review(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): @@ -11848,6 +11857,7 @@ async def test_path_params_scan(self, async_client: AsyncCloudflare) -> None: body={}, ) + @pytest.mark.skip(reason="mock server returns invalid data") @parametrize async def test_method_scan_list(self, async_client: AsyncCloudflare) -> None: record = await async_client.dns.records.scan_list( @@ -11855,6 +11865,7 @@ async def test_method_scan_list(self, async_client: AsyncCloudflare) -> None: ) assert_matches_type(AsyncSinglePage[RecordResponse], record, path=["response"]) + @pytest.mark.skip(reason="mock server returns invalid data") @parametrize async def test_raw_response_scan_list(self, async_client: AsyncCloudflare) -> None: response = await async_client.dns.records.with_raw_response.scan_list( @@ -11866,6 +11877,7 @@ async def test_raw_response_scan_list(self, async_client: AsyncCloudflare) -> No record = await response.parse() assert_matches_type(AsyncSinglePage[RecordResponse], record, path=["response"]) + @pytest.mark.skip(reason="mock server returns invalid data") @parametrize async def test_streaming_response_scan_list(self, async_client: AsyncCloudflare) -> None: async with async_client.dns.records.with_streaming_response.scan_list( @@ -11879,6 +11891,7 @@ async def test_streaming_response_scan_list(self, async_client: AsyncCloudflare) assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="mock server returns invalid data") @parametrize async def test_path_params_scan_list(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): @@ -11886,6 +11899,7 @@ async def test_path_params_scan_list(self, async_client: AsyncCloudflare) -> Non zone_id="", ) + @pytest.mark.skip(reason="mock server returns invalid data") @parametrize async def test_method_scan_review(self, async_client: AsyncCloudflare) -> None: record = await async_client.dns.records.scan_review( @@ -11893,6 +11907,7 @@ async def test_method_scan_review(self, async_client: AsyncCloudflare) -> None: ) assert_matches_type(Optional[RecordScanReviewResponse], record, path=["response"]) + @pytest.mark.skip(reason="mock server returns invalid data") @parametrize async def test_method_scan_review_with_all_params(self, async_client: AsyncCloudflare) -> None: record = await async_client.dns.records.scan_review( @@ -11917,6 +11932,7 @@ async def test_method_scan_review_with_all_params(self, async_client: AsyncCloud ) assert_matches_type(Optional[RecordScanReviewResponse], record, path=["response"]) + @pytest.mark.skip(reason="mock server returns invalid data") @parametrize async def test_raw_response_scan_review(self, async_client: AsyncCloudflare) -> None: response = await async_client.dns.records.with_raw_response.scan_review( @@ -11928,6 +11944,7 @@ async def test_raw_response_scan_review(self, async_client: AsyncCloudflare) -> record = await response.parse() assert_matches_type(Optional[RecordScanReviewResponse], record, path=["response"]) + @pytest.mark.skip(reason="mock server returns invalid data") @parametrize async def test_streaming_response_scan_review(self, async_client: AsyncCloudflare) -> None: async with async_client.dns.records.with_streaming_response.scan_review( @@ -11941,6 +11958,7 @@ async def test_streaming_response_scan_review(self, async_client: AsyncCloudflar assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="mock server returns invalid data") @parametrize async def test_path_params_scan_review(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): diff --git a/tests/api_resources/email_security/investigate/test_detections.py b/tests/api_resources/email_security/investigate/test_detections.py index b9a5059538d..a8ae16ab645 100644 --- a/tests/api_resources/email_security/investigate/test_detections.py +++ b/tests/api_resources/email_security/investigate/test_detections.py @@ -20,7 +20,7 @@ class TestDetections: @parametrize def test_method_get(self, client: Cloudflare) -> None: detection = client.email_security.investigate.detections.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert_matches_type(DetectionGetResponse, detection, path=["response"]) @@ -28,7 +28,7 @@ def test_method_get(self, client: Cloudflare) -> None: @parametrize def test_raw_response_get(self, client: Cloudflare) -> None: response = client.email_security.investigate.detections.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) @@ -40,7 +40,7 @@ def test_raw_response_get(self, client: Cloudflare) -> None: @parametrize def test_streaming_response_get(self, client: Cloudflare) -> None: with client.email_security.investigate.detections.with_streaming_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed @@ -55,13 +55,13 @@ def test_streaming_response_get(self, client: Cloudflare) -> None: def test_path_params_get(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.email_security.investigate.detections.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `investigate_id` but received ''"): client.email_security.investigate.detections.with_raw_response.get( - postfix_id="", + investigate_id="", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) @@ -74,7 +74,7 @@ class TestAsyncDetections: @parametrize async def test_method_get(self, async_client: AsyncCloudflare) -> None: detection = await async_client.email_security.investigate.detections.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert_matches_type(DetectionGetResponse, detection, path=["response"]) @@ -82,7 +82,7 @@ async def test_method_get(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: response = await async_client.email_security.investigate.detections.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) @@ -94,7 +94,7 @@ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: async with async_client.email_security.investigate.detections.with_streaming_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed @@ -109,12 +109,12 @@ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> No async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.email_security.investigate.detections.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `investigate_id` but received ''"): await async_client.email_security.investigate.detections.with_raw_response.get( - postfix_id="", + investigate_id="", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) diff --git a/tests/api_resources/email_security/investigate/test_move.py b/tests/api_resources/email_security/investigate/test_move.py index 141f729f76e..cf738cea491 100644 --- a/tests/api_resources/email_security/investigate/test_move.py +++ b/tests/api_resources/email_security/investigate/test_move.py @@ -24,26 +24,16 @@ class TestMove: @parametrize def test_method_create(self, client: Cloudflare) -> None: move = client.email_security.investigate.move.create( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", destination="Inbox", ) - assert_matches_type(MoveCreateResponse, move, path=["response"]) - - @parametrize - def test_method_create_with_all_params(self, client: Cloudflare) -> None: - move = client.email_security.investigate.move.create( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - destination="Inbox", - submission=True, - ) - assert_matches_type(MoveCreateResponse, move, path=["response"]) + assert_matches_type(SyncSinglePage[MoveCreateResponse], move, path=["response"]) @parametrize def test_raw_response_create(self, client: Cloudflare) -> None: response = client.email_security.investigate.move.with_raw_response.create( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", destination="Inbox", ) @@ -51,12 +41,12 @@ def test_raw_response_create(self, client: Cloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" move = response.parse() - assert_matches_type(MoveCreateResponse, move, path=["response"]) + assert_matches_type(SyncSinglePage[MoveCreateResponse], move, path=["response"]) @parametrize def test_streaming_response_create(self, client: Cloudflare) -> None: with client.email_security.investigate.move.with_streaming_response.create( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", destination="Inbox", ) as response: @@ -64,7 +54,7 @@ def test_streaming_response_create(self, client: Cloudflare) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" move = response.parse() - assert_matches_type(MoveCreateResponse, move, path=["response"]) + assert_matches_type(SyncSinglePage[MoveCreateResponse], move, path=["response"]) assert cast(Any, response.is_closed) is True @@ -72,14 +62,14 @@ def test_streaming_response_create(self, client: Cloudflare) -> None: def test_path_params_create(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.email_security.investigate.move.with_raw_response.create( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="", destination="Inbox", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `investigate_id` but received ''"): client.email_security.investigate.move.with_raw_response.create( - postfix_id="", + investigate_id="", account_id="023e105f4ecef8ad9ca31a8372d0c353", destination="Inbox", ) @@ -97,7 +87,7 @@ def test_method_bulk_with_all_params(self, client: Cloudflare) -> None: move = client.email_security.investigate.move.bulk( account_id="023e105f4ecef8ad9ca31a8372d0c353", destination="Inbox", - ids=["string"], + ids=["4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678"], postfix_ids=["4Njp3P0STMz2c02Q"], ) assert_matches_type(SyncSinglePage[MoveBulkResponse], move, path=["response"]) @@ -145,26 +135,16 @@ class TestAsyncMove: @parametrize async def test_method_create(self, async_client: AsyncCloudflare) -> None: move = await async_client.email_security.investigate.move.create( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - destination="Inbox", - ) - assert_matches_type(MoveCreateResponse, move, path=["response"]) - - @parametrize - async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: - move = await async_client.email_security.investigate.move.create( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", destination="Inbox", - submission=True, ) - assert_matches_type(MoveCreateResponse, move, path=["response"]) + assert_matches_type(AsyncSinglePage[MoveCreateResponse], move, path=["response"]) @parametrize async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: response = await async_client.email_security.investigate.move.with_raw_response.create( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", destination="Inbox", ) @@ -172,12 +152,12 @@ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" move = await response.parse() - assert_matches_type(MoveCreateResponse, move, path=["response"]) + assert_matches_type(AsyncSinglePage[MoveCreateResponse], move, path=["response"]) @parametrize async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: async with async_client.email_security.investigate.move.with_streaming_response.create( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", destination="Inbox", ) as response: @@ -185,7 +165,7 @@ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> assert response.http_request.headers.get("X-Stainless-Lang") == "python" move = await response.parse() - assert_matches_type(MoveCreateResponse, move, path=["response"]) + assert_matches_type(AsyncSinglePage[MoveCreateResponse], move, path=["response"]) assert cast(Any, response.is_closed) is True @@ -193,14 +173,14 @@ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.email_security.investigate.move.with_raw_response.create( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="", destination="Inbox", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `investigate_id` but received ''"): await async_client.email_security.investigate.move.with_raw_response.create( - postfix_id="", + investigate_id="", account_id="023e105f4ecef8ad9ca31a8372d0c353", destination="Inbox", ) @@ -218,7 +198,7 @@ async def test_method_bulk_with_all_params(self, async_client: AsyncCloudflare) move = await async_client.email_security.investigate.move.bulk( account_id="023e105f4ecef8ad9ca31a8372d0c353", destination="Inbox", - ids=["string"], + ids=["4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678"], postfix_ids=["4Njp3P0STMz2c02Q"], ) assert_matches_type(AsyncSinglePage[MoveBulkResponse], move, path=["response"]) diff --git a/tests/api_resources/email_security/investigate/test_preview.py b/tests/api_resources/email_security/investigate/test_preview.py index 0d0cfa1bdac..47e7ed01f01 100644 --- a/tests/api_resources/email_security/investigate/test_preview.py +++ b/tests/api_resources/email_security/investigate/test_preview.py @@ -25,15 +25,6 @@ def test_method_create(self, client: Cloudflare) -> None: ) assert_matches_type(PreviewCreateResponse, preview, path=["response"]) - @parametrize - def test_method_create_with_all_params(self, client: Cloudflare) -> None: - preview = client.email_security.investigate.preview.create( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - postfix_id="4Njp3P0STMz2c02Q", - submission=True, - ) - assert_matches_type(PreviewCreateResponse, preview, path=["response"]) - @parametrize def test_raw_response_create(self, client: Cloudflare) -> None: response = client.email_security.investigate.preview.with_raw_response.create( @@ -71,7 +62,7 @@ def test_path_params_create(self, client: Cloudflare) -> None: @parametrize def test_method_get(self, client: Cloudflare) -> None: preview = client.email_security.investigate.preview.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert_matches_type(PreviewGetResponse, preview, path=["response"]) @@ -79,7 +70,7 @@ def test_method_get(self, client: Cloudflare) -> None: @parametrize def test_raw_response_get(self, client: Cloudflare) -> None: response = client.email_security.investigate.preview.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) @@ -91,7 +82,7 @@ def test_raw_response_get(self, client: Cloudflare) -> None: @parametrize def test_streaming_response_get(self, client: Cloudflare) -> None: with client.email_security.investigate.preview.with_streaming_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed @@ -106,13 +97,13 @@ def test_streaming_response_get(self, client: Cloudflare) -> None: def test_path_params_get(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.email_security.investigate.preview.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `investigate_id` but received ''"): client.email_security.investigate.preview.with_raw_response.get( - postfix_id="", + investigate_id="", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) @@ -130,15 +121,6 @@ async def test_method_create(self, async_client: AsyncCloudflare) -> None: ) assert_matches_type(PreviewCreateResponse, preview, path=["response"]) - @parametrize - async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: - preview = await async_client.email_security.investigate.preview.create( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - postfix_id="4Njp3P0STMz2c02Q", - submission=True, - ) - assert_matches_type(PreviewCreateResponse, preview, path=["response"]) - @parametrize async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: response = await async_client.email_security.investigate.preview.with_raw_response.create( @@ -176,7 +158,7 @@ async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_method_get(self, async_client: AsyncCloudflare) -> None: preview = await async_client.email_security.investigate.preview.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert_matches_type(PreviewGetResponse, preview, path=["response"]) @@ -184,7 +166,7 @@ async def test_method_get(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: response = await async_client.email_security.investigate.preview.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) @@ -196,7 +178,7 @@ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: async with async_client.email_security.investigate.preview.with_streaming_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed @@ -211,12 +193,12 @@ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> No async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.email_security.investigate.preview.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `investigate_id` but received ''"): await async_client.email_security.investigate.preview.with_raw_response.get( - postfix_id="", + investigate_id="", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) diff --git a/tests/api_resources/email_security/investigate/test_raw.py b/tests/api_resources/email_security/investigate/test_raw.py index 204fbb63f6b..79d72553050 100644 --- a/tests/api_resources/email_security/investigate/test_raw.py +++ b/tests/api_resources/email_security/investigate/test_raw.py @@ -20,7 +20,7 @@ class TestRaw: @parametrize def test_method_get(self, client: Cloudflare) -> None: raw = client.email_security.investigate.raw.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert_matches_type(RawGetResponse, raw, path=["response"]) @@ -28,7 +28,7 @@ def test_method_get(self, client: Cloudflare) -> None: @parametrize def test_raw_response_get(self, client: Cloudflare) -> None: response = client.email_security.investigate.raw.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) @@ -40,7 +40,7 @@ def test_raw_response_get(self, client: Cloudflare) -> None: @parametrize def test_streaming_response_get(self, client: Cloudflare) -> None: with client.email_security.investigate.raw.with_streaming_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed @@ -55,13 +55,13 @@ def test_streaming_response_get(self, client: Cloudflare) -> None: def test_path_params_get(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.email_security.investigate.raw.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `investigate_id` but received ''"): client.email_security.investigate.raw.with_raw_response.get( - postfix_id="", + investigate_id="", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) @@ -74,7 +74,7 @@ class TestAsyncRaw: @parametrize async def test_method_get(self, async_client: AsyncCloudflare) -> None: raw = await async_client.email_security.investigate.raw.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert_matches_type(RawGetResponse, raw, path=["response"]) @@ -82,7 +82,7 @@ async def test_method_get(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: response = await async_client.email_security.investigate.raw.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) @@ -94,7 +94,7 @@ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: async with async_client.email_security.investigate.raw.with_streaming_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed @@ -109,12 +109,12 @@ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> No async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.email_security.investigate.raw.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `investigate_id` but received ''"): await async_client.email_security.investigate.raw.with_raw_response.get( - postfix_id="", + investigate_id="", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) diff --git a/tests/api_resources/email_security/investigate/test_reclassify.py b/tests/api_resources/email_security/investigate/test_reclassify.py index 00739cafa7f..8fe07d41a74 100644 --- a/tests/api_resources/email_security/investigate/test_reclassify.py +++ b/tests/api_resources/email_security/investigate/test_reclassify.py @@ -19,7 +19,7 @@ class TestReclassify: @parametrize def test_method_create(self, client: Cloudflare) -> None: reclassify = client.email_security.investigate.reclassify.create( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", expected_disposition="NONE", ) @@ -28,10 +28,9 @@ def test_method_create(self, client: Cloudflare) -> None: @parametrize def test_method_create_with_all_params(self, client: Cloudflare) -> None: reclassify = client.email_security.investigate.reclassify.create( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", expected_disposition="NONE", - submission=True, eml_content="eml_content", escalated_submission_id="escalated_submission_id", ) @@ -40,7 +39,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: @parametrize def test_raw_response_create(self, client: Cloudflare) -> None: response = client.email_security.investigate.reclassify.with_raw_response.create( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", expected_disposition="NONE", ) @@ -53,7 +52,7 @@ def test_raw_response_create(self, client: Cloudflare) -> None: @parametrize def test_streaming_response_create(self, client: Cloudflare) -> None: with client.email_security.investigate.reclassify.with_streaming_response.create( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", expected_disposition="NONE", ) as response: @@ -69,14 +68,14 @@ def test_streaming_response_create(self, client: Cloudflare) -> None: def test_path_params_create(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.email_security.investigate.reclassify.with_raw_response.create( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="", expected_disposition="NONE", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `investigate_id` but received ''"): client.email_security.investigate.reclassify.with_raw_response.create( - postfix_id="", + investigate_id="", account_id="023e105f4ecef8ad9ca31a8372d0c353", expected_disposition="NONE", ) @@ -90,7 +89,7 @@ class TestAsyncReclassify: @parametrize async def test_method_create(self, async_client: AsyncCloudflare) -> None: reclassify = await async_client.email_security.investigate.reclassify.create( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", expected_disposition="NONE", ) @@ -99,10 +98,9 @@ async def test_method_create(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: reclassify = await async_client.email_security.investigate.reclassify.create( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", expected_disposition="NONE", - submission=True, eml_content="eml_content", escalated_submission_id="escalated_submission_id", ) @@ -111,7 +109,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare @parametrize async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: response = await async_client.email_security.investigate.reclassify.with_raw_response.create( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", expected_disposition="NONE", ) @@ -124,7 +122,7 @@ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: async with async_client.email_security.investigate.reclassify.with_streaming_response.create( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", expected_disposition="NONE", ) as response: @@ -140,14 +138,14 @@ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.email_security.investigate.reclassify.with_raw_response.create( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="", expected_disposition="NONE", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `investigate_id` but received ''"): await async_client.email_security.investigate.reclassify.with_raw_response.create( - postfix_id="", + investigate_id="", account_id="023e105f4ecef8ad9ca31a8372d0c353", expected_disposition="NONE", ) diff --git a/tests/api_resources/email_security/investigate/test_release.py b/tests/api_resources/email_security/investigate/test_release.py index 44430b8c827..92555d31686 100644 --- a/tests/api_resources/email_security/investigate/test_release.py +++ b/tests/api_resources/email_security/investigate/test_release.py @@ -22,7 +22,7 @@ class TestRelease: def test_method_bulk(self, client: Cloudflare) -> None: release = client.email_security.investigate.release.bulk( account_id="023e105f4ecef8ad9ca31a8372d0c353", - body=["4Njp3P0STMz2c02Q"], + body=["4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678"], ) assert_matches_type(SyncSinglePage[ReleaseBulkResponse], release, path=["response"]) @@ -30,7 +30,7 @@ def test_method_bulk(self, client: Cloudflare) -> None: def test_raw_response_bulk(self, client: Cloudflare) -> None: response = client.email_security.investigate.release.with_raw_response.bulk( account_id="023e105f4ecef8ad9ca31a8372d0c353", - body=["4Njp3P0STMz2c02Q"], + body=["4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678"], ) assert response.is_closed is True @@ -42,7 +42,7 @@ def test_raw_response_bulk(self, client: Cloudflare) -> None: def test_streaming_response_bulk(self, client: Cloudflare) -> None: with client.email_security.investigate.release.with_streaming_response.bulk( account_id="023e105f4ecef8ad9ca31a8372d0c353", - body=["4Njp3P0STMz2c02Q"], + body=["4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678"], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -57,7 +57,7 @@ def test_path_params_bulk(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.email_security.investigate.release.with_raw_response.bulk( account_id="", - body=["4Njp3P0STMz2c02Q"], + body=["4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678"], ) @@ -70,7 +70,7 @@ class TestAsyncRelease: async def test_method_bulk(self, async_client: AsyncCloudflare) -> None: release = await async_client.email_security.investigate.release.bulk( account_id="023e105f4ecef8ad9ca31a8372d0c353", - body=["4Njp3P0STMz2c02Q"], + body=["4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678"], ) assert_matches_type(AsyncSinglePage[ReleaseBulkResponse], release, path=["response"]) @@ -78,7 +78,7 @@ async def test_method_bulk(self, async_client: AsyncCloudflare) -> None: async def test_raw_response_bulk(self, async_client: AsyncCloudflare) -> None: response = await async_client.email_security.investigate.release.with_raw_response.bulk( account_id="023e105f4ecef8ad9ca31a8372d0c353", - body=["4Njp3P0STMz2c02Q"], + body=["4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678"], ) assert response.is_closed is True @@ -90,7 +90,7 @@ async def test_raw_response_bulk(self, async_client: AsyncCloudflare) -> None: async def test_streaming_response_bulk(self, async_client: AsyncCloudflare) -> None: async with async_client.email_security.investigate.release.with_streaming_response.bulk( account_id="023e105f4ecef8ad9ca31a8372d0c353", - body=["4Njp3P0STMz2c02Q"], + body=["4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678"], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -105,5 +105,5 @@ async def test_path_params_bulk(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.email_security.investigate.release.with_raw_response.bulk( account_id="", - body=["4Njp3P0STMz2c02Q"], + body=["4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678"], ) diff --git a/tests/api_resources/email_security/investigate/test_trace.py b/tests/api_resources/email_security/investigate/test_trace.py index d674b118b10..fdea6fe7a3a 100644 --- a/tests/api_resources/email_security/investigate/test_trace.py +++ b/tests/api_resources/email_security/investigate/test_trace.py @@ -20,24 +20,15 @@ class TestTrace: @parametrize def test_method_get(self, client: Cloudflare) -> None: trace = client.email_security.investigate.trace.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert_matches_type(TraceGetResponse, trace, path=["response"]) - @parametrize - def test_method_get_with_all_params(self, client: Cloudflare) -> None: - trace = client.email_security.investigate.trace.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - submission=True, - ) - assert_matches_type(TraceGetResponse, trace, path=["response"]) - @parametrize def test_raw_response_get(self, client: Cloudflare) -> None: response = client.email_security.investigate.trace.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) @@ -49,7 +40,7 @@ def test_raw_response_get(self, client: Cloudflare) -> None: @parametrize def test_streaming_response_get(self, client: Cloudflare) -> None: with client.email_security.investigate.trace.with_streaming_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed @@ -64,13 +55,13 @@ def test_streaming_response_get(self, client: Cloudflare) -> None: def test_path_params_get(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.email_security.investigate.trace.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `investigate_id` but received ''"): client.email_security.investigate.trace.with_raw_response.get( - postfix_id="", + investigate_id="", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) @@ -83,24 +74,15 @@ class TestAsyncTrace: @parametrize async def test_method_get(self, async_client: AsyncCloudflare) -> None: trace = await async_client.email_security.investigate.trace.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - assert_matches_type(TraceGetResponse, trace, path=["response"]) - - @parametrize - async def test_method_get_with_all_params(self, async_client: AsyncCloudflare) -> None: - trace = await async_client.email_security.investigate.trace.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", - submission=True, ) assert_matches_type(TraceGetResponse, trace, path=["response"]) @parametrize async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: response = await async_client.email_security.investigate.trace.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) @@ -112,7 +94,7 @@ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: async with async_client.email_security.investigate.trace.with_streaming_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed @@ -127,12 +109,12 @@ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> No async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.email_security.investigate.trace.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `investigate_id` but received ''"): await async_client.email_security.investigate.trace.with_raw_response.get( - postfix_id="", + investigate_id="", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) diff --git a/tests/api_resources/email_security/settings/test_allow_policies.py b/tests/api_resources/email_security/settings/test_allow_policies.py index 9957ba139f1..e6da1ccfdae 100644 --- a/tests/api_resources/email_security/settings/test_allow_policies.py +++ b/tests/api_resources/email_security/settings/test_allow_policies.py @@ -3,7 +3,7 @@ from __future__ import annotations import os -from typing import Any, cast +from typing import Any, Optional, cast import pytest @@ -36,7 +36,7 @@ def test_method_create(self, client: Cloudflare) -> None: pattern_type="EMAIL", verify_sender=True, ) - assert_matches_type(AllowPolicyCreateResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyCreateResponse], allow_policy, path=["response"]) @parametrize def test_method_create_with_all_params(self, client: Cloudflare) -> None: @@ -54,7 +54,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: is_sender=True, is_spoof=False, ) - assert_matches_type(AllowPolicyCreateResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyCreateResponse], allow_policy, path=["response"]) @parametrize def test_raw_response_create(self, client: Cloudflare) -> None: @@ -72,7 +72,7 @@ def test_raw_response_create(self, client: Cloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" allow_policy = response.parse() - assert_matches_type(AllowPolicyCreateResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyCreateResponse], allow_policy, path=["response"]) @parametrize def test_streaming_response_create(self, client: Cloudflare) -> None: @@ -90,7 +90,7 @@ def test_streaming_response_create(self, client: Cloudflare) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" allow_policy = response.parse() - assert_matches_type(AllowPolicyCreateResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyCreateResponse], allow_policy, path=["response"]) assert cast(Any, response.is_closed) is True @@ -122,15 +122,12 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: direction="asc", is_acceptable_sender=True, is_exempt_recipient=True, - is_recipient=True, - is_sender=True, - is_spoof=True, is_trusted_sender=True, order="pattern", page=1, pattern="pattern", pattern_type="EMAIL", - per_page=1, + per_page=20, search="search", verify_sender=True, ) @@ -170,34 +167,34 @@ def test_path_params_list(self, client: Cloudflare) -> None: @parametrize def test_method_delete(self, client: Cloudflare) -> None: allow_policy = client.email_security.settings.allow_policies.delete( - policy_id=2401, + policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(AllowPolicyDeleteResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyDeleteResponse], allow_policy, path=["response"]) @parametrize def test_raw_response_delete(self, client: Cloudflare) -> None: response = client.email_security.settings.allow_policies.with_raw_response.delete( - policy_id=2401, + policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" allow_policy = response.parse() - assert_matches_type(AllowPolicyDeleteResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyDeleteResponse], allow_policy, path=["response"]) @parametrize def test_streaming_response_delete(self, client: Cloudflare) -> None: with client.email_security.settings.allow_policies.with_streaming_response.delete( - policy_id=2401, + policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" allow_policy = response.parse() - assert_matches_type(AllowPolicyDeleteResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyDeleteResponse], allow_policy, path=["response"]) assert cast(Any, response.is_closed) is True @@ -205,99 +202,119 @@ def test_streaming_response_delete(self, client: Cloudflare) -> None: def test_path_params_delete(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.email_security.settings.allow_policies.with_raw_response.delete( - policy_id=2401, + policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) + with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_id` but received ''"): + client.email_security.settings.allow_policies.with_raw_response.delete( + policy_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize def test_method_edit(self, client: Cloudflare) -> None: allow_policy = client.email_security.settings.allow_policies.edit( - policy_id=2401, + policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(AllowPolicyEditResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyEditResponse], allow_policy, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize def test_method_edit_with_all_params(self, client: Cloudflare) -> None: allow_policy = client.email_security.settings.allow_policies.edit( - policy_id=2401, + policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", - comments="comments", - is_acceptable_sender=True, - is_exempt_recipient=True, - is_regex=True, + comments="Trust all messages send from test@example.com", + is_acceptable_sender=False, + is_exempt_recipient=False, + is_recipient=False, + is_regex=False, + is_sender=True, + is_spoof=False, is_trusted_sender=True, - pattern="x", + pattern="test@example.com", pattern_type="EMAIL", verify_sender=True, ) - assert_matches_type(AllowPolicyEditResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyEditResponse], allow_policy, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize def test_raw_response_edit(self, client: Cloudflare) -> None: response = client.email_security.settings.allow_policies.with_raw_response.edit( - policy_id=2401, + policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" allow_policy = response.parse() - assert_matches_type(AllowPolicyEditResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyEditResponse], allow_policy, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize def test_streaming_response_edit(self, client: Cloudflare) -> None: with client.email_security.settings.allow_policies.with_streaming_response.edit( - policy_id=2401, + policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" allow_policy = response.parse() - assert_matches_type(AllowPolicyEditResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyEditResponse], allow_policy, path=["response"]) assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize def test_path_params_edit(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.email_security.settings.allow_policies.with_raw_response.edit( - policy_id=2401, + policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) + with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_id` but received ''"): + client.email_security.settings.allow_policies.with_raw_response.edit( + policy_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + @parametrize def test_method_get(self, client: Cloudflare) -> None: allow_policy = client.email_security.settings.allow_policies.get( - policy_id=2401, + policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(AllowPolicyGetResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyGetResponse], allow_policy, path=["response"]) @parametrize def test_raw_response_get(self, client: Cloudflare) -> None: response = client.email_security.settings.allow_policies.with_raw_response.get( - policy_id=2401, + policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" allow_policy = response.parse() - assert_matches_type(AllowPolicyGetResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyGetResponse], allow_policy, path=["response"]) @parametrize def test_streaming_response_get(self, client: Cloudflare) -> None: with client.email_security.settings.allow_policies.with_streaming_response.get( - policy_id=2401, + policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" allow_policy = response.parse() - assert_matches_type(AllowPolicyGetResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyGetResponse], allow_policy, path=["response"]) assert cast(Any, response.is_closed) is True @@ -305,10 +322,16 @@ def test_streaming_response_get(self, client: Cloudflare) -> None: def test_path_params_get(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.email_security.settings.allow_policies.with_raw_response.get( - policy_id=2401, + policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) + with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_id` but received ''"): + client.email_security.settings.allow_policies.with_raw_response.get( + policy_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + class TestAsyncAllowPolicies: parametrize = pytest.mark.parametrize( @@ -327,7 +350,7 @@ async def test_method_create(self, async_client: AsyncCloudflare) -> None: pattern_type="EMAIL", verify_sender=True, ) - assert_matches_type(AllowPolicyCreateResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyCreateResponse], allow_policy, path=["response"]) @parametrize async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: @@ -345,7 +368,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare is_sender=True, is_spoof=False, ) - assert_matches_type(AllowPolicyCreateResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyCreateResponse], allow_policy, path=["response"]) @parametrize async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: @@ -363,7 +386,7 @@ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" allow_policy = await response.parse() - assert_matches_type(AllowPolicyCreateResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyCreateResponse], allow_policy, path=["response"]) @parametrize async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: @@ -381,7 +404,7 @@ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> assert response.http_request.headers.get("X-Stainless-Lang") == "python" allow_policy = await response.parse() - assert_matches_type(AllowPolicyCreateResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyCreateResponse], allow_policy, path=["response"]) assert cast(Any, response.is_closed) is True @@ -413,15 +436,12 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) direction="asc", is_acceptable_sender=True, is_exempt_recipient=True, - is_recipient=True, - is_sender=True, - is_spoof=True, is_trusted_sender=True, order="pattern", page=1, pattern="pattern", pattern_type="EMAIL", - per_page=1, + per_page=20, search="search", verify_sender=True, ) @@ -461,34 +481,34 @@ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_method_delete(self, async_client: AsyncCloudflare) -> None: allow_policy = await async_client.email_security.settings.allow_policies.delete( - policy_id=2401, + policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(AllowPolicyDeleteResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyDeleteResponse], allow_policy, path=["response"]) @parametrize async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: response = await async_client.email_security.settings.allow_policies.with_raw_response.delete( - policy_id=2401, + policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" allow_policy = await response.parse() - assert_matches_type(AllowPolicyDeleteResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyDeleteResponse], allow_policy, path=["response"]) @parametrize async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: async with async_client.email_security.settings.allow_policies.with_streaming_response.delete( - policy_id=2401, + policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" allow_policy = await response.parse() - assert_matches_type(AllowPolicyDeleteResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyDeleteResponse], allow_policy, path=["response"]) assert cast(Any, response.is_closed) is True @@ -496,99 +516,119 @@ async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.email_security.settings.allow_policies.with_raw_response.delete( - policy_id=2401, + policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) + with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_id` but received ''"): + await async_client.email_security.settings.allow_policies.with_raw_response.delete( + policy_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize async def test_method_edit(self, async_client: AsyncCloudflare) -> None: allow_policy = await async_client.email_security.settings.allow_policies.edit( - policy_id=2401, + policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(AllowPolicyEditResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyEditResponse], allow_policy, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) -> None: allow_policy = await async_client.email_security.settings.allow_policies.edit( - policy_id=2401, + policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", - comments="comments", - is_acceptable_sender=True, - is_exempt_recipient=True, - is_regex=True, + comments="Trust all messages send from test@example.com", + is_acceptable_sender=False, + is_exempt_recipient=False, + is_recipient=False, + is_regex=False, + is_sender=True, + is_spoof=False, is_trusted_sender=True, - pattern="x", + pattern="test@example.com", pattern_type="EMAIL", verify_sender=True, ) - assert_matches_type(AllowPolicyEditResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyEditResponse], allow_policy, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize async def test_raw_response_edit(self, async_client: AsyncCloudflare) -> None: response = await async_client.email_security.settings.allow_policies.with_raw_response.edit( - policy_id=2401, + policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" allow_policy = await response.parse() - assert_matches_type(AllowPolicyEditResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyEditResponse], allow_policy, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize async def test_streaming_response_edit(self, async_client: AsyncCloudflare) -> None: async with async_client.email_security.settings.allow_policies.with_streaming_response.edit( - policy_id=2401, + policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" allow_policy = await response.parse() - assert_matches_type(AllowPolicyEditResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyEditResponse], allow_policy, path=["response"]) assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize async def test_path_params_edit(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.email_security.settings.allow_policies.with_raw_response.edit( - policy_id=2401, + policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) + with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_id` but received ''"): + await async_client.email_security.settings.allow_policies.with_raw_response.edit( + policy_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + @parametrize async def test_method_get(self, async_client: AsyncCloudflare) -> None: allow_policy = await async_client.email_security.settings.allow_policies.get( - policy_id=2401, + policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(AllowPolicyGetResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyGetResponse], allow_policy, path=["response"]) @parametrize async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: response = await async_client.email_security.settings.allow_policies.with_raw_response.get( - policy_id=2401, + policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" allow_policy = await response.parse() - assert_matches_type(AllowPolicyGetResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyGetResponse], allow_policy, path=["response"]) @parametrize async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: async with async_client.email_security.settings.allow_policies.with_streaming_response.get( - policy_id=2401, + policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" allow_policy = await response.parse() - assert_matches_type(AllowPolicyGetResponse, allow_policy, path=["response"]) + assert_matches_type(Optional[AllowPolicyGetResponse], allow_policy, path=["response"]) assert cast(Any, response.is_closed) is True @@ -596,6 +636,12 @@ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> No async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.email_security.settings.allow_policies.with_raw_response.get( - policy_id=2401, + policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_id` but received ''"): + await async_client.email_security.settings.allow_policies.with_raw_response.get( + policy_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) diff --git a/tests/api_resources/email_security/settings/test_block_senders.py b/tests/api_resources/email_security/settings/test_block_senders.py index f2611adf7dd..4be3b0b5cd8 100644 --- a/tests/api_resources/email_security/settings/test_block_senders.py +++ b/tests/api_resources/email_security/settings/test_block_senders.py @@ -3,7 +3,7 @@ from __future__ import annotations import os -from typing import Any, cast +from typing import Any, Optional, cast import pytest @@ -32,7 +32,7 @@ def test_method_create(self, client: Cloudflare) -> None: pattern="test@example.com", pattern_type="EMAIL", ) - assert_matches_type(BlockSenderCreateResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderCreateResponse], block_sender, path=["response"]) @parametrize def test_method_create_with_all_params(self, client: Cloudflare) -> None: @@ -41,9 +41,9 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: is_regex=False, pattern="test@example.com", pattern_type="EMAIL", - comments="block sender with email test@example.com", + comments="Block sender with email test@example.com", ) - assert_matches_type(BlockSenderCreateResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderCreateResponse], block_sender, path=["response"]) @parametrize def test_raw_response_create(self, client: Cloudflare) -> None: @@ -57,7 +57,7 @@ def test_raw_response_create(self, client: Cloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" block_sender = response.parse() - assert_matches_type(BlockSenderCreateResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderCreateResponse], block_sender, path=["response"]) @parametrize def test_streaming_response_create(self, client: Cloudflare) -> None: @@ -71,7 +71,7 @@ def test_streaming_response_create(self, client: Cloudflare) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" block_sender = response.parse() - assert_matches_type(BlockSenderCreateResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderCreateResponse], block_sender, path=["response"]) assert cast(Any, response.is_closed) is True @@ -101,7 +101,7 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: page=1, pattern="pattern", pattern_type="EMAIL", - per_page=1, + per_page=20, search="search", ) assert_matches_type(SyncV4PagePaginationArray[BlockSenderListResponse], block_sender, path=["response"]) @@ -140,34 +140,34 @@ def test_path_params_list(self, client: Cloudflare) -> None: @parametrize def test_method_delete(self, client: Cloudflare) -> None: block_sender = client.email_security.settings.block_senders.delete( - pattern_id=2402, + pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(BlockSenderDeleteResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderDeleteResponse], block_sender, path=["response"]) @parametrize def test_raw_response_delete(self, client: Cloudflare) -> None: response = client.email_security.settings.block_senders.with_raw_response.delete( - pattern_id=2402, + pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" block_sender = response.parse() - assert_matches_type(BlockSenderDeleteResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderDeleteResponse], block_sender, path=["response"]) @parametrize def test_streaming_response_delete(self, client: Cloudflare) -> None: with client.email_security.settings.block_senders.with_streaming_response.delete( - pattern_id=2402, + pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" block_sender = response.parse() - assert_matches_type(BlockSenderDeleteResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderDeleteResponse], block_sender, path=["response"]) assert cast(Any, response.is_closed) is True @@ -175,95 +175,112 @@ def test_streaming_response_delete(self, client: Cloudflare) -> None: def test_path_params_delete(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.email_security.settings.block_senders.with_raw_response.delete( - pattern_id=2402, + pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) + with pytest.raises(ValueError, match=r"Expected a non-empty value for `pattern_id` but received ''"): + client.email_security.settings.block_senders.with_raw_response.delete( + pattern_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize def test_method_edit(self, client: Cloudflare) -> None: block_sender = client.email_security.settings.block_senders.edit( - pattern_id=2402, + pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(BlockSenderEditResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderEditResponse], block_sender, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize def test_method_edit_with_all_params(self, client: Cloudflare) -> None: block_sender = client.email_security.settings.block_senders.edit( - pattern_id=2402, + pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", - comments="comments", - is_regex=True, - pattern="x", + comments="Block sender with email test@example.com", + is_regex=False, + pattern="test@example.com", pattern_type="EMAIL", ) - assert_matches_type(BlockSenderEditResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderEditResponse], block_sender, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize def test_raw_response_edit(self, client: Cloudflare) -> None: response = client.email_security.settings.block_senders.with_raw_response.edit( - pattern_id=2402, + pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" block_sender = response.parse() - assert_matches_type(BlockSenderEditResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderEditResponse], block_sender, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize def test_streaming_response_edit(self, client: Cloudflare) -> None: with client.email_security.settings.block_senders.with_streaming_response.edit( - pattern_id=2402, + pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" block_sender = response.parse() - assert_matches_type(BlockSenderEditResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderEditResponse], block_sender, path=["response"]) assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize def test_path_params_edit(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.email_security.settings.block_senders.with_raw_response.edit( - pattern_id=2402, + pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) + with pytest.raises(ValueError, match=r"Expected a non-empty value for `pattern_id` but received ''"): + client.email_security.settings.block_senders.with_raw_response.edit( + pattern_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + @parametrize def test_method_get(self, client: Cloudflare) -> None: block_sender = client.email_security.settings.block_senders.get( - pattern_id=2402, + pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(BlockSenderGetResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderGetResponse], block_sender, path=["response"]) @parametrize def test_raw_response_get(self, client: Cloudflare) -> None: response = client.email_security.settings.block_senders.with_raw_response.get( - pattern_id=2402, + pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" block_sender = response.parse() - assert_matches_type(BlockSenderGetResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderGetResponse], block_sender, path=["response"]) @parametrize def test_streaming_response_get(self, client: Cloudflare) -> None: with client.email_security.settings.block_senders.with_streaming_response.get( - pattern_id=2402, + pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" block_sender = response.parse() - assert_matches_type(BlockSenderGetResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderGetResponse], block_sender, path=["response"]) assert cast(Any, response.is_closed) is True @@ -271,10 +288,16 @@ def test_streaming_response_get(self, client: Cloudflare) -> None: def test_path_params_get(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.email_security.settings.block_senders.with_raw_response.get( - pattern_id=2402, + pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) + with pytest.raises(ValueError, match=r"Expected a non-empty value for `pattern_id` but received ''"): + client.email_security.settings.block_senders.with_raw_response.get( + pattern_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + class TestAsyncBlockSenders: parametrize = pytest.mark.parametrize( @@ -289,7 +312,7 @@ async def test_method_create(self, async_client: AsyncCloudflare) -> None: pattern="test@example.com", pattern_type="EMAIL", ) - assert_matches_type(BlockSenderCreateResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderCreateResponse], block_sender, path=["response"]) @parametrize async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: @@ -298,9 +321,9 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare is_regex=False, pattern="test@example.com", pattern_type="EMAIL", - comments="block sender with email test@example.com", + comments="Block sender with email test@example.com", ) - assert_matches_type(BlockSenderCreateResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderCreateResponse], block_sender, path=["response"]) @parametrize async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: @@ -314,7 +337,7 @@ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" block_sender = await response.parse() - assert_matches_type(BlockSenderCreateResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderCreateResponse], block_sender, path=["response"]) @parametrize async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: @@ -328,7 +351,7 @@ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> assert response.http_request.headers.get("X-Stainless-Lang") == "python" block_sender = await response.parse() - assert_matches_type(BlockSenderCreateResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderCreateResponse], block_sender, path=["response"]) assert cast(Any, response.is_closed) is True @@ -358,7 +381,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) page=1, pattern="pattern", pattern_type="EMAIL", - per_page=1, + per_page=20, search="search", ) assert_matches_type(AsyncV4PagePaginationArray[BlockSenderListResponse], block_sender, path=["response"]) @@ -397,34 +420,34 @@ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_method_delete(self, async_client: AsyncCloudflare) -> None: block_sender = await async_client.email_security.settings.block_senders.delete( - pattern_id=2402, + pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(BlockSenderDeleteResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderDeleteResponse], block_sender, path=["response"]) @parametrize async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: response = await async_client.email_security.settings.block_senders.with_raw_response.delete( - pattern_id=2402, + pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" block_sender = await response.parse() - assert_matches_type(BlockSenderDeleteResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderDeleteResponse], block_sender, path=["response"]) @parametrize async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: async with async_client.email_security.settings.block_senders.with_streaming_response.delete( - pattern_id=2402, + pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" block_sender = await response.parse() - assert_matches_type(BlockSenderDeleteResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderDeleteResponse], block_sender, path=["response"]) assert cast(Any, response.is_closed) is True @@ -432,95 +455,112 @@ async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.email_security.settings.block_senders.with_raw_response.delete( - pattern_id=2402, + pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) + with pytest.raises(ValueError, match=r"Expected a non-empty value for `pattern_id` but received ''"): + await async_client.email_security.settings.block_senders.with_raw_response.delete( + pattern_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize async def test_method_edit(self, async_client: AsyncCloudflare) -> None: block_sender = await async_client.email_security.settings.block_senders.edit( - pattern_id=2402, + pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(BlockSenderEditResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderEditResponse], block_sender, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) -> None: block_sender = await async_client.email_security.settings.block_senders.edit( - pattern_id=2402, + pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", - comments="comments", - is_regex=True, - pattern="x", + comments="Block sender with email test@example.com", + is_regex=False, + pattern="test@example.com", pattern_type="EMAIL", ) - assert_matches_type(BlockSenderEditResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderEditResponse], block_sender, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize async def test_raw_response_edit(self, async_client: AsyncCloudflare) -> None: response = await async_client.email_security.settings.block_senders.with_raw_response.edit( - pattern_id=2402, + pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" block_sender = await response.parse() - assert_matches_type(BlockSenderEditResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderEditResponse], block_sender, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize async def test_streaming_response_edit(self, async_client: AsyncCloudflare) -> None: async with async_client.email_security.settings.block_senders.with_streaming_response.edit( - pattern_id=2402, + pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" block_sender = await response.parse() - assert_matches_type(BlockSenderEditResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderEditResponse], block_sender, path=["response"]) assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize async def test_path_params_edit(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.email_security.settings.block_senders.with_raw_response.edit( - pattern_id=2402, + pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) + with pytest.raises(ValueError, match=r"Expected a non-empty value for `pattern_id` but received ''"): + await async_client.email_security.settings.block_senders.with_raw_response.edit( + pattern_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + @parametrize async def test_method_get(self, async_client: AsyncCloudflare) -> None: block_sender = await async_client.email_security.settings.block_senders.get( - pattern_id=2402, + pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(BlockSenderGetResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderGetResponse], block_sender, path=["response"]) @parametrize async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: response = await async_client.email_security.settings.block_senders.with_raw_response.get( - pattern_id=2402, + pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" block_sender = await response.parse() - assert_matches_type(BlockSenderGetResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderGetResponse], block_sender, path=["response"]) @parametrize async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: async with async_client.email_security.settings.block_senders.with_streaming_response.get( - pattern_id=2402, + pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" block_sender = await response.parse() - assert_matches_type(BlockSenderGetResponse, block_sender, path=["response"]) + assert_matches_type(Optional[BlockSenderGetResponse], block_sender, path=["response"]) assert cast(Any, response.is_closed) is True @@ -528,6 +568,12 @@ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> No async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.email_security.settings.block_senders.with_raw_response.get( - pattern_id=2402, + pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `pattern_id` but received ''"): + await async_client.email_security.settings.block_senders.with_raw_response.get( + pattern_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) diff --git a/tests/api_resources/email_security/settings/test_domains.py b/tests/api_resources/email_security/settings/test_domains.py index f7a0c73a988..2336b6321de 100644 --- a/tests/api_resources/email_security/settings/test_domains.py +++ b/tests/api_resources/email_security/settings/test_domains.py @@ -3,19 +3,18 @@ from __future__ import annotations import os -from typing import Any, cast +from typing import Any, Optional, cast import pytest from cloudflare import Cloudflare, AsyncCloudflare from tests.utils import assert_matches_type -from cloudflare.pagination import SyncSinglePage, AsyncSinglePage, SyncV4PagePaginationArray, AsyncV4PagePaginationArray +from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray from cloudflare.types.email_security.settings import ( DomainGetResponse, DomainEditResponse, DomainListResponse, DomainDeleteResponse, - DomainBulkDeleteResponse, ) base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -42,8 +41,9 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: integration_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", order="domain", page=1, - per_page=1, + per_page=20, search="search", + status="pending", ) assert_matches_type(SyncV4PagePaginationArray[DomainListResponse], domain, path=["response"]) @@ -81,34 +81,34 @@ def test_path_params_list(self, client: Cloudflare) -> None: @parametrize def test_method_delete(self, client: Cloudflare) -> None: domain = client.email_security.settings.domains.delete( - domain_id=2400, + domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(DomainDeleteResponse, domain, path=["response"]) + assert_matches_type(Optional[DomainDeleteResponse], domain, path=["response"]) @parametrize def test_raw_response_delete(self, client: Cloudflare) -> None: response = client.email_security.settings.domains.with_raw_response.delete( - domain_id=2400, + domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" domain = response.parse() - assert_matches_type(DomainDeleteResponse, domain, path=["response"]) + assert_matches_type(Optional[DomainDeleteResponse], domain, path=["response"]) @parametrize def test_streaming_response_delete(self, client: Cloudflare) -> None: with client.email_security.settings.domains.with_streaming_response.delete( - domain_id=2400, + domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" domain = response.parse() - assert_matches_type(DomainDeleteResponse, domain, path=["response"]) + assert_matches_type(Optional[DomainDeleteResponse], domain, path=["response"]) assert cast(Any, response.is_closed) is True @@ -116,101 +116,66 @@ def test_streaming_response_delete(self, client: Cloudflare) -> None: def test_path_params_delete(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.email_security.settings.domains.with_raw_response.delete( - domain_id=2400, + domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) - @parametrize - def test_method_bulk_delete(self, client: Cloudflare) -> None: - domain = client.email_security.settings.domains.bulk_delete( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - assert_matches_type(SyncSinglePage[DomainBulkDeleteResponse], domain, path=["response"]) - - @parametrize - def test_raw_response_bulk_delete(self, client: Cloudflare) -> None: - response = client.email_security.settings.domains.with_raw_response.bulk_delete( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - domain = response.parse() - assert_matches_type(SyncSinglePage[DomainBulkDeleteResponse], domain, path=["response"]) - - @parametrize - def test_streaming_response_bulk_delete(self, client: Cloudflare) -> None: - with client.email_security.settings.domains.with_streaming_response.bulk_delete( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - domain = response.parse() - assert_matches_type(SyncSinglePage[DomainBulkDeleteResponse], domain, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_bulk_delete(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.email_security.settings.domains.with_raw_response.bulk_delete( - account_id="", + with pytest.raises(ValueError, match=r"Expected a non-empty value for `domain_id` but received ''"): + client.email_security.settings.domains.with_raw_response.delete( + domain_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", ) @parametrize def test_method_edit(self, client: Cloudflare) -> None: domain = client.email_security.settings.domains.edit( - domain_id=2400, + domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", - ip_restrictions=["192.0.2.0/24", "2001:db8::/32"], ) - assert_matches_type(DomainEditResponse, domain, path=["response"]) + assert_matches_type(Optional[DomainEditResponse], domain, path=["response"]) @parametrize def test_method_edit_with_all_params(self, client: Cloudflare) -> None: domain = client.email_security.settings.domains.edit( - domain_id=2400, + domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", - ip_restrictions=["192.0.2.0/24", "2001:db8::/32"], allowed_delivery_modes=["DIRECT"], domain="domain", drop_dispositions=["MALICIOUS"], folder="AllItems", integration_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ip_restrictions=["192.0.2.0/24", "2001:db8::/32"], lookback_hops=1, regions=["GLOBAL"], require_tls_inbound=True, require_tls_outbound=True, transport="transport", ) - assert_matches_type(DomainEditResponse, domain, path=["response"]) + assert_matches_type(Optional[DomainEditResponse], domain, path=["response"]) @parametrize def test_raw_response_edit(self, client: Cloudflare) -> None: response = client.email_security.settings.domains.with_raw_response.edit( - domain_id=2400, + domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", - ip_restrictions=["192.0.2.0/24", "2001:db8::/32"], ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" domain = response.parse() - assert_matches_type(DomainEditResponse, domain, path=["response"]) + assert_matches_type(Optional[DomainEditResponse], domain, path=["response"]) @parametrize def test_streaming_response_edit(self, client: Cloudflare) -> None: with client.email_security.settings.domains.with_streaming_response.edit( - domain_id=2400, + domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", - ip_restrictions=["192.0.2.0/24", "2001:db8::/32"], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" domain = response.parse() - assert_matches_type(DomainEditResponse, domain, path=["response"]) + assert_matches_type(Optional[DomainEditResponse], domain, path=["response"]) assert cast(Any, response.is_closed) is True @@ -218,42 +183,47 @@ def test_streaming_response_edit(self, client: Cloudflare) -> None: def test_path_params_edit(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.email_security.settings.domains.with_raw_response.edit( - domain_id=2400, + domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", - ip_restrictions=["192.0.2.0/24", "2001:db8::/32"], + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `domain_id` but received ''"): + client.email_security.settings.domains.with_raw_response.edit( + domain_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", ) @parametrize def test_method_get(self, client: Cloudflare) -> None: domain = client.email_security.settings.domains.get( - domain_id=2400, + domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(DomainGetResponse, domain, path=["response"]) + assert_matches_type(Optional[DomainGetResponse], domain, path=["response"]) @parametrize def test_raw_response_get(self, client: Cloudflare) -> None: response = client.email_security.settings.domains.with_raw_response.get( - domain_id=2400, + domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" domain = response.parse() - assert_matches_type(DomainGetResponse, domain, path=["response"]) + assert_matches_type(Optional[DomainGetResponse], domain, path=["response"]) @parametrize def test_streaming_response_get(self, client: Cloudflare) -> None: with client.email_security.settings.domains.with_streaming_response.get( - domain_id=2400, + domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" domain = response.parse() - assert_matches_type(DomainGetResponse, domain, path=["response"]) + assert_matches_type(Optional[DomainGetResponse], domain, path=["response"]) assert cast(Any, response.is_closed) is True @@ -261,10 +231,16 @@ def test_streaming_response_get(self, client: Cloudflare) -> None: def test_path_params_get(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.email_security.settings.domains.with_raw_response.get( - domain_id=2400, + domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) + with pytest.raises(ValueError, match=r"Expected a non-empty value for `domain_id` but received ''"): + client.email_security.settings.domains.with_raw_response.get( + domain_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + class TestAsyncDomains: parametrize = pytest.mark.parametrize( @@ -289,8 +265,9 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) integration_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", order="domain", page=1, - per_page=1, + per_page=20, search="search", + status="pending", ) assert_matches_type(AsyncV4PagePaginationArray[DomainListResponse], domain, path=["response"]) @@ -328,34 +305,34 @@ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_method_delete(self, async_client: AsyncCloudflare) -> None: domain = await async_client.email_security.settings.domains.delete( - domain_id=2400, + domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(DomainDeleteResponse, domain, path=["response"]) + assert_matches_type(Optional[DomainDeleteResponse], domain, path=["response"]) @parametrize async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: response = await async_client.email_security.settings.domains.with_raw_response.delete( - domain_id=2400, + domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" domain = await response.parse() - assert_matches_type(DomainDeleteResponse, domain, path=["response"]) + assert_matches_type(Optional[DomainDeleteResponse], domain, path=["response"]) @parametrize async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: async with async_client.email_security.settings.domains.with_streaming_response.delete( - domain_id=2400, + domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" domain = await response.parse() - assert_matches_type(DomainDeleteResponse, domain, path=["response"]) + assert_matches_type(Optional[DomainDeleteResponse], domain, path=["response"]) assert cast(Any, response.is_closed) is True @@ -363,101 +340,66 @@ async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.email_security.settings.domains.with_raw_response.delete( - domain_id=2400, + domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) - @parametrize - async def test_method_bulk_delete(self, async_client: AsyncCloudflare) -> None: - domain = await async_client.email_security.settings.domains.bulk_delete( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - assert_matches_type(AsyncSinglePage[DomainBulkDeleteResponse], domain, path=["response"]) - - @parametrize - async def test_raw_response_bulk_delete(self, async_client: AsyncCloudflare) -> None: - response = await async_client.email_security.settings.domains.with_raw_response.bulk_delete( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - domain = await response.parse() - assert_matches_type(AsyncSinglePage[DomainBulkDeleteResponse], domain, path=["response"]) - - @parametrize - async def test_streaming_response_bulk_delete(self, async_client: AsyncCloudflare) -> None: - async with async_client.email_security.settings.domains.with_streaming_response.bulk_delete( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - domain = await response.parse() - assert_matches_type(AsyncSinglePage[DomainBulkDeleteResponse], domain, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_bulk_delete(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.email_security.settings.domains.with_raw_response.bulk_delete( - account_id="", + with pytest.raises(ValueError, match=r"Expected a non-empty value for `domain_id` but received ''"): + await async_client.email_security.settings.domains.with_raw_response.delete( + domain_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", ) @parametrize async def test_method_edit(self, async_client: AsyncCloudflare) -> None: domain = await async_client.email_security.settings.domains.edit( - domain_id=2400, + domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", - ip_restrictions=["192.0.2.0/24", "2001:db8::/32"], ) - assert_matches_type(DomainEditResponse, domain, path=["response"]) + assert_matches_type(Optional[DomainEditResponse], domain, path=["response"]) @parametrize async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) -> None: domain = await async_client.email_security.settings.domains.edit( - domain_id=2400, + domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", - ip_restrictions=["192.0.2.0/24", "2001:db8::/32"], allowed_delivery_modes=["DIRECT"], domain="domain", drop_dispositions=["MALICIOUS"], folder="AllItems", integration_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ip_restrictions=["192.0.2.0/24", "2001:db8::/32"], lookback_hops=1, regions=["GLOBAL"], require_tls_inbound=True, require_tls_outbound=True, transport="transport", ) - assert_matches_type(DomainEditResponse, domain, path=["response"]) + assert_matches_type(Optional[DomainEditResponse], domain, path=["response"]) @parametrize async def test_raw_response_edit(self, async_client: AsyncCloudflare) -> None: response = await async_client.email_security.settings.domains.with_raw_response.edit( - domain_id=2400, + domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", - ip_restrictions=["192.0.2.0/24", "2001:db8::/32"], ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" domain = await response.parse() - assert_matches_type(DomainEditResponse, domain, path=["response"]) + assert_matches_type(Optional[DomainEditResponse], domain, path=["response"]) @parametrize async def test_streaming_response_edit(self, async_client: AsyncCloudflare) -> None: async with async_client.email_security.settings.domains.with_streaming_response.edit( - domain_id=2400, + domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", - ip_restrictions=["192.0.2.0/24", "2001:db8::/32"], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" domain = await response.parse() - assert_matches_type(DomainEditResponse, domain, path=["response"]) + assert_matches_type(Optional[DomainEditResponse], domain, path=["response"]) assert cast(Any, response.is_closed) is True @@ -465,42 +407,47 @@ async def test_streaming_response_edit(self, async_client: AsyncCloudflare) -> N async def test_path_params_edit(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.email_security.settings.domains.with_raw_response.edit( - domain_id=2400, + domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", - ip_restrictions=["192.0.2.0/24", "2001:db8::/32"], + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `domain_id` but received ''"): + await async_client.email_security.settings.domains.with_raw_response.edit( + domain_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", ) @parametrize async def test_method_get(self, async_client: AsyncCloudflare) -> None: domain = await async_client.email_security.settings.domains.get( - domain_id=2400, + domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(DomainGetResponse, domain, path=["response"]) + assert_matches_type(Optional[DomainGetResponse], domain, path=["response"]) @parametrize async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: response = await async_client.email_security.settings.domains.with_raw_response.get( - domain_id=2400, + domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" domain = await response.parse() - assert_matches_type(DomainGetResponse, domain, path=["response"]) + assert_matches_type(Optional[DomainGetResponse], domain, path=["response"]) @parametrize async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: async with async_client.email_security.settings.domains.with_streaming_response.get( - domain_id=2400, + domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" domain = await response.parse() - assert_matches_type(DomainGetResponse, domain, path=["response"]) + assert_matches_type(Optional[DomainGetResponse], domain, path=["response"]) assert cast(Any, response.is_closed) is True @@ -508,6 +455,12 @@ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> No async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.email_security.settings.domains.with_raw_response.get( - domain_id=2400, + domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `domain_id` but received ''"): + await async_client.email_security.settings.domains.with_raw_response.get( + domain_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) diff --git a/tests/api_resources/email_security/settings/test_impersonation_registry.py b/tests/api_resources/email_security/settings/test_impersonation_registry.py index 0d484d1724d..ae9f0fada97 100644 --- a/tests/api_resources/email_security/settings/test_impersonation_registry.py +++ b/tests/api_resources/email_security/settings/test_impersonation_registry.py @@ -3,7 +3,7 @@ from __future__ import annotations import os -from typing import Any, cast +from typing import Any, Optional, cast import pytest @@ -28,39 +28,56 @@ class TestImpersonationRegistry: def test_method_create(self, client: Cloudflare) -> None: impersonation_registry = client.email_security.settings.impersonation_registry.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", - email="email", - is_email_regex=True, - name="name", + email="john.doe@example.com", + is_email_regex=False, + name="John Doe", ) - assert_matches_type(ImpersonationRegistryCreateResponse, impersonation_registry, path=["response"]) + assert_matches_type(Optional[ImpersonationRegistryCreateResponse], impersonation_registry, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: Cloudflare) -> None: + impersonation_registry = client.email_security.settings.impersonation_registry.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + email="john.doe@example.com", + is_email_regex=False, + name="John Doe", + comments="comments", + directory_id=0, + directory_node_id=0, + external_directory_node_id="external_directory_node_id", + provenance="A1S_INTERNAL", + ) + assert_matches_type(Optional[ImpersonationRegistryCreateResponse], impersonation_registry, path=["response"]) @parametrize def test_raw_response_create(self, client: Cloudflare) -> None: response = client.email_security.settings.impersonation_registry.with_raw_response.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", - email="email", - is_email_regex=True, - name="name", + email="john.doe@example.com", + is_email_regex=False, + name="John Doe", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" impersonation_registry = response.parse() - assert_matches_type(ImpersonationRegistryCreateResponse, impersonation_registry, path=["response"]) + assert_matches_type(Optional[ImpersonationRegistryCreateResponse], impersonation_registry, path=["response"]) @parametrize def test_streaming_response_create(self, client: Cloudflare) -> None: with client.email_security.settings.impersonation_registry.with_streaming_response.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", - email="email", - is_email_regex=True, - name="name", + email="john.doe@example.com", + is_email_regex=False, + name="John Doe", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" impersonation_registry = response.parse() - assert_matches_type(ImpersonationRegistryCreateResponse, impersonation_registry, path=["response"]) + assert_matches_type( + Optional[ImpersonationRegistryCreateResponse], impersonation_registry, path=["response"] + ) assert cast(Any, response.is_closed) is True @@ -69,9 +86,9 @@ def test_path_params_create(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.email_security.settings.impersonation_registry.with_raw_response.create( account_id="", - email="email", - is_email_regex=True, - name="name", + email="john.doe@example.com", + is_email_regex=False, + name="John Doe", ) @parametrize @@ -90,7 +107,7 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: direction="asc", order="name", page=1, - per_page=1, + per_page=20, provenance="A1S_INTERNAL", search="search", ) @@ -136,34 +153,36 @@ def test_path_params_list(self, client: Cloudflare) -> None: @parametrize def test_method_delete(self, client: Cloudflare) -> None: impersonation_registry = client.email_security.settings.impersonation_registry.delete( - display_name_id=2403, + impersonation_registry_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(ImpersonationRegistryDeleteResponse, impersonation_registry, path=["response"]) + assert_matches_type(Optional[ImpersonationRegistryDeleteResponse], impersonation_registry, path=["response"]) @parametrize def test_raw_response_delete(self, client: Cloudflare) -> None: response = client.email_security.settings.impersonation_registry.with_raw_response.delete( - display_name_id=2403, + impersonation_registry_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" impersonation_registry = response.parse() - assert_matches_type(ImpersonationRegistryDeleteResponse, impersonation_registry, path=["response"]) + assert_matches_type(Optional[ImpersonationRegistryDeleteResponse], impersonation_registry, path=["response"]) @parametrize def test_streaming_response_delete(self, client: Cloudflare) -> None: with client.email_security.settings.impersonation_registry.with_streaming_response.delete( - display_name_id=2403, + impersonation_registry_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" impersonation_registry = response.parse() - assert_matches_type(ImpersonationRegistryDeleteResponse, impersonation_registry, path=["response"]) + assert_matches_type( + Optional[ImpersonationRegistryDeleteResponse], impersonation_registry, path=["response"] + ) assert cast(Any, response.is_closed) is True @@ -171,94 +190,120 @@ def test_streaming_response_delete(self, client: Cloudflare) -> None: def test_path_params_delete(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.email_security.settings.impersonation_registry.with_raw_response.delete( - display_name_id=2403, + impersonation_registry_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) + with pytest.raises( + ValueError, match=r"Expected a non-empty value for `impersonation_registry_id` but received ''" + ): + client.email_security.settings.impersonation_registry.with_raw_response.delete( + impersonation_registry_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize def test_method_edit(self, client: Cloudflare) -> None: impersonation_registry = client.email_security.settings.impersonation_registry.edit( - display_name_id=2403, + impersonation_registry_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(ImpersonationRegistryEditResponse, impersonation_registry, path=["response"]) + assert_matches_type(Optional[ImpersonationRegistryEditResponse], impersonation_registry, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize def test_method_edit_with_all_params(self, client: Cloudflare) -> None: impersonation_registry = client.email_security.settings.impersonation_registry.edit( - display_name_id=2403, - account_id="023e105f4ecef8ad9ca31a8372d0c353", - email="email", - is_email_regex=True, - name="name", + impersonation_registry_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + comments="comments", + directory_id=0, + directory_node_id=0, + email="john.doe@example.com", + external_directory_node_id="external_directory_node_id", + is_email_regex=False, + name="John Doe", + provenance="A1S_INTERNAL", ) - assert_matches_type(ImpersonationRegistryEditResponse, impersonation_registry, path=["response"]) + assert_matches_type(Optional[ImpersonationRegistryEditResponse], impersonation_registry, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize def test_raw_response_edit(self, client: Cloudflare) -> None: response = client.email_security.settings.impersonation_registry.with_raw_response.edit( - display_name_id=2403, + impersonation_registry_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" impersonation_registry = response.parse() - assert_matches_type(ImpersonationRegistryEditResponse, impersonation_registry, path=["response"]) + assert_matches_type(Optional[ImpersonationRegistryEditResponse], impersonation_registry, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize def test_streaming_response_edit(self, client: Cloudflare) -> None: with client.email_security.settings.impersonation_registry.with_streaming_response.edit( - display_name_id=2403, + impersonation_registry_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" impersonation_registry = response.parse() - assert_matches_type(ImpersonationRegistryEditResponse, impersonation_registry, path=["response"]) + assert_matches_type(Optional[ImpersonationRegistryEditResponse], impersonation_registry, path=["response"]) assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize def test_path_params_edit(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.email_security.settings.impersonation_registry.with_raw_response.edit( - display_name_id=2403, + impersonation_registry_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) + with pytest.raises( + ValueError, match=r"Expected a non-empty value for `impersonation_registry_id` but received ''" + ): + client.email_security.settings.impersonation_registry.with_raw_response.edit( + impersonation_registry_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + @parametrize def test_method_get(self, client: Cloudflare) -> None: impersonation_registry = client.email_security.settings.impersonation_registry.get( - display_name_id=2403, + impersonation_registry_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(ImpersonationRegistryGetResponse, impersonation_registry, path=["response"]) + assert_matches_type(Optional[ImpersonationRegistryGetResponse], impersonation_registry, path=["response"]) @parametrize def test_raw_response_get(self, client: Cloudflare) -> None: response = client.email_security.settings.impersonation_registry.with_raw_response.get( - display_name_id=2403, + impersonation_registry_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" impersonation_registry = response.parse() - assert_matches_type(ImpersonationRegistryGetResponse, impersonation_registry, path=["response"]) + assert_matches_type(Optional[ImpersonationRegistryGetResponse], impersonation_registry, path=["response"]) @parametrize def test_streaming_response_get(self, client: Cloudflare) -> None: with client.email_security.settings.impersonation_registry.with_streaming_response.get( - display_name_id=2403, + impersonation_registry_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" impersonation_registry = response.parse() - assert_matches_type(ImpersonationRegistryGetResponse, impersonation_registry, path=["response"]) + assert_matches_type(Optional[ImpersonationRegistryGetResponse], impersonation_registry, path=["response"]) assert cast(Any, response.is_closed) is True @@ -266,10 +311,18 @@ def test_streaming_response_get(self, client: Cloudflare) -> None: def test_path_params_get(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.email_security.settings.impersonation_registry.with_raw_response.get( - display_name_id=2403, + impersonation_registry_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) + with pytest.raises( + ValueError, match=r"Expected a non-empty value for `impersonation_registry_id` but received ''" + ): + client.email_security.settings.impersonation_registry.with_raw_response.get( + impersonation_registry_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + class TestAsyncImpersonationRegistry: parametrize = pytest.mark.parametrize( @@ -280,39 +333,56 @@ class TestAsyncImpersonationRegistry: async def test_method_create(self, async_client: AsyncCloudflare) -> None: impersonation_registry = await async_client.email_security.settings.impersonation_registry.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", - email="email", - is_email_regex=True, - name="name", + email="john.doe@example.com", + is_email_regex=False, + name="John Doe", ) - assert_matches_type(ImpersonationRegistryCreateResponse, impersonation_registry, path=["response"]) + assert_matches_type(Optional[ImpersonationRegistryCreateResponse], impersonation_registry, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: + impersonation_registry = await async_client.email_security.settings.impersonation_registry.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + email="john.doe@example.com", + is_email_regex=False, + name="John Doe", + comments="comments", + directory_id=0, + directory_node_id=0, + external_directory_node_id="external_directory_node_id", + provenance="A1S_INTERNAL", + ) + assert_matches_type(Optional[ImpersonationRegistryCreateResponse], impersonation_registry, path=["response"]) @parametrize async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: response = await async_client.email_security.settings.impersonation_registry.with_raw_response.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", - email="email", - is_email_regex=True, - name="name", + email="john.doe@example.com", + is_email_regex=False, + name="John Doe", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" impersonation_registry = await response.parse() - assert_matches_type(ImpersonationRegistryCreateResponse, impersonation_registry, path=["response"]) + assert_matches_type(Optional[ImpersonationRegistryCreateResponse], impersonation_registry, path=["response"]) @parametrize async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: async with async_client.email_security.settings.impersonation_registry.with_streaming_response.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", - email="email", - is_email_regex=True, - name="name", + email="john.doe@example.com", + is_email_regex=False, + name="John Doe", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" impersonation_registry = await response.parse() - assert_matches_type(ImpersonationRegistryCreateResponse, impersonation_registry, path=["response"]) + assert_matches_type( + Optional[ImpersonationRegistryCreateResponse], impersonation_registry, path=["response"] + ) assert cast(Any, response.is_closed) is True @@ -321,9 +391,9 @@ async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.email_security.settings.impersonation_registry.with_raw_response.create( account_id="", - email="email", - is_email_regex=True, - name="name", + email="john.doe@example.com", + is_email_regex=False, + name="John Doe", ) @parametrize @@ -342,7 +412,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) direction="asc", order="name", page=1, - per_page=1, + per_page=20, provenance="A1S_INTERNAL", search="search", ) @@ -388,34 +458,36 @@ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_method_delete(self, async_client: AsyncCloudflare) -> None: impersonation_registry = await async_client.email_security.settings.impersonation_registry.delete( - display_name_id=2403, + impersonation_registry_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(ImpersonationRegistryDeleteResponse, impersonation_registry, path=["response"]) + assert_matches_type(Optional[ImpersonationRegistryDeleteResponse], impersonation_registry, path=["response"]) @parametrize async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: response = await async_client.email_security.settings.impersonation_registry.with_raw_response.delete( - display_name_id=2403, + impersonation_registry_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" impersonation_registry = await response.parse() - assert_matches_type(ImpersonationRegistryDeleteResponse, impersonation_registry, path=["response"]) + assert_matches_type(Optional[ImpersonationRegistryDeleteResponse], impersonation_registry, path=["response"]) @parametrize async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: async with async_client.email_security.settings.impersonation_registry.with_streaming_response.delete( - display_name_id=2403, + impersonation_registry_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" impersonation_registry = await response.parse() - assert_matches_type(ImpersonationRegistryDeleteResponse, impersonation_registry, path=["response"]) + assert_matches_type( + Optional[ImpersonationRegistryDeleteResponse], impersonation_registry, path=["response"] + ) assert cast(Any, response.is_closed) is True @@ -423,94 +495,120 @@ async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.email_security.settings.impersonation_registry.with_raw_response.delete( - display_name_id=2403, + impersonation_registry_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) + with pytest.raises( + ValueError, match=r"Expected a non-empty value for `impersonation_registry_id` but received ''" + ): + await async_client.email_security.settings.impersonation_registry.with_raw_response.delete( + impersonation_registry_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize async def test_method_edit(self, async_client: AsyncCloudflare) -> None: impersonation_registry = await async_client.email_security.settings.impersonation_registry.edit( - display_name_id=2403, + impersonation_registry_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(ImpersonationRegistryEditResponse, impersonation_registry, path=["response"]) + assert_matches_type(Optional[ImpersonationRegistryEditResponse], impersonation_registry, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) -> None: impersonation_registry = await async_client.email_security.settings.impersonation_registry.edit( - display_name_id=2403, - account_id="023e105f4ecef8ad9ca31a8372d0c353", - email="email", - is_email_regex=True, - name="name", + impersonation_registry_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + comments="comments", + directory_id=0, + directory_node_id=0, + email="john.doe@example.com", + external_directory_node_id="external_directory_node_id", + is_email_regex=False, + name="John Doe", + provenance="A1S_INTERNAL", ) - assert_matches_type(ImpersonationRegistryEditResponse, impersonation_registry, path=["response"]) + assert_matches_type(Optional[ImpersonationRegistryEditResponse], impersonation_registry, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize async def test_raw_response_edit(self, async_client: AsyncCloudflare) -> None: response = await async_client.email_security.settings.impersonation_registry.with_raw_response.edit( - display_name_id=2403, + impersonation_registry_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" impersonation_registry = await response.parse() - assert_matches_type(ImpersonationRegistryEditResponse, impersonation_registry, path=["response"]) + assert_matches_type(Optional[ImpersonationRegistryEditResponse], impersonation_registry, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize async def test_streaming_response_edit(self, async_client: AsyncCloudflare) -> None: async with async_client.email_security.settings.impersonation_registry.with_streaming_response.edit( - display_name_id=2403, + impersonation_registry_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" impersonation_registry = await response.parse() - assert_matches_type(ImpersonationRegistryEditResponse, impersonation_registry, path=["response"]) + assert_matches_type(Optional[ImpersonationRegistryEditResponse], impersonation_registry, path=["response"]) assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize async def test_path_params_edit(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.email_security.settings.impersonation_registry.with_raw_response.edit( - display_name_id=2403, + impersonation_registry_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) + with pytest.raises( + ValueError, match=r"Expected a non-empty value for `impersonation_registry_id` but received ''" + ): + await async_client.email_security.settings.impersonation_registry.with_raw_response.edit( + impersonation_registry_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + @parametrize async def test_method_get(self, async_client: AsyncCloudflare) -> None: impersonation_registry = await async_client.email_security.settings.impersonation_registry.get( - display_name_id=2403, + impersonation_registry_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(ImpersonationRegistryGetResponse, impersonation_registry, path=["response"]) + assert_matches_type(Optional[ImpersonationRegistryGetResponse], impersonation_registry, path=["response"]) @parametrize async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: response = await async_client.email_security.settings.impersonation_registry.with_raw_response.get( - display_name_id=2403, + impersonation_registry_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" impersonation_registry = await response.parse() - assert_matches_type(ImpersonationRegistryGetResponse, impersonation_registry, path=["response"]) + assert_matches_type(Optional[ImpersonationRegistryGetResponse], impersonation_registry, path=["response"]) @parametrize async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: async with async_client.email_security.settings.impersonation_registry.with_streaming_response.get( - display_name_id=2403, + impersonation_registry_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" impersonation_registry = await response.parse() - assert_matches_type(ImpersonationRegistryGetResponse, impersonation_registry, path=["response"]) + assert_matches_type(Optional[ImpersonationRegistryGetResponse], impersonation_registry, path=["response"]) assert cast(Any, response.is_closed) is True @@ -518,6 +616,14 @@ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> No async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.email_security.settings.impersonation_registry.with_raw_response.get( - display_name_id=2403, + impersonation_registry_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) + + with pytest.raises( + ValueError, match=r"Expected a non-empty value for `impersonation_registry_id` but received ''" + ): + await async_client.email_security.settings.impersonation_registry.with_raw_response.get( + impersonation_registry_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) diff --git a/tests/api_resources/email_security/settings/test_trusted_domains.py b/tests/api_resources/email_security/settings/test_trusted_domains.py index 57aa6fcd50d..c7bc53875a7 100644 --- a/tests/api_resources/email_security/settings/test_trusted_domains.py +++ b/tests/api_resources/email_security/settings/test_trusted_domains.py @@ -3,7 +3,7 @@ from __future__ import annotations import os -from typing import Any, cast +from typing import Any, Optional, cast import pytest @@ -26,7 +26,7 @@ class TestTrustedDomains: @pytest.mark.skip(reason="TODO: investigate HTTP 422 errors on test suite") @parametrize - def test_method_create_overload_1(self, client: Cloudflare) -> None: + def test_method_create(self, client: Cloudflare) -> None: trusted_domain = client.email_security.settings.trusted_domains.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", is_recent=True, @@ -34,24 +34,24 @@ def test_method_create_overload_1(self, client: Cloudflare) -> None: is_similarity=False, pattern="example.com", ) - assert_matches_type(TrustedDomainCreateResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainCreateResponse], trusted_domain, path=["response"]) @pytest.mark.skip(reason="TODO: investigate HTTP 422 errors on test suite") @parametrize - def test_method_create_with_all_params_overload_1(self, client: Cloudflare) -> None: + def test_method_create_with_all_params(self, client: Cloudflare) -> None: trusted_domain = client.email_security.settings.trusted_domains.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", is_recent=True, is_regex=False, is_similarity=False, pattern="example.com", - comments=None, + comments="Trusted partner domain", ) - assert_matches_type(TrustedDomainCreateResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainCreateResponse], trusted_domain, path=["response"]) @pytest.mark.skip(reason="TODO: investigate HTTP 422 errors on test suite") @parametrize - def test_raw_response_create_overload_1(self, client: Cloudflare) -> None: + def test_raw_response_create(self, client: Cloudflare) -> None: response = client.email_security.settings.trusted_domains.with_raw_response.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", is_recent=True, @@ -63,11 +63,11 @@ def test_raw_response_create_overload_1(self, client: Cloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" trusted_domain = response.parse() - assert_matches_type(TrustedDomainCreateResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainCreateResponse], trusted_domain, path=["response"]) @pytest.mark.skip(reason="TODO: investigate HTTP 422 errors on test suite") @parametrize - def test_streaming_response_create_overload_1(self, client: Cloudflare) -> None: + def test_streaming_response_create(self, client: Cloudflare) -> None: with client.email_security.settings.trusted_domains.with_streaming_response.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", is_recent=True, @@ -79,13 +79,13 @@ def test_streaming_response_create_overload_1(self, client: Cloudflare) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" trusted_domain = response.parse() - assert_matches_type(TrustedDomainCreateResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainCreateResponse], trusted_domain, path=["response"]) assert cast(Any, response.is_closed) is True @pytest.mark.skip(reason="TODO: investigate HTTP 422 errors on test suite") @parametrize - def test_path_params_create_overload_1(self, client: Cloudflare) -> None: + def test_path_params_create(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.email_security.settings.trusted_domains.with_raw_response.create( account_id="", @@ -95,80 +95,6 @@ def test_path_params_create_overload_1(self, client: Cloudflare) -> None: pattern="example.com", ) - @pytest.mark.skip(reason="TODO: investigate HTTP 422 errors on test suite") - @parametrize - def test_method_create_overload_2(self, client: Cloudflare) -> None: - trusted_domain = client.email_security.settings.trusted_domains.create( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - body=[ - { - "is_recent": True, - "is_regex": False, - "is_similarity": False, - "pattern": "example.com", - } - ], - ) - assert_matches_type(TrustedDomainCreateResponse, trusted_domain, path=["response"]) - - @pytest.mark.skip(reason="TODO: investigate HTTP 422 errors on test suite") - @parametrize - def test_raw_response_create_overload_2(self, client: Cloudflare) -> None: - response = client.email_security.settings.trusted_domains.with_raw_response.create( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - body=[ - { - "is_recent": True, - "is_regex": False, - "is_similarity": False, - "pattern": "example.com", - } - ], - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - trusted_domain = response.parse() - assert_matches_type(TrustedDomainCreateResponse, trusted_domain, path=["response"]) - - @pytest.mark.skip(reason="TODO: investigate HTTP 422 errors on test suite") - @parametrize - def test_streaming_response_create_overload_2(self, client: Cloudflare) -> None: - with client.email_security.settings.trusted_domains.with_streaming_response.create( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - body=[ - { - "is_recent": True, - "is_regex": False, - "is_similarity": False, - "pattern": "example.com", - } - ], - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - trusted_domain = response.parse() - assert_matches_type(TrustedDomainCreateResponse, trusted_domain, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="TODO: investigate HTTP 422 errors on test suite") - @parametrize - def test_path_params_create_overload_2(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.email_security.settings.trusted_domains.with_raw_response.create( - account_id="", - body=[ - { - "is_recent": True, - "is_regex": False, - "is_similarity": False, - "pattern": "example.com", - } - ], - ) - @parametrize def test_method_list(self, client: Cloudflare) -> None: trusted_domain = client.email_security.settings.trusted_domains.list( @@ -186,7 +112,7 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: order="pattern", page=1, pattern="pattern", - per_page=1, + per_page=20, search="search", ) assert_matches_type(SyncV4PagePaginationArray[TrustedDomainListResponse], trusted_domain, path=["response"]) @@ -225,34 +151,34 @@ def test_path_params_list(self, client: Cloudflare) -> None: @parametrize def test_method_delete(self, client: Cloudflare) -> None: trusted_domain = client.email_security.settings.trusted_domains.delete( - trusted_domain_id=2401, + trusted_domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(TrustedDomainDeleteResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainDeleteResponse], trusted_domain, path=["response"]) @parametrize def test_raw_response_delete(self, client: Cloudflare) -> None: response = client.email_security.settings.trusted_domains.with_raw_response.delete( - trusted_domain_id=2401, + trusted_domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" trusted_domain = response.parse() - assert_matches_type(TrustedDomainDeleteResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainDeleteResponse], trusted_domain, path=["response"]) @parametrize def test_streaming_response_delete(self, client: Cloudflare) -> None: with client.email_security.settings.trusted_domains.with_streaming_response.delete( - trusted_domain_id=2401, + trusted_domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" trusted_domain = response.parse() - assert_matches_type(TrustedDomainDeleteResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainDeleteResponse], trusted_domain, path=["response"]) assert cast(Any, response.is_closed) is True @@ -260,96 +186,113 @@ def test_streaming_response_delete(self, client: Cloudflare) -> None: def test_path_params_delete(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.email_security.settings.trusted_domains.with_raw_response.delete( - trusted_domain_id=2401, + trusted_domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) + with pytest.raises(ValueError, match=r"Expected a non-empty value for `trusted_domain_id` but received ''"): + client.email_security.settings.trusted_domains.with_raw_response.delete( + trusted_domain_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize def test_method_edit(self, client: Cloudflare) -> None: trusted_domain = client.email_security.settings.trusted_domains.edit( - trusted_domain_id=2401, + trusted_domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(TrustedDomainEditResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainEditResponse], trusted_domain, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize def test_method_edit_with_all_params(self, client: Cloudflare) -> None: trusted_domain = client.email_security.settings.trusted_domains.edit( - trusted_domain_id=2401, + trusted_domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", - comments="comments", + comments="Trusted partner domain", is_recent=True, - is_regex=True, - is_similarity=True, - pattern="x", + is_regex=False, + is_similarity=False, + pattern="example.com", ) - assert_matches_type(TrustedDomainEditResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainEditResponse], trusted_domain, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize def test_raw_response_edit(self, client: Cloudflare) -> None: response = client.email_security.settings.trusted_domains.with_raw_response.edit( - trusted_domain_id=2401, + trusted_domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" trusted_domain = response.parse() - assert_matches_type(TrustedDomainEditResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainEditResponse], trusted_domain, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize def test_streaming_response_edit(self, client: Cloudflare) -> None: with client.email_security.settings.trusted_domains.with_streaming_response.edit( - trusted_domain_id=2401, + trusted_domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" trusted_domain = response.parse() - assert_matches_type(TrustedDomainEditResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainEditResponse], trusted_domain, path=["response"]) assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize def test_path_params_edit(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.email_security.settings.trusted_domains.with_raw_response.edit( - trusted_domain_id=2401, + trusted_domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) + with pytest.raises(ValueError, match=r"Expected a non-empty value for `trusted_domain_id` but received ''"): + client.email_security.settings.trusted_domains.with_raw_response.edit( + trusted_domain_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + @parametrize def test_method_get(self, client: Cloudflare) -> None: trusted_domain = client.email_security.settings.trusted_domains.get( - trusted_domain_id=2401, + trusted_domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(TrustedDomainGetResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainGetResponse], trusted_domain, path=["response"]) @parametrize def test_raw_response_get(self, client: Cloudflare) -> None: response = client.email_security.settings.trusted_domains.with_raw_response.get( - trusted_domain_id=2401, + trusted_domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" trusted_domain = response.parse() - assert_matches_type(TrustedDomainGetResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainGetResponse], trusted_domain, path=["response"]) @parametrize def test_streaming_response_get(self, client: Cloudflare) -> None: with client.email_security.settings.trusted_domains.with_streaming_response.get( - trusted_domain_id=2401, + trusted_domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" trusted_domain = response.parse() - assert_matches_type(TrustedDomainGetResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainGetResponse], trusted_domain, path=["response"]) assert cast(Any, response.is_closed) is True @@ -357,10 +300,16 @@ def test_streaming_response_get(self, client: Cloudflare) -> None: def test_path_params_get(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.email_security.settings.trusted_domains.with_raw_response.get( - trusted_domain_id=2401, + trusted_domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) + with pytest.raises(ValueError, match=r"Expected a non-empty value for `trusted_domain_id` but received ''"): + client.email_security.settings.trusted_domains.with_raw_response.get( + trusted_domain_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + class TestAsyncTrustedDomains: parametrize = pytest.mark.parametrize( @@ -369,7 +318,7 @@ class TestAsyncTrustedDomains: @pytest.mark.skip(reason="TODO: investigate HTTP 422 errors on test suite") @parametrize - async def test_method_create_overload_1(self, async_client: AsyncCloudflare) -> None: + async def test_method_create(self, async_client: AsyncCloudflare) -> None: trusted_domain = await async_client.email_security.settings.trusted_domains.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", is_recent=True, @@ -377,24 +326,24 @@ async def test_method_create_overload_1(self, async_client: AsyncCloudflare) -> is_similarity=False, pattern="example.com", ) - assert_matches_type(TrustedDomainCreateResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainCreateResponse], trusted_domain, path=["response"]) @pytest.mark.skip(reason="TODO: investigate HTTP 422 errors on test suite") @parametrize - async def test_method_create_with_all_params_overload_1(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: trusted_domain = await async_client.email_security.settings.trusted_domains.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", is_recent=True, is_regex=False, is_similarity=False, pattern="example.com", - comments=None, + comments="Trusted partner domain", ) - assert_matches_type(TrustedDomainCreateResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainCreateResponse], trusted_domain, path=["response"]) @pytest.mark.skip(reason="TODO: investigate HTTP 422 errors on test suite") @parametrize - async def test_raw_response_create_overload_1(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: response = await async_client.email_security.settings.trusted_domains.with_raw_response.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", is_recent=True, @@ -406,11 +355,11 @@ async def test_raw_response_create_overload_1(self, async_client: AsyncCloudflar assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" trusted_domain = await response.parse() - assert_matches_type(TrustedDomainCreateResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainCreateResponse], trusted_domain, path=["response"]) @pytest.mark.skip(reason="TODO: investigate HTTP 422 errors on test suite") @parametrize - async def test_streaming_response_create_overload_1(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: async with async_client.email_security.settings.trusted_domains.with_streaming_response.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", is_recent=True, @@ -422,13 +371,13 @@ async def test_streaming_response_create_overload_1(self, async_client: AsyncClo assert response.http_request.headers.get("X-Stainless-Lang") == "python" trusted_domain = await response.parse() - assert_matches_type(TrustedDomainCreateResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainCreateResponse], trusted_domain, path=["response"]) assert cast(Any, response.is_closed) is True @pytest.mark.skip(reason="TODO: investigate HTTP 422 errors on test suite") @parametrize - async def test_path_params_create_overload_1(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.email_security.settings.trusted_domains.with_raw_response.create( account_id="", @@ -438,80 +387,6 @@ async def test_path_params_create_overload_1(self, async_client: AsyncCloudflare pattern="example.com", ) - @pytest.mark.skip(reason="TODO: investigate HTTP 422 errors on test suite") - @parametrize - async def test_method_create_overload_2(self, async_client: AsyncCloudflare) -> None: - trusted_domain = await async_client.email_security.settings.trusted_domains.create( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - body=[ - { - "is_recent": True, - "is_regex": False, - "is_similarity": False, - "pattern": "example.com", - } - ], - ) - assert_matches_type(TrustedDomainCreateResponse, trusted_domain, path=["response"]) - - @pytest.mark.skip(reason="TODO: investigate HTTP 422 errors on test suite") - @parametrize - async def test_raw_response_create_overload_2(self, async_client: AsyncCloudflare) -> None: - response = await async_client.email_security.settings.trusted_domains.with_raw_response.create( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - body=[ - { - "is_recent": True, - "is_regex": False, - "is_similarity": False, - "pattern": "example.com", - } - ], - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - trusted_domain = await response.parse() - assert_matches_type(TrustedDomainCreateResponse, trusted_domain, path=["response"]) - - @pytest.mark.skip(reason="TODO: investigate HTTP 422 errors on test suite") - @parametrize - async def test_streaming_response_create_overload_2(self, async_client: AsyncCloudflare) -> None: - async with async_client.email_security.settings.trusted_domains.with_streaming_response.create( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - body=[ - { - "is_recent": True, - "is_regex": False, - "is_similarity": False, - "pattern": "example.com", - } - ], - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - trusted_domain = await response.parse() - assert_matches_type(TrustedDomainCreateResponse, trusted_domain, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="TODO: investigate HTTP 422 errors on test suite") - @parametrize - async def test_path_params_create_overload_2(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.email_security.settings.trusted_domains.with_raw_response.create( - account_id="", - body=[ - { - "is_recent": True, - "is_regex": False, - "is_similarity": False, - "pattern": "example.com", - } - ], - ) - @parametrize async def test_method_list(self, async_client: AsyncCloudflare) -> None: trusted_domain = await async_client.email_security.settings.trusted_domains.list( @@ -529,7 +404,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) order="pattern", page=1, pattern="pattern", - per_page=1, + per_page=20, search="search", ) assert_matches_type(AsyncV4PagePaginationArray[TrustedDomainListResponse], trusted_domain, path=["response"]) @@ -570,34 +445,34 @@ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_method_delete(self, async_client: AsyncCloudflare) -> None: trusted_domain = await async_client.email_security.settings.trusted_domains.delete( - trusted_domain_id=2401, + trusted_domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(TrustedDomainDeleteResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainDeleteResponse], trusted_domain, path=["response"]) @parametrize async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: response = await async_client.email_security.settings.trusted_domains.with_raw_response.delete( - trusted_domain_id=2401, + trusted_domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" trusted_domain = await response.parse() - assert_matches_type(TrustedDomainDeleteResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainDeleteResponse], trusted_domain, path=["response"]) @parametrize async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: async with async_client.email_security.settings.trusted_domains.with_streaming_response.delete( - trusted_domain_id=2401, + trusted_domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" trusted_domain = await response.parse() - assert_matches_type(TrustedDomainDeleteResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainDeleteResponse], trusted_domain, path=["response"]) assert cast(Any, response.is_closed) is True @@ -605,96 +480,113 @@ async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.email_security.settings.trusted_domains.with_raw_response.delete( - trusted_domain_id=2401, + trusted_domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) + with pytest.raises(ValueError, match=r"Expected a non-empty value for `trusted_domain_id` but received ''"): + await async_client.email_security.settings.trusted_domains.with_raw_response.delete( + trusted_domain_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize async def test_method_edit(self, async_client: AsyncCloudflare) -> None: trusted_domain = await async_client.email_security.settings.trusted_domains.edit( - trusted_domain_id=2401, + trusted_domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(TrustedDomainEditResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainEditResponse], trusted_domain, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) -> None: trusted_domain = await async_client.email_security.settings.trusted_domains.edit( - trusted_domain_id=2401, + trusted_domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", - comments="comments", + comments="Trusted partner domain", is_recent=True, - is_regex=True, - is_similarity=True, - pattern="x", + is_regex=False, + is_similarity=False, + pattern="example.com", ) - assert_matches_type(TrustedDomainEditResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainEditResponse], trusted_domain, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize async def test_raw_response_edit(self, async_client: AsyncCloudflare) -> None: response = await async_client.email_security.settings.trusted_domains.with_raw_response.edit( - trusted_domain_id=2401, + trusted_domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" trusted_domain = await response.parse() - assert_matches_type(TrustedDomainEditResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainEditResponse], trusted_domain, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize async def test_streaming_response_edit(self, async_client: AsyncCloudflare) -> None: async with async_client.email_security.settings.trusted_domains.with_streaming_response.edit( - trusted_domain_id=2401, + trusted_domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" trusted_domain = await response.parse() - assert_matches_type(TrustedDomainEditResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainEditResponse], trusted_domain, path=["response"]) assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize async def test_path_params_edit(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.email_security.settings.trusted_domains.with_raw_response.edit( - trusted_domain_id=2401, + trusted_domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) + with pytest.raises(ValueError, match=r"Expected a non-empty value for `trusted_domain_id` but received ''"): + await async_client.email_security.settings.trusted_domains.with_raw_response.edit( + trusted_domain_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + @parametrize async def test_method_get(self, async_client: AsyncCloudflare) -> None: trusted_domain = await async_client.email_security.settings.trusted_domains.get( - trusted_domain_id=2401, + trusted_domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(TrustedDomainGetResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainGetResponse], trusted_domain, path=["response"]) @parametrize async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: response = await async_client.email_security.settings.trusted_domains.with_raw_response.get( - trusted_domain_id=2401, + trusted_domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" trusted_domain = await response.parse() - assert_matches_type(TrustedDomainGetResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainGetResponse], trusted_domain, path=["response"]) @parametrize async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: async with async_client.email_security.settings.trusted_domains.with_streaming_response.get( - trusted_domain_id=2401, + trusted_domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" trusted_domain = await response.parse() - assert_matches_type(TrustedDomainGetResponse, trusted_domain, path=["response"]) + assert_matches_type(Optional[TrustedDomainGetResponse], trusted_domain, path=["response"]) assert cast(Any, response.is_closed) is True @@ -702,6 +594,12 @@ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> No async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.email_security.settings.trusted_domains.with_raw_response.get( - trusted_domain_id=2401, + trusted_domain_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `trusted_domain_id` but received ''"): + await async_client.email_security.settings.trusted_domains.with_raw_response.get( + trusted_domain_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) diff --git a/tests/api_resources/email_security/test_investigate.py b/tests/api_resources/email_security/test_investigate.py index 0d74e6ae1d8..82f56549196 100644 --- a/tests/api_resources/email_security/test_investigate.py +++ b/tests/api_resources/email_security/test_investigate.py @@ -39,19 +39,17 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: detections_only=True, domain="domain", end=parse_datetime("2019-12-27T18:11:19.117Z"), - exact_subject="exact_subject", final_disposition="MALICIOUS", message_action="PREVIEW", message_id="message_id", metric="metric", page=1, - per_page=1, + per_page=20, query="query", recipient="recipient", sender="sender", start=parse_datetime("2019-12-27T18:11:19.117Z"), subject="subject", - submissions=True, ) assert_matches_type(SyncV4PagePaginationArray[InvestigateListResponse], investigate, path=["response"]) @@ -89,7 +87,7 @@ def test_path_params_list(self, client: Cloudflare) -> None: @parametrize def test_method_get(self, client: Cloudflare) -> None: investigate = client.email_security.investigate.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert_matches_type(InvestigateGetResponse, investigate, path=["response"]) @@ -97,7 +95,7 @@ def test_method_get(self, client: Cloudflare) -> None: @parametrize def test_method_get_with_all_params(self, client: Cloudflare) -> None: investigate = client.email_security.investigate.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", submission=True, ) @@ -106,7 +104,7 @@ def test_method_get_with_all_params(self, client: Cloudflare) -> None: @parametrize def test_raw_response_get(self, client: Cloudflare) -> None: response = client.email_security.investigate.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) @@ -118,7 +116,7 @@ def test_raw_response_get(self, client: Cloudflare) -> None: @parametrize def test_streaming_response_get(self, client: Cloudflare) -> None: with client.email_security.investigate.with_streaming_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed @@ -133,13 +131,13 @@ def test_streaming_response_get(self, client: Cloudflare) -> None: def test_path_params_get(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.email_security.investigate.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `investigate_id` but received ''"): client.email_security.investigate.with_raw_response.get( - postfix_id="", + investigate_id="", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) @@ -166,19 +164,17 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) detections_only=True, domain="domain", end=parse_datetime("2019-12-27T18:11:19.117Z"), - exact_subject="exact_subject", final_disposition="MALICIOUS", message_action="PREVIEW", message_id="message_id", metric="metric", page=1, - per_page=1, + per_page=20, query="query", recipient="recipient", sender="sender", start=parse_datetime("2019-12-27T18:11:19.117Z"), subject="subject", - submissions=True, ) assert_matches_type(AsyncV4PagePaginationArray[InvestigateListResponse], investigate, path=["response"]) @@ -216,7 +212,7 @@ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_method_get(self, async_client: AsyncCloudflare) -> None: investigate = await async_client.email_security.investigate.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert_matches_type(InvestigateGetResponse, investigate, path=["response"]) @@ -224,7 +220,7 @@ async def test_method_get(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_method_get_with_all_params(self, async_client: AsyncCloudflare) -> None: investigate = await async_client.email_security.investigate.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", submission=True, ) @@ -233,7 +229,7 @@ async def test_method_get_with_all_params(self, async_client: AsyncCloudflare) - @parametrize async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: response = await async_client.email_security.investigate.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) @@ -245,7 +241,7 @@ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: async with async_client.email_security.investigate.with_streaming_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) as response: assert not response.is_closed @@ -260,12 +256,12 @@ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> No async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.email_security.investigate.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", account_id="", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `investigate_id` but received ''"): await async_client.email_security.investigate.with_raw_response.get( - postfix_id="", + investigate_id="", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) diff --git a/tests/api_resources/email_security/test_submissions.py b/tests/api_resources/email_security/test_submissions.py index 5c6e59faee4..a3ccfcd375d 100644 --- a/tests/api_resources/email_security/test_submissions.py +++ b/tests/api_resources/email_security/test_submissions.py @@ -30,12 +30,11 @@ def test_method_list(self, client: Cloudflare) -> None: def test_method_list_with_all_params(self, client: Cloudflare) -> None: submission = client.email_security.submissions.list( account_id="023e105f4ecef8ad9ca31a8372d0c353", - customer_status="escalated", end=parse_datetime("2019-12-27T18:11:19.117Z"), original_disposition="MALICIOUS", outcome_disposition="MALICIOUS", page=1, - per_page=1, + per_page=20, query="query", requested_disposition="MALICIOUS", start=parse_datetime("2019-12-27T18:11:19.117Z"), @@ -93,12 +92,11 @@ async def test_method_list(self, async_client: AsyncCloudflare) -> None: async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: submission = await async_client.email_security.submissions.list( account_id="023e105f4ecef8ad9ca31a8372d0c353", - customer_status="escalated", end=parse_datetime("2019-12-27T18:11:19.117Z"), original_disposition="MALICIOUS", outcome_disposition="MALICIOUS", page=1, - per_page=1, + per_page=20, query="query", requested_disposition="MALICIOUS", start=parse_datetime("2019-12-27T18:11:19.117Z"), diff --git a/tests/api_resources/magic_transit/sites/test_lans.py b/tests/api_resources/magic_transit/sites/test_lans.py index b5b9d2a9bc3..89140a8b749 100644 --- a/tests/api_resources/magic_transit/sites/test_lans.py +++ b/tests/api_resources/magic_transit/sites/test_lans.py @@ -51,6 +51,13 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: "address": "192.0.2.0/24", "dhcp_relay": {"server_addresses": ["192.0.2.1"]}, "dhcp_server": { + "dhcp_options": [ + { + "code": 66, + "type": "ip", + "value": "10.20.30.40", + } + ], "dhcp_pool_end": "192.0.2.1", "dhcp_pool_start": "192.0.2.1", "dns_server": "192.0.2.1", @@ -139,6 +146,13 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: "address": "192.0.2.0/24", "dhcp_relay": {"server_addresses": ["192.0.2.1"]}, "dhcp_server": { + "dhcp_options": [ + { + "code": 66, + "type": "ip", + "value": "10.20.30.40", + } + ], "dhcp_pool_end": "192.0.2.1", "dhcp_pool_start": "192.0.2.1", "dns_server": "192.0.2.1", @@ -346,6 +360,13 @@ def test_method_edit_with_all_params(self, client: Cloudflare) -> None: "address": "192.0.2.0/24", "dhcp_relay": {"server_addresses": ["192.0.2.1"]}, "dhcp_server": { + "dhcp_options": [ + { + "code": 66, + "type": "ip", + "value": "10.20.30.40", + } + ], "dhcp_pool_end": "192.0.2.1", "dhcp_pool_start": "192.0.2.1", "dns_server": "192.0.2.1", @@ -510,6 +531,13 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare "address": "192.0.2.0/24", "dhcp_relay": {"server_addresses": ["192.0.2.1"]}, "dhcp_server": { + "dhcp_options": [ + { + "code": 66, + "type": "ip", + "value": "10.20.30.40", + } + ], "dhcp_pool_end": "192.0.2.1", "dhcp_pool_start": "192.0.2.1", "dns_server": "192.0.2.1", @@ -598,6 +626,13 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare "address": "192.0.2.0/24", "dhcp_relay": {"server_addresses": ["192.0.2.1"]}, "dhcp_server": { + "dhcp_options": [ + { + "code": 66, + "type": "ip", + "value": "10.20.30.40", + } + ], "dhcp_pool_end": "192.0.2.1", "dhcp_pool_start": "192.0.2.1", "dns_server": "192.0.2.1", @@ -805,6 +840,13 @@ async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) "address": "192.0.2.0/24", "dhcp_relay": {"server_addresses": ["192.0.2.1"]}, "dhcp_server": { + "dhcp_options": [ + { + "code": 66, + "type": "ip", + "value": "10.20.30.40", + } + ], "dhcp_pool_end": "192.0.2.1", "dhcp_pool_start": "192.0.2.1", "dns_server": "192.0.2.1", diff --git a/tests/api_resources/magic_transit/test_connectors.py b/tests/api_resources/magic_transit/test_connectors.py index 17cf666175a..640220cc89b 100644 --- a/tests/api_resources/magic_transit/test_connectors.py +++ b/tests/api_resources/magic_transit/test_connectors.py @@ -172,6 +172,14 @@ def test_method_list(self, client: Cloudflare) -> None: ) assert_matches_type(SyncSinglePage[ConnectorListResponse], connector, path=["response"]) + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + connector = client.magic_transit.connectors.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + device_type="MANAGED", + ) + assert_matches_type(SyncSinglePage[ConnectorListResponse], connector, path=["response"]) + @parametrize def test_raw_response_list(self, client: Cloudflare) -> None: response = client.magic_transit.connectors.with_raw_response.list( @@ -516,6 +524,14 @@ async def test_method_list(self, async_client: AsyncCloudflare) -> None: ) assert_matches_type(AsyncSinglePage[ConnectorListResponse], connector, path=["response"]) + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + connector = await async_client.magic_transit.connectors.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + device_type="MANAGED", + ) + assert_matches_type(AsyncSinglePage[ConnectorListResponse], connector, path=["response"]) + @parametrize async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: response = await async_client.magic_transit.connectors.with_raw_response.list( diff --git a/tests/api_resources/test_fraud.py b/tests/api_resources/test_fraud.py index 91984bef14c..bd27a068ef6 100644 --- a/tests/api_resources/test_fraud.py +++ b/tests/api_resources/test_fraud.py @@ -17,6 +17,7 @@ class TestFraud: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize def test_method_update(self, client: Cloudflare) -> None: fraud = client.fraud.update( @@ -24,15 +25,27 @@ def test_method_update(self, client: Cloudflare) -> None: ) assert_matches_type(Optional[FraudSettings], fraud, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize def test_method_update_with_all_params(self, client: Cloudflare) -> None: fraud = client.fraud.update( zone_id="023e105f4ecef8ad9ca31a8372d0c353", + authentication_settings={ + "failure_criteria": { + "kind": "status_code", + "status_codes": [200, 201], + }, + "success_criteria": { + "kind": "status_code", + "status_codes": [200, 201], + }, + }, user_profiles="disabled", username_expressions=["string"], ) assert_matches_type(Optional[FraudSettings], fraud, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize def test_raw_response_update(self, client: Cloudflare) -> None: response = client.fraud.with_raw_response.update( @@ -44,6 +57,7 @@ def test_raw_response_update(self, client: Cloudflare) -> None: fraud = response.parse() assert_matches_type(Optional[FraudSettings], fraud, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize def test_streaming_response_update(self, client: Cloudflare) -> None: with client.fraud.with_streaming_response.update( @@ -57,6 +71,7 @@ def test_streaming_response_update(self, client: Cloudflare) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize def test_path_params_update(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): @@ -108,6 +123,7 @@ class TestAsyncFraud: "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] ) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize async def test_method_update(self, async_client: AsyncCloudflare) -> None: fraud = await async_client.fraud.update( @@ -115,15 +131,27 @@ async def test_method_update(self, async_client: AsyncCloudflare) -> None: ) assert_matches_type(Optional[FraudSettings], fraud, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: fraud = await async_client.fraud.update( zone_id="023e105f4ecef8ad9ca31a8372d0c353", + authentication_settings={ + "failure_criteria": { + "kind": "status_code", + "status_codes": [200, 201], + }, + "success_criteria": { + "kind": "status_code", + "status_codes": [200, 201], + }, + }, user_profiles="disabled", username_expressions=["string"], ) assert_matches_type(Optional[FraudSettings], fraud, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: response = await async_client.fraud.with_raw_response.update( @@ -135,6 +163,7 @@ async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: fraud = await response.parse() assert_matches_type(Optional[FraudSettings], fraud, path=["response"]) + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: async with async_client.fraud.with_streaming_response.update( @@ -148,6 +177,7 @@ async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="HTTP 422 error from prism") @parametrize async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): diff --git a/tests/api_resources/test_queues.py b/tests/api_resources/test_queues.py index e337e5aae5c..d2806191967 100644 --- a/tests/api_resources/test_queues.py +++ b/tests/api_resources/test_queues.py @@ -13,6 +13,7 @@ from cloudflare.types.queues import ( Queue, QueueDeleteResponse, + QueueGetMetricsResponse, ) base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -321,6 +322,54 @@ def test_path_params_get(self, client: Cloudflare) -> None: account_id="023e105f4ecef8ad9ca31a8372d0c353", ) + @parametrize + def test_method_get_metrics(self, client: Cloudflare) -> None: + queue = client.queues.get_metrics( + queue_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[QueueGetMetricsResponse], queue, path=["response"]) + + @parametrize + def test_raw_response_get_metrics(self, client: Cloudflare) -> None: + response = client.queues.with_raw_response.get_metrics( + queue_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + queue = response.parse() + assert_matches_type(Optional[QueueGetMetricsResponse], queue, path=["response"]) + + @parametrize + def test_streaming_response_get_metrics(self, client: Cloudflare) -> None: + with client.queues.with_streaming_response.get_metrics( + queue_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + queue = response.parse() + assert_matches_type(Optional[QueueGetMetricsResponse], queue, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get_metrics(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.queues.with_raw_response.get_metrics( + queue_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `queue_id` but received ''"): + client.queues.with_raw_response.get_metrics( + queue_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + class TestAsyncQueues: parametrize = pytest.mark.parametrize( @@ -626,3 +675,51 @@ async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: queue_id="", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) + + @parametrize + async def test_method_get_metrics(self, async_client: AsyncCloudflare) -> None: + queue = await async_client.queues.get_metrics( + queue_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[QueueGetMetricsResponse], queue, path=["response"]) + + @parametrize + async def test_raw_response_get_metrics(self, async_client: AsyncCloudflare) -> None: + response = await async_client.queues.with_raw_response.get_metrics( + queue_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + queue = await response.parse() + assert_matches_type(Optional[QueueGetMetricsResponse], queue, path=["response"]) + + @parametrize + async def test_streaming_response_get_metrics(self, async_client: AsyncCloudflare) -> None: + async with async_client.queues.with_streaming_response.get_metrics( + queue_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + queue = await response.parse() + assert_matches_type(Optional[QueueGetMetricsResponse], queue, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get_metrics(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.queues.with_raw_response.get_metrics( + queue_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `queue_id` but received ''"): + await async_client.queues.with_raw_response.get_metrics( + queue_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) diff --git a/tests/api_resources/test_zones.py b/tests/api_resources/test_zones.py index 0ee90986d59..60b348fbaea 100644 --- a/tests/api_resources/test_zones.py +++ b/tests/api_resources/test_zones.py @@ -83,6 +83,7 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: page=1, per_page=5, status="initializing", + type=["full"], ) assert_matches_type(SyncV4PagePaginationArray[Zone], zone, path=["response"]) @@ -302,6 +303,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) page=1, per_page=5, status="initializing", + type=["full"], ) assert_matches_type(AsyncV4PagePaginationArray[Zone], zone, path=["response"]) diff --git a/tests/api_resources/workers/beta/test_workers.py b/tests/api_resources/workers/beta/test_workers.py index 101ed4f8cae..64ee91aac7e 100644 --- a/tests/api_resources/workers/beta/test_workers.py +++ b/tests/api_resources/workers/beta/test_workers.py @@ -21,6 +21,7 @@ class TestWorkers: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize def test_method_create(self, client: Cloudflare) -> None: worker = client.workers.beta.workers.create( @@ -29,6 +30,7 @@ def test_method_create(self, client: Cloudflare) -> None: ) assert_matches_type(Worker, worker, path=["response"]) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize def test_method_create_with_all_params(self, client: Cloudflare) -> None: worker = client.workers.beta.workers.create( @@ -61,6 +63,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: ) assert_matches_type(Worker, worker, path=["response"]) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize def test_raw_response_create(self, client: Cloudflare) -> None: response = client.workers.beta.workers.with_raw_response.create( @@ -73,6 +76,7 @@ def test_raw_response_create(self, client: Cloudflare) -> None: worker = response.parse() assert_matches_type(Worker, worker, path=["response"]) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize def test_streaming_response_create(self, client: Cloudflare) -> None: with client.workers.beta.workers.with_streaming_response.create( @@ -87,6 +91,7 @@ def test_streaming_response_create(self, client: Cloudflare) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize def test_path_params_create(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): @@ -95,6 +100,7 @@ def test_path_params_create(self, client: Cloudflare) -> None: name="my-worker", ) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize def test_method_update(self, client: Cloudflare) -> None: worker = client.workers.beta.workers.update( @@ -104,6 +110,7 @@ def test_method_update(self, client: Cloudflare) -> None: ) assert_matches_type(Worker, worker, path=["response"]) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize def test_method_update_with_all_params(self, client: Cloudflare) -> None: worker = client.workers.beta.workers.update( @@ -137,6 +144,7 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: ) assert_matches_type(Worker, worker, path=["response"]) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize def test_raw_response_update(self, client: Cloudflare) -> None: response = client.workers.beta.workers.with_raw_response.update( @@ -150,6 +158,7 @@ def test_raw_response_update(self, client: Cloudflare) -> None: worker = response.parse() assert_matches_type(Worker, worker, path=["response"]) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize def test_streaming_response_update(self, client: Cloudflare) -> None: with client.workers.beta.workers.with_streaming_response.update( @@ -165,6 +174,7 @@ def test_streaming_response_update(self, client: Cloudflare) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize def test_path_params_update(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): @@ -443,6 +453,7 @@ class TestAsyncWorkers: "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] ) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize async def test_method_create(self, async_client: AsyncCloudflare) -> None: worker = await async_client.workers.beta.workers.create( @@ -451,6 +462,7 @@ async def test_method_create(self, async_client: AsyncCloudflare) -> None: ) assert_matches_type(Worker, worker, path=["response"]) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: worker = await async_client.workers.beta.workers.create( @@ -483,6 +495,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare ) assert_matches_type(Worker, worker, path=["response"]) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: response = await async_client.workers.beta.workers.with_raw_response.create( @@ -495,6 +508,7 @@ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: worker = await response.parse() assert_matches_type(Worker, worker, path=["response"]) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: async with async_client.workers.beta.workers.with_streaming_response.create( @@ -509,6 +523,7 @@ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): @@ -517,6 +532,7 @@ async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: name="my-worker", ) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize async def test_method_update(self, async_client: AsyncCloudflare) -> None: worker = await async_client.workers.beta.workers.update( @@ -526,6 +542,7 @@ async def test_method_update(self, async_client: AsyncCloudflare) -> None: ) assert_matches_type(Worker, worker, path=["response"]) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: worker = await async_client.workers.beta.workers.update( @@ -559,6 +576,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare ) assert_matches_type(Worker, worker, path=["response"]) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: response = await async_client.workers.beta.workers.with_raw_response.update( @@ -572,6 +590,7 @@ async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: worker = await response.parse() assert_matches_type(Worker, worker, path=["response"]) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: async with async_client.workers.beta.workers.with_streaming_response.update( @@ -587,6 +606,7 @@ async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): diff --git a/tests/api_resources/workers/observability/test_telemetry.py b/tests/api_resources/workers/observability/test_telemetry.py index 2628834629b..3d5d7594ef2 100644 --- a/tests/api_resources/workers/observability/test_telemetry.py +++ b/tests/api_resources/workers/observability/test_telemetry.py @@ -22,6 +22,7 @@ class TestTelemetry: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize def test_method_keys(self, client: Cloudflare) -> None: telemetry = client.workers.observability.telemetry.keys( @@ -29,6 +30,7 @@ def test_method_keys(self, client: Cloudflare) -> None: ) assert_matches_type(SyncSinglePage[TelemetryKeysResponse], telemetry, path=["response"]) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize def test_method_keys_with_all_params(self, client: Cloudflare) -> None: telemetry = client.workers.observability.telemetry.keys( @@ -37,7 +39,13 @@ def test_method_keys_with_all_params(self, client: Cloudflare) -> None: filters=[ { "filter_combination": "and", - "filters": [{}], + "filters": [ + { + "filter_combination": "and", + "filters": [{}], + "kind": "group", + } + ], "kind": "group", } ], @@ -57,6 +65,7 @@ def test_method_keys_with_all_params(self, client: Cloudflare) -> None: ) assert_matches_type(SyncSinglePage[TelemetryKeysResponse], telemetry, path=["response"]) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize def test_raw_response_keys(self, client: Cloudflare) -> None: response = client.workers.observability.telemetry.with_raw_response.keys( @@ -68,6 +77,7 @@ def test_raw_response_keys(self, client: Cloudflare) -> None: telemetry = response.parse() assert_matches_type(SyncSinglePage[TelemetryKeysResponse], telemetry, path=["response"]) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize def test_streaming_response_keys(self, client: Cloudflare) -> None: with client.workers.observability.telemetry.with_streaming_response.keys( @@ -81,6 +91,7 @@ def test_streaming_response_keys(self, client: Cloudflare) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize def test_path_params_keys(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): @@ -88,7 +99,7 @@ def test_path_params_keys(self, client: Cloudflare) -> None: account_id="", ) - @pytest.mark.skip(reason="RunQueryParametersNeedleValue modeled as empty BaseModel, cannot deserialize string from Prism") + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize def test_method_query(self, client: Cloudflare) -> None: telemetry = client.workers.observability.telemetry.query( @@ -101,7 +112,7 @@ def test_method_query(self, client: Cloudflare) -> None: ) assert_matches_type(TelemetryQueryResponse, telemetry, path=["response"]) - @pytest.mark.skip(reason="RunQueryParametersNeedleValue modeled as empty BaseModel, cannot deserialize string from Prism") + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize def test_method_query_with_all_params(self, client: Cloudflare) -> None: telemetry = client.workers.observability.telemetry.query( @@ -134,7 +145,13 @@ def test_method_query_with_all_params(self, client: Cloudflare) -> None: "filters": [ { "filter_combination": "and", - "filters": [{}], + "filters": [ + { + "filter_combination": "and", + "filters": [{}], + "kind": "group", + } + ], "kind": "group", } ], @@ -166,7 +183,7 @@ def test_method_query_with_all_params(self, client: Cloudflare) -> None: ) assert_matches_type(TelemetryQueryResponse, telemetry, path=["response"]) - @pytest.mark.skip(reason="RunQueryParametersNeedleValue modeled as empty BaseModel, cannot deserialize string from Prism") + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize def test_raw_response_query(self, client: Cloudflare) -> None: response = client.workers.observability.telemetry.with_raw_response.query( @@ -183,7 +200,7 @@ def test_raw_response_query(self, client: Cloudflare) -> None: telemetry = response.parse() assert_matches_type(TelemetryQueryResponse, telemetry, path=["response"]) - @pytest.mark.skip(reason="RunQueryParametersNeedleValue modeled as empty BaseModel, cannot deserialize string from Prism") + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize def test_streaming_response_query(self, client: Cloudflare) -> None: with client.workers.observability.telemetry.with_streaming_response.query( @@ -202,6 +219,7 @@ def test_streaming_response_query(self, client: Cloudflare) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize def test_path_params_query(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): @@ -214,6 +232,7 @@ def test_path_params_query(self, client: Cloudflare) -> None: }, ) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize def test_method_values(self, client: Cloudflare) -> None: telemetry = client.workers.observability.telemetry.values( @@ -228,6 +247,7 @@ def test_method_values(self, client: Cloudflare) -> None: ) assert_matches_type(SyncSinglePage[TelemetryValuesResponse], telemetry, path=["response"]) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize def test_method_values_with_all_params(self, client: Cloudflare) -> None: telemetry = client.workers.observability.telemetry.values( @@ -242,7 +262,13 @@ def test_method_values_with_all_params(self, client: Cloudflare) -> None: filters=[ { "filter_combination": "and", - "filters": [{}], + "filters": [ + { + "filter_combination": "and", + "filters": [{}], + "kind": "group", + } + ], "kind": "group", } ], @@ -255,6 +281,7 @@ def test_method_values_with_all_params(self, client: Cloudflare) -> None: ) assert_matches_type(SyncSinglePage[TelemetryValuesResponse], telemetry, path=["response"]) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize def test_raw_response_values(self, client: Cloudflare) -> None: response = client.workers.observability.telemetry.with_raw_response.values( @@ -273,6 +300,7 @@ def test_raw_response_values(self, client: Cloudflare) -> None: telemetry = response.parse() assert_matches_type(SyncSinglePage[TelemetryValuesResponse], telemetry, path=["response"]) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize def test_streaming_response_values(self, client: Cloudflare) -> None: with client.workers.observability.telemetry.with_streaming_response.values( @@ -293,6 +321,7 @@ def test_streaming_response_values(self, client: Cloudflare) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize def test_path_params_values(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): @@ -313,6 +342,7 @@ class TestAsyncTelemetry: "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] ) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize async def test_method_keys(self, async_client: AsyncCloudflare) -> None: telemetry = await async_client.workers.observability.telemetry.keys( @@ -320,6 +350,7 @@ async def test_method_keys(self, async_client: AsyncCloudflare) -> None: ) assert_matches_type(AsyncSinglePage[TelemetryKeysResponse], telemetry, path=["response"]) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize async def test_method_keys_with_all_params(self, async_client: AsyncCloudflare) -> None: telemetry = await async_client.workers.observability.telemetry.keys( @@ -328,7 +359,13 @@ async def test_method_keys_with_all_params(self, async_client: AsyncCloudflare) filters=[ { "filter_combination": "and", - "filters": [{}], + "filters": [ + { + "filter_combination": "and", + "filters": [{}], + "kind": "group", + } + ], "kind": "group", } ], @@ -348,6 +385,7 @@ async def test_method_keys_with_all_params(self, async_client: AsyncCloudflare) ) assert_matches_type(AsyncSinglePage[TelemetryKeysResponse], telemetry, path=["response"]) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize async def test_raw_response_keys(self, async_client: AsyncCloudflare) -> None: response = await async_client.workers.observability.telemetry.with_raw_response.keys( @@ -359,6 +397,7 @@ async def test_raw_response_keys(self, async_client: AsyncCloudflare) -> None: telemetry = await response.parse() assert_matches_type(AsyncSinglePage[TelemetryKeysResponse], telemetry, path=["response"]) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize async def test_streaming_response_keys(self, async_client: AsyncCloudflare) -> None: async with async_client.workers.observability.telemetry.with_streaming_response.keys( @@ -372,6 +411,7 @@ async def test_streaming_response_keys(self, async_client: AsyncCloudflare) -> N assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize async def test_path_params_keys(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): @@ -379,7 +419,7 @@ async def test_path_params_keys(self, async_client: AsyncCloudflare) -> None: account_id="", ) - @pytest.mark.skip(reason="RunQueryParametersNeedleValue modeled as empty BaseModel, cannot deserialize string from Prism") + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize async def test_method_query(self, async_client: AsyncCloudflare) -> None: telemetry = await async_client.workers.observability.telemetry.query( @@ -392,7 +432,7 @@ async def test_method_query(self, async_client: AsyncCloudflare) -> None: ) assert_matches_type(TelemetryQueryResponse, telemetry, path=["response"]) - @pytest.mark.skip(reason="RunQueryParametersNeedleValue modeled as empty BaseModel, cannot deserialize string from Prism") + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize async def test_method_query_with_all_params(self, async_client: AsyncCloudflare) -> None: telemetry = await async_client.workers.observability.telemetry.query( @@ -425,7 +465,13 @@ async def test_method_query_with_all_params(self, async_client: AsyncCloudflare) "filters": [ { "filter_combination": "and", - "filters": [{}], + "filters": [ + { + "filter_combination": "and", + "filters": [{}], + "kind": "group", + } + ], "kind": "group", } ], @@ -457,7 +503,7 @@ async def test_method_query_with_all_params(self, async_client: AsyncCloudflare) ) assert_matches_type(TelemetryQueryResponse, telemetry, path=["response"]) - @pytest.mark.skip(reason="RunQueryParametersNeedleValue modeled as empty BaseModel, cannot deserialize string from Prism") + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize async def test_raw_response_query(self, async_client: AsyncCloudflare) -> None: response = await async_client.workers.observability.telemetry.with_raw_response.query( @@ -474,7 +520,7 @@ async def test_raw_response_query(self, async_client: AsyncCloudflare) -> None: telemetry = await response.parse() assert_matches_type(TelemetryQueryResponse, telemetry, path=["response"]) - @pytest.mark.skip(reason="RunQueryParametersNeedleValue modeled as empty BaseModel, cannot deserialize string from Prism") + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize async def test_streaming_response_query(self, async_client: AsyncCloudflare) -> None: async with async_client.workers.observability.telemetry.with_streaming_response.query( @@ -493,6 +539,7 @@ async def test_streaming_response_query(self, async_client: AsyncCloudflare) -> assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize async def test_path_params_query(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): @@ -505,6 +552,7 @@ async def test_path_params_query(self, async_client: AsyncCloudflare) -> None: }, ) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize async def test_method_values(self, async_client: AsyncCloudflare) -> None: telemetry = await async_client.workers.observability.telemetry.values( @@ -519,6 +567,7 @@ async def test_method_values(self, async_client: AsyncCloudflare) -> None: ) assert_matches_type(AsyncSinglePage[TelemetryValuesResponse], telemetry, path=["response"]) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize async def test_method_values_with_all_params(self, async_client: AsyncCloudflare) -> None: telemetry = await async_client.workers.observability.telemetry.values( @@ -533,7 +582,13 @@ async def test_method_values_with_all_params(self, async_client: AsyncCloudflare filters=[ { "filter_combination": "and", - "filters": [{}], + "filters": [ + { + "filter_combination": "and", + "filters": [{}], + "kind": "group", + } + ], "kind": "group", } ], @@ -546,6 +601,7 @@ async def test_method_values_with_all_params(self, async_client: AsyncCloudflare ) assert_matches_type(AsyncSinglePage[TelemetryValuesResponse], telemetry, path=["response"]) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize async def test_raw_response_values(self, async_client: AsyncCloudflare) -> None: response = await async_client.workers.observability.telemetry.with_raw_response.values( @@ -564,6 +620,7 @@ async def test_raw_response_values(self, async_client: AsyncCloudflare) -> None: telemetry = await response.parse() assert_matches_type(AsyncSinglePage[TelemetryValuesResponse], telemetry, path=["response"]) + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize async def test_streaming_response_values(self, async_client: AsyncCloudflare) -> None: async with async_client.workers.observability.telemetry.with_streaming_response.values( @@ -584,6 +641,7 @@ async def test_streaming_response_values(self, async_client: AsyncCloudflare) -> assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="HTTP 400 error from prism") @parametrize async def test_path_params_values(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): diff --git a/tests/api_resources/zero_trust/access/applications/policy_tests/__init__.py b/tests/api_resources/zero_trust/access/applications/policy_tests/__init__.py old mode 100755 new mode 100644 diff --git a/tests/api_resources/zero_trust/access/applications/policy_tests/test_users.py b/tests/api_resources/zero_trust/access/applications/policy_tests/test_users.py old mode 100755 new mode 100644 diff --git a/tests/api_resources/zero_trust/access/applications/test_policy_tests.py b/tests/api_resources/zero_trust/access/applications/test_policy_tests.py old mode 100755 new mode 100644 diff --git a/tests/api_resources/zero_trust/devices/policies/test_custom.py b/tests/api_resources/zero_trust/devices/policies/test_custom.py index 324311c25b8..2579fa98389 100644 --- a/tests/api_resources/zero_trust/devices/policies/test_custom.py +++ b/tests/api_resources/zero_trust/devices/policies/test_custom.py @@ -69,6 +69,10 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: support_url="https://1.1.1.1/help", switch_locked=True, tunnel_protocol="wireguard", + virtual_networks={ + "allowed": ["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + "default": "f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + }, ) assert_matches_type(Optional[SettingsPolicy], custom, path=["response"]) @@ -251,6 +255,10 @@ def test_method_edit_with_all_params(self, client: Cloudflare) -> None: support_url="https://1.1.1.1/help", switch_locked=True, tunnel_protocol="wireguard", + virtual_networks={ + "allowed": ["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + "default": "f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + }, ) assert_matches_type(Optional[SettingsPolicy], custom, path=["response"]) @@ -406,6 +414,10 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare support_url="https://1.1.1.1/help", switch_locked=True, tunnel_protocol="wireguard", + virtual_networks={ + "allowed": ["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + "default": "f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + }, ) assert_matches_type(Optional[SettingsPolicy], custom, path=["response"]) @@ -588,6 +600,10 @@ async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) support_url="https://1.1.1.1/help", switch_locked=True, tunnel_protocol="wireguard", + virtual_networks={ + "allowed": ["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + "default": "f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + }, ) assert_matches_type(Optional[SettingsPolicy], custom, path=["response"]) diff --git a/tests/api_resources/zero_trust/devices/policies/test_default.py b/tests/api_resources/zero_trust/devices/policies/test_default.py index 4e6dce31427..2c5d907468e 100644 --- a/tests/api_resources/zero_trust/devices/policies/test_default.py +++ b/tests/api_resources/zero_trust/devices/policies/test_default.py @@ -58,6 +58,10 @@ def test_method_edit_with_all_params(self, client: Cloudflare) -> None: support_url="https://1.1.1.1/help", switch_locked=True, tunnel_protocol="wireguard", + virtual_networks={ + "allowed": ["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + "default": "f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + }, ) assert_matches_type(Optional[DefaultEditResponse], default, path=["response"]) @@ -177,6 +181,10 @@ async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) support_url="https://1.1.1.1/help", switch_locked=True, tunnel_protocol="wireguard", + virtual_networks={ + "allowed": ["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + "default": "f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + }, ) assert_matches_type(Optional[DefaultEditResponse], default, path=["response"]) diff --git a/tests/api_resources/zero_trust/devices/test_deployment_groups.py b/tests/api_resources/zero_trust/devices/test_deployment_groups.py new file mode 100644 index 00000000000..98dd6882828 --- /dev/null +++ b/tests/api_resources/zero_trust/devices/test_deployment_groups.py @@ -0,0 +1,650 @@ +# 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 cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray +from cloudflare.types.zero_trust.devices import ( + DeploymentGroup, + DeploymentGroupDeleteResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestDeploymentGroups: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + deployment_group = client.zero_trust.devices.deployment_groups.create( + account_id="account_id", + name="Engineering Ring 0", + version_config=[ + { + "target_environment": "windows", + "version": "2026.5.234.0", + } + ], + ) + assert_matches_type(DeploymentGroup, deployment_group, path=["response"]) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + def test_method_create_with_all_params(self, client: Cloudflare) -> None: + deployment_group = client.zero_trust.devices.deployment_groups.create( + account_id="account_id", + name="Engineering Ring 0", + version_config=[ + { + "target_environment": "windows", + "version": "2026.5.234.0", + } + ], + policy_ids=["string"], + ) + assert_matches_type(DeploymentGroup, deployment_group, path=["response"]) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.zero_trust.devices.deployment_groups.with_raw_response.create( + account_id="account_id", + name="Engineering Ring 0", + version_config=[ + { + "target_environment": "windows", + "version": "2026.5.234.0", + } + ], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment_group = response.parse() + assert_matches_type(DeploymentGroup, deployment_group, path=["response"]) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.zero_trust.devices.deployment_groups.with_streaming_response.create( + account_id="account_id", + name="Engineering Ring 0", + version_config=[ + { + "target_environment": "windows", + "version": "2026.5.234.0", + } + ], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment_group = response.parse() + assert_matches_type(DeploymentGroup, deployment_group, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + def test_path_params_create(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.devices.deployment_groups.with_raw_response.create( + account_id="", + name="Engineering Ring 0", + version_config=[ + { + "target_environment": "windows", + "version": "2026.5.234.0", + } + ], + ) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + deployment_group = client.zero_trust.devices.deployment_groups.list( + account_id="account_id", + ) + assert_matches_type(SyncV4PagePaginationArray[DeploymentGroup], deployment_group, path=["response"]) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + deployment_group = client.zero_trust.devices.deployment_groups.list( + account_id="account_id", + page=1, + per_page=1, + ) + assert_matches_type(SyncV4PagePaginationArray[DeploymentGroup], deployment_group, path=["response"]) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.zero_trust.devices.deployment_groups.with_raw_response.list( + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment_group = response.parse() + assert_matches_type(SyncV4PagePaginationArray[DeploymentGroup], deployment_group, path=["response"]) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.zero_trust.devices.deployment_groups.with_streaming_response.list( + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment_group = response.parse() + assert_matches_type(SyncV4PagePaginationArray[DeploymentGroup], deployment_group, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.devices.deployment_groups.with_raw_response.list( + account_id="", + ) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + deployment_group = client.zero_trust.devices.deployment_groups.delete( + group_id="group_id", + account_id="account_id", + ) + assert_matches_type(DeploymentGroupDeleteResponse, deployment_group, path=["response"]) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.zero_trust.devices.deployment_groups.with_raw_response.delete( + group_id="group_id", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment_group = response.parse() + assert_matches_type(DeploymentGroupDeleteResponse, deployment_group, path=["response"]) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.zero_trust.devices.deployment_groups.with_streaming_response.delete( + group_id="group_id", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment_group = response.parse() + assert_matches_type(DeploymentGroupDeleteResponse, deployment_group, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.devices.deployment_groups.with_raw_response.delete( + group_id="group_id", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `group_id` but received ''"): + client.zero_trust.devices.deployment_groups.with_raw_response.delete( + group_id="", + account_id="account_id", + ) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + def test_method_edit(self, client: Cloudflare) -> None: + deployment_group = client.zero_trust.devices.deployment_groups.edit( + group_id="group_id", + account_id="account_id", + ) + assert_matches_type(DeploymentGroup, deployment_group, path=["response"]) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + def test_method_edit_with_all_params(self, client: Cloudflare) -> None: + deployment_group = client.zero_trust.devices.deployment_groups.edit( + group_id="group_id", + account_id="account_id", + name="Engineering Ring 0", + policy_ids=["string"], + version_config=[ + { + "target_environment": "windows", + "version": "2026.5.234.0", + } + ], + ) + assert_matches_type(DeploymentGroup, deployment_group, path=["response"]) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + def test_raw_response_edit(self, client: Cloudflare) -> None: + response = client.zero_trust.devices.deployment_groups.with_raw_response.edit( + group_id="group_id", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment_group = response.parse() + assert_matches_type(DeploymentGroup, deployment_group, path=["response"]) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + def test_streaming_response_edit(self, client: Cloudflare) -> None: + with client.zero_trust.devices.deployment_groups.with_streaming_response.edit( + group_id="group_id", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment_group = response.parse() + assert_matches_type(DeploymentGroup, deployment_group, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + def test_path_params_edit(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.devices.deployment_groups.with_raw_response.edit( + group_id="group_id", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `group_id` but received ''"): + client.zero_trust.devices.deployment_groups.with_raw_response.edit( + group_id="", + account_id="account_id", + ) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + deployment_group = client.zero_trust.devices.deployment_groups.get( + group_id="group_id", + account_id="account_id", + ) + assert_matches_type(DeploymentGroup, deployment_group, path=["response"]) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.zero_trust.devices.deployment_groups.with_raw_response.get( + group_id="group_id", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment_group = response.parse() + assert_matches_type(DeploymentGroup, deployment_group, path=["response"]) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.zero_trust.devices.deployment_groups.with_streaming_response.get( + group_id="group_id", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment_group = response.parse() + assert_matches_type(DeploymentGroup, deployment_group, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.devices.deployment_groups.with_raw_response.get( + group_id="group_id", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `group_id` but received ''"): + client.zero_trust.devices.deployment_groups.with_raw_response.get( + group_id="", + account_id="account_id", + ) + + +class TestAsyncDeploymentGroups: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + async def test_method_create(self, async_client: AsyncCloudflare) -> None: + deployment_group = await async_client.zero_trust.devices.deployment_groups.create( + account_id="account_id", + name="Engineering Ring 0", + version_config=[ + { + "target_environment": "windows", + "version": "2026.5.234.0", + } + ], + ) + assert_matches_type(DeploymentGroup, deployment_group, path=["response"]) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: + deployment_group = await async_client.zero_trust.devices.deployment_groups.create( + account_id="account_id", + name="Engineering Ring 0", + version_config=[ + { + "target_environment": "windows", + "version": "2026.5.234.0", + } + ], + policy_ids=["string"], + ) + assert_matches_type(DeploymentGroup, deployment_group, path=["response"]) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.devices.deployment_groups.with_raw_response.create( + account_id="account_id", + name="Engineering Ring 0", + version_config=[ + { + "target_environment": "windows", + "version": "2026.5.234.0", + } + ], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment_group = await response.parse() + assert_matches_type(DeploymentGroup, deployment_group, path=["response"]) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.devices.deployment_groups.with_streaming_response.create( + account_id="account_id", + name="Engineering Ring 0", + version_config=[ + { + "target_environment": "windows", + "version": "2026.5.234.0", + } + ], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment_group = await response.parse() + assert_matches_type(DeploymentGroup, deployment_group, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.devices.deployment_groups.with_raw_response.create( + account_id="", + name="Engineering Ring 0", + version_config=[ + { + "target_environment": "windows", + "version": "2026.5.234.0", + } + ], + ) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + deployment_group = await async_client.zero_trust.devices.deployment_groups.list( + account_id="account_id", + ) + assert_matches_type(AsyncV4PagePaginationArray[DeploymentGroup], deployment_group, path=["response"]) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + deployment_group = await async_client.zero_trust.devices.deployment_groups.list( + account_id="account_id", + page=1, + per_page=1, + ) + assert_matches_type(AsyncV4PagePaginationArray[DeploymentGroup], deployment_group, path=["response"]) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.devices.deployment_groups.with_raw_response.list( + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment_group = await response.parse() + assert_matches_type(AsyncV4PagePaginationArray[DeploymentGroup], deployment_group, path=["response"]) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.devices.deployment_groups.with_streaming_response.list( + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment_group = await response.parse() + assert_matches_type(AsyncV4PagePaginationArray[DeploymentGroup], deployment_group, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.devices.deployment_groups.with_raw_response.list( + account_id="", + ) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + deployment_group = await async_client.zero_trust.devices.deployment_groups.delete( + group_id="group_id", + account_id="account_id", + ) + assert_matches_type(DeploymentGroupDeleteResponse, deployment_group, path=["response"]) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.devices.deployment_groups.with_raw_response.delete( + group_id="group_id", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment_group = await response.parse() + assert_matches_type(DeploymentGroupDeleteResponse, deployment_group, path=["response"]) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.devices.deployment_groups.with_streaming_response.delete( + group_id="group_id", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment_group = await response.parse() + assert_matches_type(DeploymentGroupDeleteResponse, deployment_group, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.devices.deployment_groups.with_raw_response.delete( + group_id="group_id", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `group_id` but received ''"): + await async_client.zero_trust.devices.deployment_groups.with_raw_response.delete( + group_id="", + account_id="account_id", + ) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + async def test_method_edit(self, async_client: AsyncCloudflare) -> None: + deployment_group = await async_client.zero_trust.devices.deployment_groups.edit( + group_id="group_id", + account_id="account_id", + ) + assert_matches_type(DeploymentGroup, deployment_group, path=["response"]) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) -> None: + deployment_group = await async_client.zero_trust.devices.deployment_groups.edit( + group_id="group_id", + account_id="account_id", + name="Engineering Ring 0", + policy_ids=["string"], + version_config=[ + { + "target_environment": "windows", + "version": "2026.5.234.0", + } + ], + ) + assert_matches_type(DeploymentGroup, deployment_group, path=["response"]) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + async def test_raw_response_edit(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.devices.deployment_groups.with_raw_response.edit( + group_id="group_id", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment_group = await response.parse() + assert_matches_type(DeploymentGroup, deployment_group, path=["response"]) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + async def test_streaming_response_edit(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.devices.deployment_groups.with_streaming_response.edit( + group_id="group_id", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment_group = await response.parse() + assert_matches_type(DeploymentGroup, deployment_group, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + async def test_path_params_edit(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.devices.deployment_groups.with_raw_response.edit( + group_id="group_id", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `group_id` but received ''"): + await async_client.zero_trust.devices.deployment_groups.with_raw_response.edit( + group_id="", + account_id="account_id", + ) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + deployment_group = await async_client.zero_trust.devices.deployment_groups.get( + group_id="group_id", + account_id="account_id", + ) + assert_matches_type(DeploymentGroup, deployment_group, path=["response"]) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.devices.deployment_groups.with_raw_response.get( + group_id="group_id", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment_group = await response.parse() + assert_matches_type(DeploymentGroup, deployment_group, path=["response"]) + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.devices.deployment_groups.with_streaming_response.get( + group_id="group_id", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment_group = await response.parse() + assert_matches_type(DeploymentGroup, deployment_group, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="HTTP 401 error from prism") + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.devices.deployment_groups.with_raw_response.get( + group_id="group_id", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `group_id` but received ''"): + await async_client.zero_trust.devices.deployment_groups.with_raw_response.get( + group_id="", + account_id="account_id", + ) diff --git a/tests/api_resources/zero_trust/dlp/datasets/test_versions.py b/tests/api_resources/zero_trust/dlp/datasets/test_versions.py old mode 100755 new mode 100644 diff --git a/tests/api_resources/zero_trust/dlp/datasets/versions/__init__.py b/tests/api_resources/zero_trust/dlp/datasets/versions/__init__.py old mode 100755 new mode 100644 diff --git a/tests/api_resources/zero_trust/dlp/datasets/versions/test_entries.py b/tests/api_resources/zero_trust/dlp/datasets/versions/test_entries.py old mode 100755 new mode 100644 diff --git a/tests/api_resources/zero_trust/dlp/test_limits.py b/tests/api_resources/zero_trust/dlp/test_limits.py old mode 100755 new mode 100644 diff --git a/tests/api_resources/zero_trust/gateway/configurations/__init__.py b/tests/api_resources/zero_trust/gateway/configurations/__init__.py old mode 100755 new mode 100644 diff --git a/uv.lock b/uv.lock new file mode 100644 index 00000000000..d9973e37a7d --- /dev/null +++ b/uv.lock @@ -0,0 +1,2083 @@ +version = 1 +revision = 3 +requires-python = ">=3.9" +resolution-markers = [ + "python_full_version >= '3.14' and extra != 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and python_full_version < '3.14' and extra != 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2'", + "python_full_version < '3.10' and extra != 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and extra == 'group-10-cloudflare-pydantic-v1' and extra != 'group-10-cloudflare-pydantic-v2'", + "python_full_version < '3.10' and extra == 'group-10-cloudflare-pydantic-v1' and extra != 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and extra != 'group-10-cloudflare-pydantic-v1' and extra != 'group-10-cloudflare-pydantic-v2'", + "python_full_version < '3.10' and extra != 'group-10-cloudflare-pydantic-v1' and extra != 'group-10-cloudflare-pydantic-v2'", +] +conflicts = [[ + { package = "cloudflare", group = "pydantic-v1" }, + { package = "cloudflare", group = "pydantic-v2" }, +]] + +[[package]] +name = "aiohappyeyeballs" +version = "2.6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/26/30/f84a107a9c4331c14b2b586036f40965c128aa4fee4dda5d3d51cb14ad54/aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", size = 22760, upload-time = "2025-03-12T01:42:48.764Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8", size = 15265, upload-time = "2025-03-12T01:42:47.083Z" }, +] + +[[package]] +name = "aiohttp" +version = "3.13.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohappyeyeballs" }, + { name = "aiosignal" }, + { name = "async-timeout", marker = "python_full_version < '3.11' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "attrs" }, + { name = "frozenlist" }, + { name = "multidict" }, + { name = "propcache" }, + { name = "yarl", version = "1.22.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "yarl", version = "1.23.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/77/9a/152096d4808df8e4268befa55fba462f440f14beab85e8ad9bf990516918/aiohttp-3.13.5.tar.gz", hash = "sha256:9d98cc980ecc96be6eb4c1994ce35d28d8b1f5e5208a23b421187d1209dbb7d1", size = 7858271, upload-time = "2026-03-31T22:01:03.343Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/85/cebc47ee74d8b408749073a1a46c6fcba13d170dc8af7e61996c6c9394ac/aiohttp-3.13.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:02222e7e233295f40e011c1b00e3b0bd451f22cf853a0304c3595633ee47da4b", size = 750547, upload-time = "2026-03-31T21:56:30.024Z" }, + { url = "https://files.pythonhosted.org/packages/05/98/afd308e35b9d3d8c9ec54c0918f1d722c86dc17ddfec272fcdbcce5a3124/aiohttp-3.13.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bace460460ed20614fa6bc8cb09966c0b8517b8c58ad8046828c6078d25333b5", size = 503535, upload-time = "2026-03-31T21:56:31.935Z" }, + { url = "https://files.pythonhosted.org/packages/6f/4d/926c183e06b09d5270a309eb50fbde7b09782bfd305dec1e800f329834fb/aiohttp-3.13.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f546a4dc1e6a5edbb9fd1fd6ad18134550e096a5a43f4ad74acfbd834fc6670", size = 497830, upload-time = "2026-03-31T21:56:33.654Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d6/f47d1c690f115a5c2a5e8938cce4a232a5be9aac5c5fb2647efcbbbda333/aiohttp-3.13.5-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c86969d012e51b8e415a8c6ce96f7857d6a87d6207303ab02d5d11ef0cad2274", size = 1682474, upload-time = "2026-03-31T21:56:35.513Z" }, + { url = "https://files.pythonhosted.org/packages/01/44/056fd37b1bb52eac760303e5196acc74d9d546631b035704ae5927f7b4ac/aiohttp-3.13.5-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b6f6cd1560c5fa427e3b6074bb24d2c64e225afbb7165008903bd42e4e33e28a", size = 1655259, upload-time = "2026-03-31T21:56:37.843Z" }, + { url = "https://files.pythonhosted.org/packages/91/9f/78eb1a20c1c28ae02f6a3c0f4d7b0dcc66abce5290cadd53d78ce3084175/aiohttp-3.13.5-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:636bc362f0c5bbc7372bc3ae49737f9e3030dbce469f0f422c8f38079780363d", size = 1736204, upload-time = "2026-03-31T21:56:39.822Z" }, + { url = "https://files.pythonhosted.org/packages/de/6c/d20d7de23f0b52b8c1d9e2033b2db1ac4dacbb470bb74c56de0f5f86bb4f/aiohttp-3.13.5-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6a7cbeb06d1070f1d14895eeeed4dac5913b22d7b456f2eb969f11f4b3993796", size = 1826198, upload-time = "2026-03-31T21:56:41.378Z" }, + { url = "https://files.pythonhosted.org/packages/2f/86/a6f3ff1fd795f49545a7c74b2c92f62729135d73e7e4055bf74da5a26c82/aiohttp-3.13.5-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bca9ef7517fd7874a1a08970ae88f497bf5c984610caa0bf40bd7e8450852b95", size = 1681329, upload-time = "2026-03-31T21:56:43.374Z" }, + { url = "https://files.pythonhosted.org/packages/fb/68/84cd3dab6b7b4f3e6fe9459a961acb142aaab846417f6e8905110d7027e5/aiohttp-3.13.5-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:019a67772e034a0e6b9b17c13d0a8fe56ad9fb150fc724b7f3ffd3724288d9e5", size = 1560023, upload-time = "2026-03-31T21:56:45.031Z" }, + { url = "https://files.pythonhosted.org/packages/41/2c/db61b64b0249e30f954a65ab4cb4970ced57544b1de2e3c98ee5dc24165f/aiohttp-3.13.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f34ecee82858e41dd217734f0c41a532bd066bcaab636ad830f03a30b2a96f2a", size = 1652372, upload-time = "2026-03-31T21:56:47.075Z" }, + { url = "https://files.pythonhosted.org/packages/25/6f/e96988a6c982d047810c772e28c43c64c300c943b0ed5c1c0c4ce1e1027c/aiohttp-3.13.5-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:4eac02d9af4813ee289cd63a361576da36dba57f5a1ab36377bc2600db0cbb73", size = 1662031, upload-time = "2026-03-31T21:56:48.835Z" }, + { url = "https://files.pythonhosted.org/packages/b7/26/a56feace81f3d347b4052403a9d03754a0ab23f7940780dada0849a38c92/aiohttp-3.13.5-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4beac52e9fe46d6abf98b0176a88154b742e878fdf209d2248e99fcdf73cd297", size = 1708118, upload-time = "2026-03-31T21:56:50.833Z" }, + { url = "https://files.pythonhosted.org/packages/78/6e/b6173a8ff03d01d5e1a694bc06764b5dad1df2d4ed8f0ceec12bb3277936/aiohttp-3.13.5-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:c180f480207a9b2475f2b8d8bd7204e47aec952d084b2a2be58a782ffcf96074", size = 1548667, upload-time = "2026-03-31T21:56:52.81Z" }, + { url = "https://files.pythonhosted.org/packages/16/13/13296ffe2c132d888b3fe2c195c8b9c0c24c89c3fa5cc2c44464dc23b22e/aiohttp-3.13.5-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2837fb92951564d6339cedae4a7231692aa9f73cbc4fb2e04263b96844e03b4e", size = 1724490, upload-time = "2026-03-31T21:56:54.541Z" }, + { url = "https://files.pythonhosted.org/packages/7a/b4/1f1c287f4a79782ef36e5a6e62954c85343bc30470d862d30bd5f26c9fa2/aiohttp-3.13.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d9010032a0b9710f58012a1e9c222528763d860ba2ee1422c03473eab47703e7", size = 1667109, upload-time = "2026-03-31T21:56:56.21Z" }, + { url = "https://files.pythonhosted.org/packages/ef/42/8461a2aaf60a8f4ea4549a4056be36b904b0eb03d97ca9a8a2604681a500/aiohttp-3.13.5-cp310-cp310-win32.whl", hash = "sha256:7c4b6668b2b2b9027f209ddf647f2a4407784b5d88b8be4efcc72036f365baf9", size = 439478, upload-time = "2026-03-31T21:56:58.292Z" }, + { url = "https://files.pythonhosted.org/packages/e5/71/06956304cb5ee439dfe8d86e1b2e70088bd88ed1ced1f42fb29e5d855f0e/aiohttp-3.13.5-cp310-cp310-win_amd64.whl", hash = "sha256:cd3db5927bf9167d5a6157ddb2f036f6b6b0ad001ac82355d43e97a4bde76d76", size = 462047, upload-time = "2026-03-31T21:57:00.257Z" }, + { url = "https://files.pythonhosted.org/packages/d6/f5/a20c4ac64aeaef1679e25c9983573618ff765d7aa829fa2b84ae7573169e/aiohttp-3.13.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7ab7229b6f9b5c1ba4910d6c41a9eb11f543eadb3f384df1b4c293f4e73d44d6", size = 757513, upload-time = "2026-03-31T21:57:02.146Z" }, + { url = "https://files.pythonhosted.org/packages/75/0a/39fa6c6b179b53fcb3e4b3d2b6d6cad0180854eda17060c7218540102bef/aiohttp-3.13.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8f14c50708bb156b3a3ca7230b3d820199d56a48e3af76fa21c2d6087190fe3d", size = 506748, upload-time = "2026-03-31T21:57:04.275Z" }, + { url = "https://files.pythonhosted.org/packages/87/ec/e38ce072e724fd7add6243613f8d1810da084f54175353d25ccf9f9c7e5a/aiohttp-3.13.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e7d2f8616f0ff60bd332022279011776c3ac0faa0f1b463f7bb12326fbc97a1c", size = 501673, upload-time = "2026-03-31T21:57:06.208Z" }, + { url = "https://files.pythonhosted.org/packages/ba/ba/3bc7525d7e2beaa11b309a70d48b0d3cfc3c2089ec6a7d0820d59c657053/aiohttp-3.13.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a2567b72e1ffc3ab25510db43f355b29eeada56c0a622e58dcdb19530eb0a3cb", size = 1763757, upload-time = "2026-03-31T21:57:07.882Z" }, + { url = "https://files.pythonhosted.org/packages/5e/ab/e87744cf18f1bd78263aba24924d4953b41086bd3a31d22452378e9028a0/aiohttp-3.13.5-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:fb0540c854ac9c0c5ad495908fdfd3e332d553ec731698c0e29b1877ba0d2ec6", size = 1720152, upload-time = "2026-03-31T21:57:09.946Z" }, + { url = "https://files.pythonhosted.org/packages/6b/f3/ed17a6f2d742af17b50bae2d152315ed1b164b07a5fd5cc1754d99e4dfa5/aiohttp-3.13.5-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c9883051c6972f58bfc4ebb2116345ee2aa151178e99c3f2b2bbe2af712abd13", size = 1818010, upload-time = "2026-03-31T21:57:12.157Z" }, + { url = "https://files.pythonhosted.org/packages/53/06/ecbc63dc937192e2a5cb46df4d3edb21deb8225535818802f210a6ea5816/aiohttp-3.13.5-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2294172ce08a82fb7c7273485895de1fa1186cc8294cfeb6aef4af42ad261174", size = 1907251, upload-time = "2026-03-31T21:57:14.023Z" }, + { url = "https://files.pythonhosted.org/packages/7e/a5/0521aa32c1ddf3aa1e71dcc466be0b7db2771907a13f18cddaa45967d97b/aiohttp-3.13.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3a807cabd5115fb55af198b98178997a5e0e57dead43eb74a93d9c07d6d4a7dc", size = 1759969, upload-time = "2026-03-31T21:57:16.146Z" }, + { url = "https://files.pythonhosted.org/packages/f6/78/a38f8c9105199dd3b9706745865a8a59d0041b6be0ca0cc4b2ccf1bab374/aiohttp-3.13.5-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:aa6d0d932e0f39c02b80744273cd5c388a2d9bc07760a03164f229c8e02662f6", size = 1616871, upload-time = "2026-03-31T21:57:17.856Z" }, + { url = "https://files.pythonhosted.org/packages/6f/41/27392a61ead8ab38072105c71aa44ff891e71653fe53d576a7067da2b4e8/aiohttp-3.13.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:60869c7ac4aaabe7110f26499f3e6e5696eae98144735b12a9c3d9eae2b51a49", size = 1739844, upload-time = "2026-03-31T21:57:19.679Z" }, + { url = "https://files.pythonhosted.org/packages/6e/55/5564e7ae26d94f3214250009a0b1c65a0c6af4bf88924ccb6fdab901de28/aiohttp-3.13.5-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:26d2f8546f1dfa75efa50c3488215a903c0168d253b75fba4210f57ab77a0fb8", size = 1731969, upload-time = "2026-03-31T21:57:22.006Z" }, + { url = "https://files.pythonhosted.org/packages/6d/c5/705a3929149865fc941bcbdd1047b238e4a72bcb215a9b16b9d7a2e8d992/aiohttp-3.13.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1162a1492032c82f14271e831c8f4b49f2b6078f4f5fc74de2c912fa225d51d", size = 1795193, upload-time = "2026-03-31T21:57:24.256Z" }, + { url = "https://files.pythonhosted.org/packages/a6/19/edabed62f718d02cff7231ca0db4ef1c72504235bc467f7b67adb1679f48/aiohttp-3.13.5-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:8b14eb3262fad0dc2f89c1a43b13727e709504972186ff6a99a3ecaa77102b6c", size = 1606477, upload-time = "2026-03-31T21:57:26.364Z" }, + { url = "https://files.pythonhosted.org/packages/de/fc/76f80ef008675637d88d0b21584596dc27410a990b0918cb1e5776545b5b/aiohttp-3.13.5-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:ca9ac61ac6db4eb6c2a0cd1d0f7e1357647b638ccc92f7e9d8d133e71ed3c6ac", size = 1813198, upload-time = "2026-03-31T21:57:28.316Z" }, + { url = "https://files.pythonhosted.org/packages/e5/67/5b3ac26b80adb20ea541c487f73730dc8fa107d632c998f25bbbab98fcda/aiohttp-3.13.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7996023b2ed59489ae4762256c8516df9820f751cf2c5da8ed2fb20ee50abab3", size = 1752321, upload-time = "2026-03-31T21:57:30.549Z" }, + { url = "https://files.pythonhosted.org/packages/88/06/e4a2e49255ea23fa4feeb5ab092d90240d927c15e47b5b5c48dff5a9ce29/aiohttp-3.13.5-cp311-cp311-win32.whl", hash = "sha256:77dfa48c9f8013271011e51c00f8ada19851f013cde2c48fca1ba5e0caf5bb06", size = 439069, upload-time = "2026-03-31T21:57:32.388Z" }, + { url = "https://files.pythonhosted.org/packages/c0/43/8c7163a596dab4f8be12c190cf467a1e07e4734cf90eebb39f7f5d53fc6a/aiohttp-3.13.5-cp311-cp311-win_amd64.whl", hash = "sha256:d3a4834f221061624b8887090637db9ad4f61752001eae37d56c52fddade2dc8", size = 462859, upload-time = "2026-03-31T21:57:34.455Z" }, + { url = "https://files.pythonhosted.org/packages/be/6f/353954c29e7dcce7cf00280a02c75f30e133c00793c7a2ed3776d7b2f426/aiohttp-3.13.5-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:023ecba036ddd840b0b19bf195bfae970083fd7024ce1ac22e9bba90464620e9", size = 748876, upload-time = "2026-03-31T21:57:36.319Z" }, + { url = "https://files.pythonhosted.org/packages/f5/1b/428a7c64687b3b2e9cd293186695affc0e1e54a445d0361743b231f11066/aiohttp-3.13.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:15c933ad7920b7d9a20de151efcd05a6e38302cbf0e10c9b2acb9a42210a2416", size = 499557, upload-time = "2026-03-31T21:57:38.236Z" }, + { url = "https://files.pythonhosted.org/packages/29/47/7be41556bfbb6917069d6a6634bb7dd5e163ba445b783a90d40f5ac7e3a7/aiohttp-3.13.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ab2899f9fa2f9f741896ebb6fa07c4c883bfa5c7f2ddd8cf2aafa86fa981b2d2", size = 500258, upload-time = "2026-03-31T21:57:39.923Z" }, + { url = "https://files.pythonhosted.org/packages/67/84/c9ecc5828cb0b3695856c07c0a6817a99d51e2473400f705275a2b3d9239/aiohttp-3.13.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a60eaa2d440cd4707696b52e40ed3e2b0f73f65be07fd0ef23b6b539c9c0b0b4", size = 1749199, upload-time = "2026-03-31T21:57:41.938Z" }, + { url = "https://files.pythonhosted.org/packages/f0/d3/3c6d610e66b495657622edb6ae7c7fd31b2e9086b4ec50b47897ad6042a9/aiohttp-3.13.5-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:55b3bdd3292283295774ab585160c4004f4f2f203946997f49aac032c84649e9", size = 1721013, upload-time = "2026-03-31T21:57:43.904Z" }, + { url = "https://files.pythonhosted.org/packages/49/a0/24409c12217456df0bae7babe3b014e460b0b38a8e60753d6cb339f6556d/aiohttp-3.13.5-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c2b2355dc094e5f7d45a7bb262fe7207aa0460b37a0d87027dcf21b5d890e7d5", size = 1781501, upload-time = "2026-03-31T21:57:46.285Z" }, + { url = "https://files.pythonhosted.org/packages/98/9d/b65ec649adc5bccc008b0957a9a9c691070aeac4e41cea18559fef49958b/aiohttp-3.13.5-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b38765950832f7d728297689ad78f5f2cf79ff82487131c4d26fe6ceecdc5f8e", size = 1878981, upload-time = "2026-03-31T21:57:48.734Z" }, + { url = "https://files.pythonhosted.org/packages/57/d8/8d44036d7eb7b6a8ec4c5494ea0c8c8b94fbc0ed3991c1a7adf230df03bf/aiohttp-3.13.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b18f31b80d5a33661e08c89e202edabf1986e9b49c42b4504371daeaa11b47c1", size = 1767934, upload-time = "2026-03-31T21:57:51.171Z" }, + { url = "https://files.pythonhosted.org/packages/31/04/d3f8211f273356f158e3464e9e45484d3fb8c4ce5eb2f6fe9405c3273983/aiohttp-3.13.5-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:33add2463dde55c4f2d9635c6ab33ce154e5ecf322bd26d09af95c5f81cfa286", size = 1566671, upload-time = "2026-03-31T21:57:53.326Z" }, + { url = "https://files.pythonhosted.org/packages/41/db/073e4ebe00b78e2dfcacff734291651729a62953b48933d765dc513bf798/aiohttp-3.13.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:327cc432fdf1356fb4fbc6fe833ad4e9f6aacb71a8acaa5f1855e4b25910e4a9", size = 1705219, upload-time = "2026-03-31T21:57:55.385Z" }, + { url = "https://files.pythonhosted.org/packages/48/45/7dfba71a2f9fd97b15c95c06819de7eb38113d2cdb6319669195a7d64270/aiohttp-3.13.5-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:7c35b0bf0b48a70b4cb4fc5d7bed9b932532728e124874355de1a0af8ec4bc88", size = 1743049, upload-time = "2026-03-31T21:57:57.341Z" }, + { url = "https://files.pythonhosted.org/packages/18/71/901db0061e0f717d226386a7f471bb59b19566f2cae5f0d93874b017271f/aiohttp-3.13.5-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:df23d57718f24badef8656c49743e11a89fd6f5358fa8a7b96e728fda2abf7d3", size = 1749557, upload-time = "2026-03-31T21:57:59.626Z" }, + { url = "https://files.pythonhosted.org/packages/08/d5/41eebd16066e59cd43728fe74bce953d7402f2b4ddfdfef2c0e9f17ca274/aiohttp-3.13.5-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:02e048037a6501a5ec1f6fc9736135aec6eb8a004ce48838cb951c515f32c80b", size = 1558931, upload-time = "2026-03-31T21:58:01.972Z" }, + { url = "https://files.pythonhosted.org/packages/30/e6/4a799798bf05740e66c3a1161079bda7a3dd8e22ca392481d7a7f9af82a6/aiohttp-3.13.5-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:31cebae8b26f8a615d2b546fee45d5ffb76852ae6450e2a03f42c9102260d6fe", size = 1774125, upload-time = "2026-03-31T21:58:04.007Z" }, + { url = "https://files.pythonhosted.org/packages/84/63/7749337c90f92bc2cb18f9560d67aa6258c7060d1397d21529b8004fcf6f/aiohttp-3.13.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:888e78eb5ca55a615d285c3c09a7a91b42e9dd6fc699b166ebd5dee87c9ccf14", size = 1732427, upload-time = "2026-03-31T21:58:06.337Z" }, + { url = "https://files.pythonhosted.org/packages/98/de/cf2f44ff98d307e72fb97d5f5bbae3bfcb442f0ea9790c0bf5c5c2331404/aiohttp-3.13.5-cp312-cp312-win32.whl", hash = "sha256:8bd3ec6376e68a41f9f95f5ed170e2fcf22d4eb27a1f8cb361d0508f6e0557f3", size = 433534, upload-time = "2026-03-31T21:58:08.712Z" }, + { url = "https://files.pythonhosted.org/packages/aa/ca/eadf6f9c8fa5e31d40993e3db153fb5ed0b11008ad5d9de98a95045bed84/aiohttp-3.13.5-cp312-cp312-win_amd64.whl", hash = "sha256:110e448e02c729bcebb18c60b9214a87ba33bac4a9fa5e9a5f139938b56c6cb1", size = 460446, upload-time = "2026-03-31T21:58:10.945Z" }, + { url = "https://files.pythonhosted.org/packages/78/e9/d76bf503005709e390122d34e15256b88f7008e246c4bdbe915cd4f1adce/aiohttp-3.13.5-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a5029cc80718bbd545123cd8fe5d15025eccaaaace5d0eeec6bd556ad6163d61", size = 742930, upload-time = "2026-03-31T21:58:13.155Z" }, + { url = "https://files.pythonhosted.org/packages/57/00/4b7b70223deaebd9bb85984d01a764b0d7bd6526fcdc73cca83bcbe7243e/aiohttp-3.13.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4bb6bf5811620003614076bdc807ef3b5e38244f9d25ca5fe888eaccea2a9832", size = 496927, upload-time = "2026-03-31T21:58:15.073Z" }, + { url = "https://files.pythonhosted.org/packages/9c/f5/0fb20fb49f8efdcdce6cd8127604ad2c503e754a8f139f5e02b01626523f/aiohttp-3.13.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a84792f8631bf5a94e52d9cc881c0b824ab42717165a5579c760b830d9392ac9", size = 497141, upload-time = "2026-03-31T21:58:17.009Z" }, + { url = "https://files.pythonhosted.org/packages/3b/86/b7c870053e36a94e8951b803cb5b909bfbc9b90ca941527f5fcafbf6b0fa/aiohttp-3.13.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:57653eac22c6a4c13eb22ecf4d673d64a12f266e72785ab1c8b8e5940d0e8090", size = 1732476, upload-time = "2026-03-31T21:58:18.925Z" }, + { url = "https://files.pythonhosted.org/packages/b5/e5/4e161f84f98d80c03a238671b4136e6530453d65262867d989bbe78244d0/aiohttp-3.13.5-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5e5f7debc7a57af53fdf5c5009f9391d9f4c12867049d509bf7bb164a6e295b", size = 1706507, upload-time = "2026-03-31T21:58:21.094Z" }, + { url = "https://files.pythonhosted.org/packages/d4/56/ea11a9f01518bd5a2a2fcee869d248c4b8a0cfa0bb13401574fa31adf4d4/aiohttp-3.13.5-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c719f65bebcdf6716f10e9eff80d27567f7892d8988c06de12bbbd39307c6e3a", size = 1773465, upload-time = "2026-03-31T21:58:23.159Z" }, + { url = "https://files.pythonhosted.org/packages/eb/40/333ca27fb74b0383f17c90570c748f7582501507307350a79d9f9f3c6eb1/aiohttp-3.13.5-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d97f93fdae594d886c5a866636397e2bcab146fd7a132fd6bb9ce182224452f8", size = 1873523, upload-time = "2026-03-31T21:58:25.59Z" }, + { url = "https://files.pythonhosted.org/packages/f0/d2/e2f77eef1acb7111405433c707dc735e63f67a56e176e72e9e7a2cd3f493/aiohttp-3.13.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3df334e39d4c2f899a914f1dba283c1aadc311790733f705182998c6f7cae665", size = 1754113, upload-time = "2026-03-31T21:58:27.624Z" }, + { url = "https://files.pythonhosted.org/packages/fb/56/3f653d7f53c89669301ec9e42c95233e2a0c0a6dd051269e6e678db4fdb0/aiohttp-3.13.5-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fe6970addfea9e5e081401bcbadf865d2b6da045472f58af08427e108d618540", size = 1562351, upload-time = "2026-03-31T21:58:29.918Z" }, + { url = "https://files.pythonhosted.org/packages/ec/a6/9b3e91eb8ae791cce4ee736da02211c85c6f835f1bdfac0594a8a3b7018c/aiohttp-3.13.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7becdf835feff2f4f335d7477f121af787e3504b48b449ff737afb35869ba7bb", size = 1693205, upload-time = "2026-03-31T21:58:32.214Z" }, + { url = "https://files.pythonhosted.org/packages/98/fc/bfb437a99a2fcebd6b6eaec609571954de2ed424f01c352f4b5504371dd3/aiohttp-3.13.5-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:676e5651705ad5d8a70aeb8eb6936c436d8ebbd56e63436cb7dd9bb36d2a9a46", size = 1730618, upload-time = "2026-03-31T21:58:34.728Z" }, + { url = "https://files.pythonhosted.org/packages/e4/b6/c8534862126191a034f68153194c389addc285a0f1347d85096d349bbc15/aiohttp-3.13.5-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:9b16c653d38eb1a611cc898c41e76859ca27f119d25b53c12875fd0474ae31a8", size = 1745185, upload-time = "2026-03-31T21:58:36.909Z" }, + { url = "https://files.pythonhosted.org/packages/0b/93/4ca8ee2ef5236e2707e0fd5fecb10ce214aee1ff4ab307af9c558bda3b37/aiohttp-3.13.5-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:999802d5fa0389f58decd24b537c54aa63c01c3219ce17d1214cbda3c2b22d2d", size = 1557311, upload-time = "2026-03-31T21:58:39.38Z" }, + { url = "https://files.pythonhosted.org/packages/57/ae/76177b15f18c5f5d094f19901d284025db28eccc5ae374d1d254181d33f4/aiohttp-3.13.5-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ec707059ee75732b1ba130ed5f9580fe10ff75180c812bc267ded039db5128c6", size = 1773147, upload-time = "2026-03-31T21:58:41.476Z" }, + { url = "https://files.pythonhosted.org/packages/01/a4/62f05a0a98d88af59d93b7fcac564e5f18f513cb7471696ac286db970d6a/aiohttp-3.13.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2d6d44a5b48132053c2f6cd5c8cb14bc67e99a63594e336b0f2af81e94d5530c", size = 1730356, upload-time = "2026-03-31T21:58:44.049Z" }, + { url = "https://files.pythonhosted.org/packages/e4/85/fc8601f59dfa8c9523808281f2da571f8b4699685f9809a228adcc90838d/aiohttp-3.13.5-cp313-cp313-win32.whl", hash = "sha256:329f292ed14d38a6c4c435e465f48bebb47479fd676a0411936cc371643225cc", size = 432637, upload-time = "2026-03-31T21:58:46.167Z" }, + { url = "https://files.pythonhosted.org/packages/c0/1b/ac685a8882896acf0f6b31d689e3792199cfe7aba37969fa91da63a7fa27/aiohttp-3.13.5-cp313-cp313-win_amd64.whl", hash = "sha256:69f571de7500e0557801c0b51f4780482c0ec5fe2ac851af5a92cfce1af1cb83", size = 458896, upload-time = "2026-03-31T21:58:48.119Z" }, + { url = "https://files.pythonhosted.org/packages/5d/ce/46572759afc859e867a5bc8ec3487315869013f59281ce61764f76d879de/aiohttp-3.13.5-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:eb4639f32fd4a9904ab8fb45bf3383ba71137f3d9d4ba25b3b3f3109977c5b8c", size = 745721, upload-time = "2026-03-31T21:58:50.229Z" }, + { url = "https://files.pythonhosted.org/packages/13/fe/8a2efd7626dbe6049b2ef8ace18ffda8a4dfcbe1bcff3ac30c0c7575c20b/aiohttp-3.13.5-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:7e5dc4311bd5ac493886c63cbf76ab579dbe4641268e7c74e48e774c74b6f2be", size = 497663, upload-time = "2026-03-31T21:58:52.232Z" }, + { url = "https://files.pythonhosted.org/packages/9b/91/cc8cc78a111826c54743d88651e1687008133c37e5ee615fee9b57990fac/aiohttp-3.13.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:756c3c304d394977519824449600adaf2be0ccee76d206ee339c5e76b70ded25", size = 499094, upload-time = "2026-03-31T21:58:54.566Z" }, + { url = "https://files.pythonhosted.org/packages/0a/33/a8362cb15cf16a3af7e86ed11962d5cd7d59b449202dc576cdc731310bde/aiohttp-3.13.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecc26751323224cf8186efcf7fbcbc30f4e1d8c7970659daf25ad995e4032a56", size = 1726701, upload-time = "2026-03-31T21:58:56.864Z" }, + { url = "https://files.pythonhosted.org/packages/45/0c/c091ac5c3a17114bd76cbf85d674650969ddf93387876cf67f754204bd77/aiohttp-3.13.5-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:10a75acfcf794edf9d8db50e5a7ec5fc818b2a8d3f591ce93bc7b1210df016d2", size = 1683360, upload-time = "2026-03-31T21:58:59.072Z" }, + { url = "https://files.pythonhosted.org/packages/23/73/bcee1c2b79bc275e964d1446c55c54441a461938e70267c86afaae6fba27/aiohttp-3.13.5-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0f7a18f258d124cd678c5fe072fe4432a4d5232b0657fca7c1847f599233c83a", size = 1773023, upload-time = "2026-03-31T21:59:01.776Z" }, + { url = "https://files.pythonhosted.org/packages/c7/ef/720e639df03004fee2d869f771799d8c23046dec47d5b81e396c7cda583a/aiohttp-3.13.5-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:df6104c009713d3a89621096f3e3e88cc323fd269dbd7c20afe18535094320be", size = 1853795, upload-time = "2026-03-31T21:59:04.568Z" }, + { url = "https://files.pythonhosted.org/packages/bd/c9/989f4034fb46841208de7aeeac2c6d8300745ab4f28c42f629ba77c2d916/aiohttp-3.13.5-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:241a94f7de7c0c3b616627aaad530fe2cb620084a8b144d3be7b6ecfe95bae3b", size = 1730405, upload-time = "2026-03-31T21:59:07.221Z" }, + { url = "https://files.pythonhosted.org/packages/ce/75/ee1fd286ca7dc599d824b5651dad7b3be7ff8d9a7e7b3fe9820d9180f7db/aiohttp-3.13.5-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c974fb66180e58709b6fc402846f13791240d180b74de81d23913abe48e96d94", size = 1558082, upload-time = "2026-03-31T21:59:09.484Z" }, + { url = "https://files.pythonhosted.org/packages/c3/20/1e9e6650dfc436340116b7aa89ff8cb2bbdf0abc11dfaceaad8f74273a10/aiohttp-3.13.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:6e27ea05d184afac78aabbac667450c75e54e35f62238d44463131bd3f96753d", size = 1692346, upload-time = "2026-03-31T21:59:12.068Z" }, + { url = "https://files.pythonhosted.org/packages/d8/40/8ebc6658d48ea630ac7903912fe0dd4e262f0e16825aa4c833c56c9f1f56/aiohttp-3.13.5-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a79a6d399cef33a11b6f004c67bb07741d91f2be01b8d712d52c75711b1e07c7", size = 1698891, upload-time = "2026-03-31T21:59:14.552Z" }, + { url = "https://files.pythonhosted.org/packages/d8/78/ea0ae5ec8ba7a5c10bdd6e318f1ba5e76fcde17db8275188772afc7917a4/aiohttp-3.13.5-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:c632ce9c0b534fbe25b52c974515ed674937c5b99f549a92127c85f771a78772", size = 1742113, upload-time = "2026-03-31T21:59:17.068Z" }, + { url = "https://files.pythonhosted.org/packages/8a/66/9d308ed71e3f2491be1acb8769d96c6f0c47d92099f3bc9119cada27b357/aiohttp-3.13.5-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:fceedde51fbd67ee2bcc8c0b33d0126cc8b51ef3bbde2f86662bd6d5a6f10ec5", size = 1553088, upload-time = "2026-03-31T21:59:19.541Z" }, + { url = "https://files.pythonhosted.org/packages/da/a6/6cc25ed8dfc6e00c90f5c6d126a98e2cf28957ad06fa1036bd34b6f24a2c/aiohttp-3.13.5-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f92995dfec9420bb69ae629abf422e516923ba79ba4403bc750d94fb4a6c68c1", size = 1757976, upload-time = "2026-03-31T21:59:22.311Z" }, + { url = "https://files.pythonhosted.org/packages/c1/2b/cce5b0ffe0de99c83e5e36d8f828e4161e415660a9f3e58339d07cce3006/aiohttp-3.13.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:20ae0ff08b1f2c8788d6fb85afcb798654ae6ba0b747575f8562de738078457b", size = 1712444, upload-time = "2026-03-31T21:59:24.635Z" }, + { url = "https://files.pythonhosted.org/packages/6c/cf/9e1795b4160c58d29421eafd1a69c6ce351e2f7c8d3c6b7e4ca44aea1a5b/aiohttp-3.13.5-cp314-cp314-win32.whl", hash = "sha256:b20df693de16f42b2472a9c485e1c948ee55524786a0a34345511afdd22246f3", size = 438128, upload-time = "2026-03-31T21:59:27.291Z" }, + { url = "https://files.pythonhosted.org/packages/22/4d/eaedff67fc805aeba4ba746aec891b4b24cebb1a7d078084b6300f79d063/aiohttp-3.13.5-cp314-cp314-win_amd64.whl", hash = "sha256:f85c6f327bf0b8c29da7d93b1cabb6363fb5e4e160a32fa241ed2dce21b73162", size = 464029, upload-time = "2026-03-31T21:59:29.429Z" }, + { url = "https://files.pythonhosted.org/packages/79/11/c27d9332ee20d68dd164dc12a6ecdef2e2e35ecc97ed6cf0d2442844624b/aiohttp-3.13.5-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:1efb06900858bb618ff5cee184ae2de5828896c448403d51fb633f09e109be0a", size = 778758, upload-time = "2026-03-31T21:59:31.547Z" }, + { url = "https://files.pythonhosted.org/packages/04/fb/377aead2e0a3ba5f09b7624f702a964bdf4f08b5b6728a9799830c80041e/aiohttp-3.13.5-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:fee86b7c4bd29bdaf0d53d14739b08a106fdda809ca5fe032a15f52fae5fe254", size = 512883, upload-time = "2026-03-31T21:59:34.098Z" }, + { url = "https://files.pythonhosted.org/packages/bb/a6/aa109a33671f7a5d3bd78b46da9d852797c5e665bfda7d6b373f56bff2ec/aiohttp-3.13.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:20058e23909b9e65f9da62b396b77dfa95965cbe840f8def6e572538b1d32e36", size = 516668, upload-time = "2026-03-31T21:59:36.497Z" }, + { url = "https://files.pythonhosted.org/packages/79/b3/ca078f9f2fa9563c36fb8ef89053ea2bb146d6f792c5104574d49d8acb63/aiohttp-3.13.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cf20a8d6868cb15a73cab329ffc07291ba8c22b1b88176026106ae39aa6df0f", size = 1883461, upload-time = "2026-03-31T21:59:38.723Z" }, + { url = "https://files.pythonhosted.org/packages/b7/e3/a7ad633ca1ca497b852233a3cce6906a56c3225fb6d9217b5e5e60b7419d/aiohttp-3.13.5-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:330f5da04c987f1d5bdb8ae189137c77139f36bd1cb23779ca1a354a4b027800", size = 1747661, upload-time = "2026-03-31T21:59:41.187Z" }, + { url = "https://files.pythonhosted.org/packages/33/b9/cd6fe579bed34a906d3d783fe60f2fa297ef55b27bb4538438ee49d4dc41/aiohttp-3.13.5-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6f1cbf0c7926d315c3c26c2da41fd2b5d2fe01ac0e157b78caefc51a782196cf", size = 1863800, upload-time = "2026-03-31T21:59:43.84Z" }, + { url = "https://files.pythonhosted.org/packages/c0/3f/2c1e2f5144cefa889c8afd5cf431994c32f3b29da9961698ff4e3811b79a/aiohttp-3.13.5-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:53fc049ed6390d05423ba33103ded7281fe897cf97878f369a527070bd95795b", size = 1958382, upload-time = "2026-03-31T21:59:46.187Z" }, + { url = "https://files.pythonhosted.org/packages/66/1d/f31ec3f1013723b3babe3609e7f119c2c2fb6ef33da90061a705ef3e1bc8/aiohttp-3.13.5-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:898703aa2667e3c5ca4c54ca36cd73f58b7a38ef87a5606414799ebce4d3fd3a", size = 1803724, upload-time = "2026-03-31T21:59:48.656Z" }, + { url = "https://files.pythonhosted.org/packages/0e/b4/57712dfc6f1542f067daa81eb61da282fab3e6f1966fca25db06c4fc62d5/aiohttp-3.13.5-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0494a01ca9584eea1e5fbd6d748e61ecff218c51b576ee1999c23db7066417d8", size = 1640027, upload-time = "2026-03-31T21:59:51.284Z" }, + { url = "https://files.pythonhosted.org/packages/25/3c/734c878fb43ec083d8e31bf029daae1beafeae582d1b35da234739e82ee7/aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:6cf81fe010b8c17b09495cbd15c1d35afbc8fb405c0c9cf4738e5ae3af1d65be", size = 1806644, upload-time = "2026-03-31T21:59:53.753Z" }, + { url = "https://files.pythonhosted.org/packages/20/a5/f671e5cbec1c21d044ff3078223f949748f3a7f86b14e34a365d74a5d21f/aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:c564dd5f09ddc9d8f2c2d0a301cd30a79a2cc1b46dd1a73bef8f0038863d016b", size = 1791630, upload-time = "2026-03-31T21:59:56.239Z" }, + { url = "https://files.pythonhosted.org/packages/0b/63/fb8d0ad63a0b8a99be97deac8c04dacf0785721c158bdf23d679a87aa99e/aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:2994be9f6e51046c4f864598fd9abeb4fba6e88f0b2152422c9666dcd4aea9c6", size = 1809403, upload-time = "2026-03-31T21:59:59.103Z" }, + { url = "https://files.pythonhosted.org/packages/59/0c/bfed7f30662fcf12206481c2aac57dedee43fe1c49275e85b3a1e1742294/aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:157826e2fa245d2ef46c83ea8a5faf77ca19355d278d425c29fda0beb3318037", size = 1634924, upload-time = "2026-03-31T22:00:02.116Z" }, + { url = "https://files.pythonhosted.org/packages/17/d6/fd518d668a09fd5a3319ae5e984d4d80b9a4b3df4e21c52f02251ef5a32e/aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:a8aca50daa9493e9e13c0f566201a9006f080e7c50e5e90d0b06f53146a54500", size = 1836119, upload-time = "2026-03-31T22:00:04.756Z" }, + { url = "https://files.pythonhosted.org/packages/78/b7/15fb7a9d52e112a25b621c67b69c167805cb1f2ab8f1708a5c490d1b52fe/aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3b13560160d07e047a93f23aaa30718606493036253d5430887514715b67c9d9", size = 1772072, upload-time = "2026-03-31T22:00:07.494Z" }, + { url = "https://files.pythonhosted.org/packages/7e/df/57ba7f0c4a553fc2bd8b6321df236870ec6fd64a2a473a8a13d4f733214e/aiohttp-3.13.5-cp314-cp314t-win32.whl", hash = "sha256:9a0f4474b6ea6818b41f82172d799e4b3d29e22c2c520ce4357856fced9af2f8", size = 471819, upload-time = "2026-03-31T22:00:10.277Z" }, + { url = "https://files.pythonhosted.org/packages/62/29/2f8418269e46454a26171bfdd6a055d74febf32234e474930f2f60a17145/aiohttp-3.13.5-cp314-cp314t-win_amd64.whl", hash = "sha256:18a2f6c1182c51baa1d28d68fea51513cb2a76612f038853c0ad3c145423d3d9", size = 505441, upload-time = "2026-03-31T22:00:12.791Z" }, + { url = "https://files.pythonhosted.org/packages/e2/a5/630bc484695d4a1342bbae85fb8689bf979106525684fc88f05b397324ad/aiohttp-3.13.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:347542f0ea3f95b2a955ee6656461fa1c776e401ac50ebce055a6c38454a0adf", size = 752872, upload-time = "2026-03-31T22:00:15.553Z" }, + { url = "https://files.pythonhosted.org/packages/cd/b8/6a19dda37fda94a9ebefb3c1ae0ff419ac7fbf4fb40750e992829fc13614/aiohttp-3.13.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:178c7b5e62b454c2bc790786e6058c3cc968613b4419251b478c153a4aec32b1", size = 504582, upload-time = "2026-03-31T22:00:18.191Z" }, + { url = "https://files.pythonhosted.org/packages/d5/34/8413eafee3421ade2d6ce9e7c0da1213e1d7f0049be09dcdc342b03a39ba/aiohttp-3.13.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:af545c2cffdb0967a96b6249e6f5f7b0d92cdfd267f9d5238d5b9ca63e8edb10", size = 499094, upload-time = "2026-03-31T22:00:21.118Z" }, + { url = "https://files.pythonhosted.org/packages/da/cf/c6f97006093d1e8ca40fbab843ff49ec7725ab668f0714dd1cb702c62cbd/aiohttp-3.13.5-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:206b7b3ef96e4ce211754f0cd003feb28b7d81f0ad26b8d077a5d5161436067f", size = 1669505, upload-time = "2026-03-31T22:00:24.01Z" }, + { url = "https://files.pythonhosted.org/packages/c2/27/3b2288e66dcec8b04771b2bee3909f70e4072bea995cde5ab7e775e73ddc/aiohttp-3.13.5-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ee5e86776273de1795947d17bddd6bb19e0365fd2af4289c0d2c5454b6b1d36b", size = 1648928, upload-time = "2026-03-31T22:00:27.001Z" }, + { url = "https://files.pythonhosted.org/packages/3a/7f/605d766887594a88dcc27a19663499c7c5e13e7aa87f129b763765a2ee63/aiohttp-3.13.5-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:95d14ca7abefde230f7639ec136ade282655431fd5db03c343b19dda72dd1643", size = 1731800, upload-time = "2026-03-31T22:00:29.603Z" }, + { url = "https://files.pythonhosted.org/packages/71/94/5a878e728e30699d22b118f1a6ad576ab6fff9eb2c6fc8a7faa9376a1c3e/aiohttp-3.13.5-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:912d4b6af530ddb1338a66229dac3a25ff11d4448be3ec3d6340583995f56031", size = 1824247, upload-time = "2026-03-31T22:00:32.139Z" }, + { url = "https://files.pythonhosted.org/packages/37/99/84b448291e9996bb83bf4fad3a71a9786d542f19c50a3ff0531bfaba6fac/aiohttp-3.13.5-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e999f0c88a458c836d5fb521814e92ed2172c649200336a6df514987c1488258", size = 1670742, upload-time = "2026-03-31T22:00:34.788Z" }, + { url = "https://files.pythonhosted.org/packages/14/a8/d8d5d1ab6d29a4a3bdb9db31f161e338bfdf6638f6574ea8380f1d4a243c/aiohttp-3.13.5-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:39380e12bd1f2fdab4285b6e055ad48efbaed5c836433b142ed4f5b9be71036a", size = 1562474, upload-time = "2026-03-31T22:00:37.623Z" }, + { url = "https://files.pythonhosted.org/packages/92/e8/bd889697916f10b65524422c61b4eeaf919eb35a170290cccb680cbe4eb4/aiohttp-3.13.5-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:9efcc0f11d850cefcafdd9275b9576ad3bfb539bed96807663b32ad99c4d4b88", size = 1642235, upload-time = "2026-03-31T22:00:40.541Z" }, + { url = "https://files.pythonhosted.org/packages/60/42/3f1928107131f1413a5972ace14ddcd5364968e9bd7b3ad71272defafc9c/aiohttp-3.13.5-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:147b4f501d0292077f29d5268c16bb7c864a1f054d7001c4c1812c0421ea1ed0", size = 1655397, upload-time = "2026-03-31T22:00:43.167Z" }, + { url = "https://files.pythonhosted.org/packages/b2/79/c4bbcf4cac3a4715a326e49720ccdc3a4b5e14a367c5029eae7727d06029/aiohttp-3.13.5-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:d147004fede1b12f6013a6dbb2a26a986a671a03c6ea740ddc76500e5f1c399f", size = 1703509, upload-time = "2026-03-31T22:00:45.908Z" }, + { url = "https://files.pythonhosted.org/packages/d1/e6/32d245876f211a7308a7d5437707f9296b1f9837a2888a407ed04e61321c/aiohttp-3.13.5-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:9277145d36a01653863899c665243871434694bcc3431922c3b35c978061bdb8", size = 1550098, upload-time = "2026-03-31T22:00:49.48Z" }, + { url = "https://files.pythonhosted.org/packages/db/62/ab0f1304def56ce2356e6fbb9f0b024d6544010351430070f48f53b89e0a/aiohttp-3.13.5-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4e704c52438f66fdd89588346183d898bb42167cf88f8b7ff1c0f9fc957c348f", size = 1724326, upload-time = "2026-03-31T22:00:52.165Z" }, + { url = "https://files.pythonhosted.org/packages/c4/9a/aab4469689024046220ea438aa020ea2ae04cd1dd71aea3057e094f8c357/aiohttp-3.13.5-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a8a4d3427e8de1312ddf309cc482186466c79895b3a139fed3259fc01dfa9a5b", size = 1658824, upload-time = "2026-03-31T22:00:55.122Z" }, + { url = "https://files.pythonhosted.org/packages/b0/98/bcc35d4db687acabf06d41f561a99fa88bca145292513388c858d99b72c5/aiohttp-3.13.5-cp39-cp39-win32.whl", hash = "sha256:6f497a6876aa4b1a102b04996ce4c1170c7040d83faa9387dd921c16e30d5c83", size = 440302, upload-time = "2026-03-31T22:00:57.673Z" }, + { url = "https://files.pythonhosted.org/packages/25/61/b0203c2ef6bd268fca0eda142f0efbba7cbebd7ad38f7bb01dd31c2ff68e/aiohttp-3.13.5-cp39-cp39-win_amd64.whl", hash = "sha256:cb979826071c0986a5f08333a36104153478ce6018c58cba7f9caddaf63d5d67", size = 463076, upload-time = "2026-03-31T22:01:00.264Z" }, +] + +[[package]] +name = "aiosignal" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "frozenlist" }, + { name = "typing-extensions", marker = "python_full_version < '3.13' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007, upload-time = "2025-07-03T22:54:43.528Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" }, +] + +[[package]] +name = "annotated-types" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, +] + +[[package]] +name = "anyio" +version = "4.12.1" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.10'", +] +dependencies = [ + { name = "exceptiongroup", marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "idna", marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "typing-extensions", marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/96/f0/5eb65b2bb0d09ac6776f2eb54adee6abe8228ea05b20a5ad0e4945de8aac/anyio-4.12.1.tar.gz", hash = "sha256:41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703", size = 228685, upload-time = "2026-01-06T11:45:21.246Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl", hash = "sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c", size = 113592, upload-time = "2026-01-06T11:45:19.497Z" }, +] + +[[package]] +name = "anyio" +version = "4.13.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14' and extra != 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and python_full_version < '3.14' and extra != 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and extra == 'group-10-cloudflare-pydantic-v1' and extra != 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and extra != 'group-10-cloudflare-pydantic-v1' and extra != 'group-10-cloudflare-pydantic-v2'", +] +dependencies = [ + { name = "exceptiongroup", marker = "python_full_version == '3.10.*' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "idna", marker = "python_full_version >= '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "typing-extensions", marker = "(python_full_version >= '3.10' and python_full_version < '3.13') or (python_full_version < '3.10' and extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2') or (python_full_version >= '3.13' and extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/14/2c5dd9f512b66549ae92767a9c7b330ae88e1932ca57876909410251fe13/anyio-4.13.0.tar.gz", hash = "sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc", size = 231622, upload-time = "2026-03-24T12:59:09.671Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl", hash = "sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708", size = 114353, upload-time = "2026-03-24T12:59:08.246Z" }, +] + +[[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 = "26.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9a/8e/82a0fe20a541c03148528be8cac2408564a6c9a0cc7e9171802bc1d26985/attrs-26.1.0.tar.gz", hash = "sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32", size = 952055, upload-time = "2026-03-19T14:22:25.026Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl", hash = "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309", size = 67548, upload-time = "2026-03-19T14:22:23.645Z" }, +] + +[[package]] +name = "backports-asyncio-runner" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/ff/70dca7d7cb1cbc0edb2c6cc0c38b65cba36cccc491eca64cabd5fe7f8670/backports_asyncio_runner-1.2.0.tar.gz", hash = "sha256:a5aa7b2b7d8f8bfcaa2b57313f70792df84e32a2a746f585213373f900b42162", size = 69893, upload-time = "2025-07-02T02:27:15.685Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/59/76ab57e3fe74484f48a53f8e337171b4a2349e506eabe136d7e01d059086/backports_asyncio_runner-1.2.0-py3-none-any.whl", hash = "sha256:0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5", size = 12313, upload-time = "2025-07-02T02:27:14.263Z" }, +] + +[[package]] +name = "certifi" +version = "2026.4.22" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/25/ee/6caf7a40c36a1220410afe15a1cc64993a1f864871f698c0f93acb72842a/certifi-2026.4.22.tar.gz", hash = "sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580", size = 137077, upload-time = "2026-04-22T11:26:11.191Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/30/7cd8fdcdfbc5b869528b079bfb76dcdf6056b1a2097a662e5e8c04f42965/certifi-2026.4.22-py3-none-any.whl", hash = "sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a", size = 135707, upload-time = "2026-04-22T11:26:09.372Z" }, +] + +[[package]] +name = "cloudflare" +version = "5.0.0b2" +source = { editable = "." } +dependencies = [ + { name = "anyio", version = "4.12.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "anyio", version = "4.13.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "distro" }, + { name = "httpx" }, + { name = "pydantic", version = "1.10.26", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'group-10-cloudflare-pydantic-v1'" }, + { name = "pydantic", version = "2.13.3", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'group-10-cloudflare-pydantic-v2' or extra != 'group-10-cloudflare-pydantic-v1'" }, + { name = "sniffio" }, + { name = "typing-extensions" }, +] + +[package.optional-dependencies] +aiohttp = [ + { name = "aiohttp" }, + { name = "httpx-aiohttp" }, +] + +[package.dev-dependencies] +dev = [ + { name = "dirty-equals" }, + { name = "griffe", version = "1.14.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "griffe", version = "2.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "importlib-metadata", version = "8.7.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "importlib-metadata", version = "9.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "mypy" }, + { name = "pyright" }, + { name = "pytest", version = "8.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "pytest", version = "9.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "pytest-asyncio", version = "1.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "pytest-asyncio", version = "1.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "pytest-xdist" }, + { name = "respx" }, + { name = "rich" }, + { name = "ruff" }, + { name = "time-machine", version = "2.19.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "time-machine", version = "3.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, +] +pydantic-v1 = [ + { name = "pydantic", version = "1.10.26", source = { registry = "https://pypi.org/simple" } }, +] +pydantic-v2 = [ + { name = "pydantic", version = "2.13.3", source = { registry = "https://pypi.org/simple" } }, +] + +[package.metadata] +requires-dist = [ + { name = "aiohttp", marker = "extra == 'aiohttp'" }, + { name = "anyio", specifier = ">=3.5.0,<5" }, + { name = "distro", specifier = ">=1.7.0,<2" }, + { name = "httpx", specifier = ">=0.23.0,<1" }, + { name = "httpx-aiohttp", marker = "extra == 'aiohttp'", specifier = ">=0.1.9" }, + { name = "pydantic", specifier = ">=1.9.0,<3" }, + { name = "sniffio" }, + { name = "typing-extensions", specifier = ">=4.14,<5" }, +] +provides-extras = ["aiohttp"] + +[package.metadata.requires-dev] +dev = [ + { name = "dirty-equals", specifier = ">=0.6.0" }, + { name = "griffe", specifier = ">=1" }, + { name = "importlib-metadata", specifier = ">=6.7.0" }, + { name = "mypy", specifier = "==1.17" }, + { name = "pyright", specifier = "==1.1.399" }, + { name = "pytest" }, + { name = "pytest-asyncio" }, + { name = "pytest-xdist", specifier = ">=3.6.1" }, + { name = "respx" }, + { name = "rich", specifier = ">=13.7.1" }, + { name = "ruff" }, + { name = "time-machine" }, +] +pydantic-v1 = [{ name = "pydantic", specifier = ">=1.9.0,<2" }] +pydantic-v2 = [ + { name = "pydantic", marker = "python_full_version < '3.14'", specifier = "~=2.0" }, + { name = "pydantic", marker = "python_full_version >= '3.14'", specifier = "~=2.12" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "dirty-equals" +version = "0.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/30/1d/c5913ac9d6615515a00f4bdc71356d302437cb74ff2e9aaccd3c14493b78/dirty_equals-0.11.tar.gz", hash = "sha256:f4ac74ee88f2d11e2fa0f65eb30ee4f07105c5f86f4dc92b09eb1138775027c3", size = 128067, upload-time = "2025-11-17T01:51:24.451Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bb/8d/dbff05239043271dbeace563a7686212a3dd517864a35623fe4d4a64ca19/dirty_equals-0.11-py3-none-any.whl", hash = "sha256:b1d7093273fc2f9be12f443a8ead954ef6daaf6746fd42ef3a5616433ee85286", size = 28051, upload-time = "2025-11-17T01:51:22.849Z" }, +] + +[[package]] +name = "distro" +version = "1.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", size = 60722, upload-time = "2023-12-24T09:54:32.31Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277, upload-time = "2023-12-24T09:54:30.421Z" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.13' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, +] + +[[package]] +name = "execnet" +version = "2.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bf/89/780e11f9588d9e7128a3f87788354c7946a9cbb1401ad38a48c4db9a4f07/execnet-2.1.2.tar.gz", hash = "sha256:63d83bfdd9a23e35b9c6a3261412324f964c2ec8dcd8d3c6916ee9373e0befcd", size = 166622, upload-time = "2025-11-12T09:56:37.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl", hash = "sha256:67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec", size = 40708, upload-time = "2025-11-12T09:56:36.333Z" }, +] + +[[package]] +name = "frozenlist" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2d/f5/c831fac6cc817d26fd54c7eaccd04ef7e0288806943f7cc5bbf69f3ac1f0/frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad", size = 45875, upload-time = "2025-10-06T05:38:17.865Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/83/4a/557715d5047da48d54e659203b9335be7bfaafda2c3f627b7c47e0b3aaf3/frozenlist-1.8.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b37f6d31b3dcea7deb5e9696e529a6aa4a898adc33db82da12e4c60a7c4d2011", size = 86230, upload-time = "2025-10-06T05:35:23.699Z" }, + { url = "https://files.pythonhosted.org/packages/a2/fb/c85f9fed3ea8fe8740e5b46a59cc141c23b842eca617da8876cfce5f760e/frozenlist-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ef2b7b394f208233e471abc541cc6991f907ffd47dc72584acee3147899d6565", size = 49621, upload-time = "2025-10-06T05:35:25.341Z" }, + { url = "https://files.pythonhosted.org/packages/63/70/26ca3f06aace16f2352796b08704338d74b6d1a24ca38f2771afbb7ed915/frozenlist-1.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a88f062f072d1589b7b46e951698950e7da00442fc1cacbe17e19e025dc327ad", size = 49889, upload-time = "2025-10-06T05:35:26.797Z" }, + { url = "https://files.pythonhosted.org/packages/5d/ed/c7895fd2fde7f3ee70d248175f9b6cdf792fb741ab92dc59cd9ef3bd241b/frozenlist-1.8.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f57fb59d9f385710aa7060e89410aeb5058b99e62f4d16b08b91986b9a2140c2", size = 219464, upload-time = "2025-10-06T05:35:28.254Z" }, + { url = "https://files.pythonhosted.org/packages/6b/83/4d587dccbfca74cb8b810472392ad62bfa100bf8108c7223eb4c4fa2f7b3/frozenlist-1.8.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:799345ab092bee59f01a915620b5d014698547afd011e691a208637312db9186", size = 221649, upload-time = "2025-10-06T05:35:29.454Z" }, + { url = "https://files.pythonhosted.org/packages/6a/c6/fd3b9cd046ec5fff9dab66831083bc2077006a874a2d3d9247dea93ddf7e/frozenlist-1.8.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c23c3ff005322a6e16f71bf8692fcf4d5a304aaafe1e262c98c6d4adc7be863e", size = 219188, upload-time = "2025-10-06T05:35:30.951Z" }, + { url = "https://files.pythonhosted.org/packages/ce/80/6693f55eb2e085fc8afb28cf611448fb5b90e98e068fa1d1b8d8e66e5c7d/frozenlist-1.8.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8a76ea0f0b9dfa06f254ee06053d93a600865b3274358ca48a352ce4f0798450", size = 231748, upload-time = "2025-10-06T05:35:32.101Z" }, + { url = "https://files.pythonhosted.org/packages/97/d6/e9459f7c5183854abd989ba384fe0cc1a0fb795a83c033f0571ec5933ca4/frozenlist-1.8.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c7366fe1418a6133d5aa824ee53d406550110984de7637d65a178010f759c6ef", size = 236351, upload-time = "2025-10-06T05:35:33.834Z" }, + { url = "https://files.pythonhosted.org/packages/97/92/24e97474b65c0262e9ecd076e826bfd1d3074adcc165a256e42e7b8a7249/frozenlist-1.8.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:13d23a45c4cebade99340c4165bd90eeb4a56c6d8a9d8aa49568cac19a6d0dc4", size = 218767, upload-time = "2025-10-06T05:35:35.205Z" }, + { url = "https://files.pythonhosted.org/packages/ee/bf/dc394a097508f15abff383c5108cb8ad880d1f64a725ed3b90d5c2fbf0bb/frozenlist-1.8.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:e4a3408834f65da56c83528fb52ce7911484f0d1eaf7b761fc66001db1646eff", size = 235887, upload-time = "2025-10-06T05:35:36.354Z" }, + { url = "https://files.pythonhosted.org/packages/40/90/25b201b9c015dbc999a5baf475a257010471a1fa8c200c843fd4abbee725/frozenlist-1.8.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:42145cd2748ca39f32801dad54aeea10039da6f86e303659db90db1c4b614c8c", size = 228785, upload-time = "2025-10-06T05:35:37.949Z" }, + { url = "https://files.pythonhosted.org/packages/84/f4/b5bc148df03082f05d2dd30c089e269acdbe251ac9a9cf4e727b2dbb8a3d/frozenlist-1.8.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:e2de870d16a7a53901e41b64ffdf26f2fbb8917b3e6ebf398098d72c5b20bd7f", size = 230312, upload-time = "2025-10-06T05:35:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/db/4b/87e95b5d15097c302430e647136b7d7ab2398a702390cf4c8601975709e7/frozenlist-1.8.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:20e63c9493d33ee48536600d1a5c95eefc870cd71e7ab037763d1fbb89cc51e7", size = 217650, upload-time = "2025-10-06T05:35:40.377Z" }, + { url = "https://files.pythonhosted.org/packages/e5/70/78a0315d1fea97120591a83e0acd644da638c872f142fd72a6cebee825f3/frozenlist-1.8.0-cp310-cp310-win32.whl", hash = "sha256:adbeebaebae3526afc3c96fad434367cafbfd1b25d72369a9e5858453b1bb71a", size = 39659, upload-time = "2025-10-06T05:35:41.863Z" }, + { url = "https://files.pythonhosted.org/packages/66/aa/3f04523fb189a00e147e60c5b2205126118f216b0aa908035c45336e27e4/frozenlist-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:667c3777ca571e5dbeb76f331562ff98b957431df140b54c85fd4d52eea8d8f6", size = 43837, upload-time = "2025-10-06T05:35:43.205Z" }, + { url = "https://files.pythonhosted.org/packages/39/75/1135feecdd7c336938bd55b4dc3b0dfc46d85b9be12ef2628574b28de776/frozenlist-1.8.0-cp310-cp310-win_arm64.whl", hash = "sha256:80f85f0a7cc86e7a54c46d99c9e1318ff01f4687c172ede30fd52d19d1da1c8e", size = 39989, upload-time = "2025-10-06T05:35:44.596Z" }, + { url = "https://files.pythonhosted.org/packages/bc/03/077f869d540370db12165c0aa51640a873fb661d8b315d1d4d67b284d7ac/frozenlist-1.8.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:09474e9831bc2b2199fad6da3c14c7b0fbdd377cce9d3d77131be28906cb7d84", size = 86912, upload-time = "2025-10-06T05:35:45.98Z" }, + { url = "https://files.pythonhosted.org/packages/df/b5/7610b6bd13e4ae77b96ba85abea1c8cb249683217ef09ac9e0ae93f25a91/frozenlist-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:17c883ab0ab67200b5f964d2b9ed6b00971917d5d8a92df149dc2c9779208ee9", size = 50046, upload-time = "2025-10-06T05:35:47.009Z" }, + { url = "https://files.pythonhosted.org/packages/6e/ef/0e8f1fe32f8a53dd26bdd1f9347efe0778b0fddf62789ea683f4cc7d787d/frozenlist-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fa47e444b8ba08fffd1c18e8cdb9a75db1b6a27f17507522834ad13ed5922b93", size = 50119, upload-time = "2025-10-06T05:35:48.38Z" }, + { url = "https://files.pythonhosted.org/packages/11/b1/71a477adc7c36e5fb628245dfbdea2166feae310757dea848d02bd0689fd/frozenlist-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2552f44204b744fba866e573be4c1f9048d6a324dfe14475103fd51613eb1d1f", size = 231067, upload-time = "2025-10-06T05:35:49.97Z" }, + { url = "https://files.pythonhosted.org/packages/45/7e/afe40eca3a2dc19b9904c0f5d7edfe82b5304cb831391edec0ac04af94c2/frozenlist-1.8.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:957e7c38f250991e48a9a73e6423db1bb9dd14e722a10f6b8bb8e16a0f55f695", size = 233160, upload-time = "2025-10-06T05:35:51.729Z" }, + { url = "https://files.pythonhosted.org/packages/a6/aa/7416eac95603ce428679d273255ffc7c998d4132cfae200103f164b108aa/frozenlist-1.8.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8585e3bb2cdea02fc88ffa245069c36555557ad3609e83be0ec71f54fd4abb52", size = 228544, upload-time = "2025-10-06T05:35:53.246Z" }, + { url = "https://files.pythonhosted.org/packages/8b/3d/2a2d1f683d55ac7e3875e4263d28410063e738384d3adc294f5ff3d7105e/frozenlist-1.8.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:edee74874ce20a373d62dc28b0b18b93f645633c2943fd90ee9d898550770581", size = 243797, upload-time = "2025-10-06T05:35:54.497Z" }, + { url = "https://files.pythonhosted.org/packages/78/1e/2d5565b589e580c296d3bb54da08d206e797d941a83a6fdea42af23be79c/frozenlist-1.8.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c9a63152fe95756b85f31186bddf42e4c02c6321207fd6601a1c89ebac4fe567", size = 247923, upload-time = "2025-10-06T05:35:55.861Z" }, + { url = "https://files.pythonhosted.org/packages/aa/c3/65872fcf1d326a7f101ad4d86285c403c87be7d832b7470b77f6d2ed5ddc/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b6db2185db9be0a04fecf2f241c70b63b1a242e2805be291855078f2b404dd6b", size = 230886, upload-time = "2025-10-06T05:35:57.399Z" }, + { url = "https://files.pythonhosted.org/packages/a0/76/ac9ced601d62f6956f03cc794f9e04c81719509f85255abf96e2510f4265/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:f4be2e3d8bc8aabd566f8d5b8ba7ecc09249d74ba3c9ed52e54dc23a293f0b92", size = 245731, upload-time = "2025-10-06T05:35:58.563Z" }, + { url = "https://files.pythonhosted.org/packages/b9/49/ecccb5f2598daf0b4a1415497eba4c33c1e8ce07495eb07d2860c731b8d5/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c8d1634419f39ea6f5c427ea2f90ca85126b54b50837f31497f3bf38266e853d", size = 241544, upload-time = "2025-10-06T05:35:59.719Z" }, + { url = "https://files.pythonhosted.org/packages/53/4b/ddf24113323c0bbcc54cb38c8b8916f1da7165e07b8e24a717b4a12cbf10/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:1a7fa382a4a223773ed64242dbe1c9c326ec09457e6b8428efb4118c685c3dfd", size = 241806, upload-time = "2025-10-06T05:36:00.959Z" }, + { url = "https://files.pythonhosted.org/packages/a7/fb/9b9a084d73c67175484ba2789a59f8eebebd0827d186a8102005ce41e1ba/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:11847b53d722050808926e785df837353bd4d75f1d494377e59b23594d834967", size = 229382, upload-time = "2025-10-06T05:36:02.22Z" }, + { url = "https://files.pythonhosted.org/packages/95/a3/c8fb25aac55bf5e12dae5c5aa6a98f85d436c1dc658f21c3ac73f9fa95e5/frozenlist-1.8.0-cp311-cp311-win32.whl", hash = "sha256:27c6e8077956cf73eadd514be8fb04d77fc946a7fe9f7fe167648b0b9085cc25", size = 39647, upload-time = "2025-10-06T05:36:03.409Z" }, + { url = "https://files.pythonhosted.org/packages/0a/f5/603d0d6a02cfd4c8f2a095a54672b3cf967ad688a60fb9faf04fc4887f65/frozenlist-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:ac913f8403b36a2c8610bbfd25b8013488533e71e62b4b4adce9c86c8cea905b", size = 44064, upload-time = "2025-10-06T05:36:04.368Z" }, + { url = "https://files.pythonhosted.org/packages/5d/16/c2c9ab44e181f043a86f9a8f84d5124b62dbcb3a02c0977ec72b9ac1d3e0/frozenlist-1.8.0-cp311-cp311-win_arm64.whl", hash = "sha256:d4d3214a0f8394edfa3e303136d0575eece0745ff2b47bd2cb2e66dd92d4351a", size = 39937, upload-time = "2025-10-06T05:36:05.669Z" }, + { url = "https://files.pythonhosted.org/packages/69/29/948b9aa87e75820a38650af445d2ef2b6b8a6fab1a23b6bb9e4ef0be2d59/frozenlist-1.8.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:78f7b9e5d6f2fdb88cdde9440dc147259b62b9d3b019924def9f6478be254ac1", size = 87782, upload-time = "2025-10-06T05:36:06.649Z" }, + { url = "https://files.pythonhosted.org/packages/64/80/4f6e318ee2a7c0750ed724fa33a4bdf1eacdc5a39a7a24e818a773cd91af/frozenlist-1.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:229bf37d2e4acdaf808fd3f06e854a4a7a3661e871b10dc1f8f1896a3b05f18b", size = 50594, upload-time = "2025-10-06T05:36:07.69Z" }, + { url = "https://files.pythonhosted.org/packages/2b/94/5c8a2b50a496b11dd519f4a24cb5496cf125681dd99e94c604ccdea9419a/frozenlist-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f833670942247a14eafbb675458b4e61c82e002a148f49e68257b79296e865c4", size = 50448, upload-time = "2025-10-06T05:36:08.78Z" }, + { url = "https://files.pythonhosted.org/packages/6a/bd/d91c5e39f490a49df14320f4e8c80161cfcce09f1e2cde1edd16a551abb3/frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:494a5952b1c597ba44e0e78113a7266e656b9794eec897b19ead706bd7074383", size = 242411, upload-time = "2025-10-06T05:36:09.801Z" }, + { url = "https://files.pythonhosted.org/packages/8f/83/f61505a05109ef3293dfb1ff594d13d64a2324ac3482be2cedc2be818256/frozenlist-1.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96f423a119f4777a4a056b66ce11527366a8bb92f54e541ade21f2374433f6d4", size = 243014, upload-time = "2025-10-06T05:36:11.394Z" }, + { url = "https://files.pythonhosted.org/packages/d8/cb/cb6c7b0f7d4023ddda30cf56b8b17494eb3a79e3fda666bf735f63118b35/frozenlist-1.8.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3462dd9475af2025c31cc61be6652dfa25cbfb56cbbf52f4ccfe029f38decaf8", size = 234909, upload-time = "2025-10-06T05:36:12.598Z" }, + { url = "https://files.pythonhosted.org/packages/31/c5/cd7a1f3b8b34af009fb17d4123c5a778b44ae2804e3ad6b86204255f9ec5/frozenlist-1.8.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4c800524c9cd9bac5166cd6f55285957fcfc907db323e193f2afcd4d9abd69b", size = 250049, upload-time = "2025-10-06T05:36:14.065Z" }, + { url = "https://files.pythonhosted.org/packages/c0/01/2f95d3b416c584a1e7f0e1d6d31998c4a795f7544069ee2e0962a4b60740/frozenlist-1.8.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d6a5df73acd3399d893dafc71663ad22534b5aa4f94e8a2fabfe856c3c1b6a52", size = 256485, upload-time = "2025-10-06T05:36:15.39Z" }, + { url = "https://files.pythonhosted.org/packages/ce/03/024bf7720b3abaebcff6d0793d73c154237b85bdf67b7ed55e5e9596dc9a/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:405e8fe955c2280ce66428b3ca55e12b3c4e9c336fb2103a4937e891c69a4a29", size = 237619, upload-time = "2025-10-06T05:36:16.558Z" }, + { url = "https://files.pythonhosted.org/packages/69/fa/f8abdfe7d76b731f5d8bd217827cf6764d4f1d9763407e42717b4bed50a0/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:908bd3f6439f2fef9e85031b59fd4f1297af54415fb60e4254a95f75b3cab3f3", size = 250320, upload-time = "2025-10-06T05:36:17.821Z" }, + { url = "https://files.pythonhosted.org/packages/f5/3c/b051329f718b463b22613e269ad72138cc256c540f78a6de89452803a47d/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:294e487f9ec720bd8ffcebc99d575f7eff3568a08a253d1ee1a0378754b74143", size = 246820, upload-time = "2025-10-06T05:36:19.046Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ae/58282e8f98e444b3f4dd42448ff36fa38bef29e40d40f330b22e7108f565/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:74c51543498289c0c43656701be6b077f4b265868fa7f8a8859c197006efb608", size = 250518, upload-time = "2025-10-06T05:36:20.763Z" }, + { url = "https://files.pythonhosted.org/packages/8f/96/007e5944694d66123183845a106547a15944fbbb7154788cbf7272789536/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:776f352e8329135506a1d6bf16ac3f87bc25b28e765949282dcc627af36123aa", size = 239096, upload-time = "2025-10-06T05:36:22.129Z" }, + { url = "https://files.pythonhosted.org/packages/66/bb/852b9d6db2fa40be96f29c0d1205c306288f0684df8fd26ca1951d461a56/frozenlist-1.8.0-cp312-cp312-win32.whl", hash = "sha256:433403ae80709741ce34038da08511d4a77062aa924baf411ef73d1146e74faf", size = 39985, upload-time = "2025-10-06T05:36:23.661Z" }, + { url = "https://files.pythonhosted.org/packages/b8/af/38e51a553dd66eb064cdf193841f16f077585d4d28394c2fa6235cb41765/frozenlist-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:34187385b08f866104f0c0617404c8eb08165ab1272e884abc89c112e9c00746", size = 44591, upload-time = "2025-10-06T05:36:24.958Z" }, + { url = "https://files.pythonhosted.org/packages/a7/06/1dc65480ab147339fecc70797e9c2f69d9cea9cf38934ce08df070fdb9cb/frozenlist-1.8.0-cp312-cp312-win_arm64.whl", hash = "sha256:fe3c58d2f5db5fbd18c2987cba06d51b0529f52bc3a6cdc33d3f4eab725104bd", size = 40102, upload-time = "2025-10-06T05:36:26.333Z" }, + { url = "https://files.pythonhosted.org/packages/2d/40/0832c31a37d60f60ed79e9dfb5a92e1e2af4f40a16a29abcc7992af9edff/frozenlist-1.8.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8d92f1a84bb12d9e56f818b3a746f3efba93c1b63c8387a73dde655e1e42282a", size = 85717, upload-time = "2025-10-06T05:36:27.341Z" }, + { url = "https://files.pythonhosted.org/packages/30/ba/b0b3de23f40bc55a7057bd38434e25c34fa48e17f20ee273bbde5e0650f3/frozenlist-1.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96153e77a591c8adc2ee805756c61f59fef4cf4073a9275ee86fe8cba41241f7", size = 49651, upload-time = "2025-10-06T05:36:28.855Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f21f00a91358803399890ab167098c131ec2ddd5f8f5fd5fe9c9f2c6fcd91e40", size = 49417, upload-time = "2025-10-06T05:36:29.877Z" }, + { url = "https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fb30f9626572a76dfe4293c7194a09fb1fe93ba94c7d4f720dfae3b646b45027", size = 234391, upload-time = "2025-10-06T05:36:31.301Z" }, + { url = "https://files.pythonhosted.org/packages/40/76/c202df58e3acdf12969a7895fd6f3bc016c642e6726aa63bd3025e0fc71c/frozenlist-1.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaa352d7047a31d87dafcacbabe89df0aa506abb5b1b85a2fb91bc3faa02d822", size = 233048, upload-time = "2025-10-06T05:36:32.531Z" }, + { url = "https://files.pythonhosted.org/packages/f9/c0/8746afb90f17b73ca5979c7a3958116e105ff796e718575175319b5bb4ce/frozenlist-1.8.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:03ae967b4e297f58f8c774c7eabcce57fe3c2434817d4385c50661845a058121", size = 226549, upload-time = "2025-10-06T05:36:33.706Z" }, + { url = "https://files.pythonhosted.org/packages/7e/eb/4c7eefc718ff72f9b6c4893291abaae5fbc0c82226a32dcd8ef4f7a5dbef/frozenlist-1.8.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f6292f1de555ffcc675941d65fffffb0a5bcd992905015f85d0592201793e0e5", size = 239833, upload-time = "2025-10-06T05:36:34.947Z" }, + { url = "https://files.pythonhosted.org/packages/c2/4e/e5c02187cf704224f8b21bee886f3d713ca379535f16893233b9d672ea71/frozenlist-1.8.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29548f9b5b5e3460ce7378144c3010363d8035cea44bc0bf02d57f5a685e084e", size = 245363, upload-time = "2025-10-06T05:36:36.534Z" }, + { url = "https://files.pythonhosted.org/packages/1f/96/cb85ec608464472e82ad37a17f844889c36100eed57bea094518bf270692/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ec3cc8c5d4084591b4237c0a272cc4f50a5b03396a47d9caaf76f5d7b38a4f11", size = 229314, upload-time = "2025-10-06T05:36:38.582Z" }, + { url = "https://files.pythonhosted.org/packages/5d/6f/4ae69c550e4cee66b57887daeebe006fe985917c01d0fff9caab9883f6d0/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:517279f58009d0b1f2e7c1b130b377a349405da3f7621ed6bfae50b10adf20c1", size = 243365, upload-time = "2025-10-06T05:36:40.152Z" }, + { url = "https://files.pythonhosted.org/packages/7a/58/afd56de246cf11780a40a2c28dc7cbabbf06337cc8ddb1c780a2d97e88d8/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:db1e72ede2d0d7ccb213f218df6a078a9c09a7de257c2fe8fcef16d5925230b1", size = 237763, upload-time = "2025-10-06T05:36:41.355Z" }, + { url = "https://files.pythonhosted.org/packages/cb/36/cdfaf6ed42e2644740d4a10452d8e97fa1c062e2a8006e4b09f1b5fd7d63/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b4dec9482a65c54a5044486847b8a66bf10c9cb4926d42927ec4e8fd5db7fed8", size = 240110, upload-time = "2025-10-06T05:36:42.716Z" }, + { url = "https://files.pythonhosted.org/packages/03/a8/9ea226fbefad669f11b52e864c55f0bd57d3c8d7eb07e9f2e9a0b39502e1/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:21900c48ae04d13d416f0e1e0c4d81f7931f73a9dfa0b7a8746fb2fe7dd970ed", size = 233717, upload-time = "2025-10-06T05:36:44.251Z" }, + { url = "https://files.pythonhosted.org/packages/1e/0b/1b5531611e83ba7d13ccc9988967ea1b51186af64c42b7a7af465dcc9568/frozenlist-1.8.0-cp313-cp313-win32.whl", hash = "sha256:8b7b94a067d1c504ee0b16def57ad5738701e4ba10cec90529f13fa03c833496", size = 39628, upload-time = "2025-10-06T05:36:45.423Z" }, + { url = "https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:878be833caa6a3821caf85eb39c5ba92d28e85df26d57afb06b35b2efd937231", size = 43882, upload-time = "2025-10-06T05:36:46.796Z" }, + { url = "https://files.pythonhosted.org/packages/c1/17/502cd212cbfa96eb1388614fe39a3fc9ab87dbbe042b66f97acb57474834/frozenlist-1.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:44389d135b3ff43ba8cc89ff7f51f5a0bb6b63d829c8300f79a2fe4fe61bcc62", size = 39676, upload-time = "2025-10-06T05:36:47.8Z" }, + { url = "https://files.pythonhosted.org/packages/d2/5c/3bbfaa920dfab09e76946a5d2833a7cbdf7b9b4a91c714666ac4855b88b4/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:e25ac20a2ef37e91c1b39938b591457666a0fa835c7783c3a8f33ea42870db94", size = 89235, upload-time = "2025-10-06T05:36:48.78Z" }, + { url = "https://files.pythonhosted.org/packages/d2/d6/f03961ef72166cec1687e84e8925838442b615bd0b8854b54923ce5b7b8a/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07cdca25a91a4386d2e76ad992916a85038a9b97561bf7a3fd12d5d9ce31870c", size = 50742, upload-time = "2025-10-06T05:36:49.837Z" }, + { url = "https://files.pythonhosted.org/packages/1e/bb/a6d12b7ba4c3337667d0e421f7181c82dda448ce4e7ad7ecd249a16fa806/frozenlist-1.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4e0c11f2cc6717e0a741f84a527c52616140741cd812a50422f83dc31749fb52", size = 51725, upload-time = "2025-10-06T05:36:50.851Z" }, + { url = "https://files.pythonhosted.org/packages/bc/71/d1fed0ffe2c2ccd70b43714c6cab0f4188f09f8a67a7914a6b46ee30f274/frozenlist-1.8.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b3210649ee28062ea6099cfda39e147fa1bc039583c8ee4481cb7811e2448c51", size = 284533, upload-time = "2025-10-06T05:36:51.898Z" }, + { url = "https://files.pythonhosted.org/packages/c9/1f/fb1685a7b009d89f9bf78a42d94461bc06581f6e718c39344754a5d9bada/frozenlist-1.8.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:581ef5194c48035a7de2aefc72ac6539823bb71508189e5de01d60c9dcd5fa65", size = 292506, upload-time = "2025-10-06T05:36:53.101Z" }, + { url = "https://files.pythonhosted.org/packages/e6/3b/b991fe1612703f7e0d05c0cf734c1b77aaf7c7d321df4572e8d36e7048c8/frozenlist-1.8.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3ef2d026f16a2b1866e1d86fc4e1291e1ed8a387b2c333809419a2f8b3a77b82", size = 274161, upload-time = "2025-10-06T05:36:54.309Z" }, + { url = "https://files.pythonhosted.org/packages/ca/ec/c5c618767bcdf66e88945ec0157d7f6c4a1322f1473392319b7a2501ded7/frozenlist-1.8.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5500ef82073f599ac84d888e3a8c1f77ac831183244bfd7f11eaa0289fb30714", size = 294676, upload-time = "2025-10-06T05:36:55.566Z" }, + { url = "https://files.pythonhosted.org/packages/7c/ce/3934758637d8f8a88d11f0585d6495ef54b2044ed6ec84492a91fa3b27aa/frozenlist-1.8.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:50066c3997d0091c411a66e710f4e11752251e6d2d73d70d8d5d4c76442a199d", size = 300638, upload-time = "2025-10-06T05:36:56.758Z" }, + { url = "https://files.pythonhosted.org/packages/fc/4f/a7e4d0d467298f42de4b41cbc7ddaf19d3cfeabaf9ff97c20c6c7ee409f9/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:5c1c8e78426e59b3f8005e9b19f6ff46e5845895adbde20ece9218319eca6506", size = 283067, upload-time = "2025-10-06T05:36:57.965Z" }, + { url = "https://files.pythonhosted.org/packages/dc/48/c7b163063d55a83772b268e6d1affb960771b0e203b632cfe09522d67ea5/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:eefdba20de0d938cec6a89bd4d70f346a03108a19b9df4248d3cf0d88f1b0f51", size = 292101, upload-time = "2025-10-06T05:36:59.237Z" }, + { url = "https://files.pythonhosted.org/packages/9f/d0/2366d3c4ecdc2fd391e0afa6e11500bfba0ea772764d631bbf82f0136c9d/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cf253e0e1c3ceb4aaff6df637ce033ff6535fb8c70a764a8f46aafd3d6ab798e", size = 289901, upload-time = "2025-10-06T05:37:00.811Z" }, + { url = "https://files.pythonhosted.org/packages/b8/94/daff920e82c1b70e3618a2ac39fbc01ae3e2ff6124e80739ce5d71c9b920/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:032efa2674356903cd0261c4317a561a6850f3ac864a63fc1583147fb05a79b0", size = 289395, upload-time = "2025-10-06T05:37:02.115Z" }, + { url = "https://files.pythonhosted.org/packages/e3/20/bba307ab4235a09fdcd3cc5508dbabd17c4634a1af4b96e0f69bfe551ebd/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6da155091429aeba16851ecb10a9104a108bcd32f6c1642867eadaee401c1c41", size = 283659, upload-time = "2025-10-06T05:37:03.711Z" }, + { url = "https://files.pythonhosted.org/packages/fd/00/04ca1c3a7a124b6de4f8a9a17cc2fcad138b4608e7a3fc5877804b8715d7/frozenlist-1.8.0-cp313-cp313t-win32.whl", hash = "sha256:0f96534f8bfebc1a394209427d0f8a63d343c9779cda6fc25e8e121b5fd8555b", size = 43492, upload-time = "2025-10-06T05:37:04.915Z" }, + { url = "https://files.pythonhosted.org/packages/59/5e/c69f733a86a94ab10f68e496dc6b7e8bc078ebb415281d5698313e3af3a1/frozenlist-1.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5d63a068f978fc69421fb0e6eb91a9603187527c86b7cd3f534a5b77a592b888", size = 48034, upload-time = "2025-10-06T05:37:06.343Z" }, + { url = "https://files.pythonhosted.org/packages/16/6c/be9d79775d8abe79b05fa6d23da99ad6e7763a1d080fbae7290b286093fd/frozenlist-1.8.0-cp313-cp313t-win_arm64.whl", hash = "sha256:bf0a7e10b077bf5fb9380ad3ae8ce20ef919a6ad93b4552896419ac7e1d8e042", size = 41749, upload-time = "2025-10-06T05:37:07.431Z" }, + { url = "https://files.pythonhosted.org/packages/f1/c8/85da824b7e7b9b6e7f7705b2ecaf9591ba6f79c1177f324c2735e41d36a2/frozenlist-1.8.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cee686f1f4cadeb2136007ddedd0aaf928ab95216e7691c63e50a8ec066336d0", size = 86127, upload-time = "2025-10-06T05:37:08.438Z" }, + { url = "https://files.pythonhosted.org/packages/8e/e8/a1185e236ec66c20afd72399522f142c3724c785789255202d27ae992818/frozenlist-1.8.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:119fb2a1bd47307e899c2fac7f28e85b9a543864df47aa7ec9d3c1b4545f096f", size = 49698, upload-time = "2025-10-06T05:37:09.48Z" }, + { url = "https://files.pythonhosted.org/packages/a1/93/72b1736d68f03fda5fdf0f2180fb6caaae3894f1b854d006ac61ecc727ee/frozenlist-1.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4970ece02dbc8c3a92fcc5228e36a3e933a01a999f7094ff7c23fbd2beeaa67c", size = 49749, upload-time = "2025-10-06T05:37:10.569Z" }, + { url = "https://files.pythonhosted.org/packages/a7/b2/fabede9fafd976b991e9f1b9c8c873ed86f202889b864756f240ce6dd855/frozenlist-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:cba69cb73723c3f329622e34bdbf5ce1f80c21c290ff04256cff1cd3c2036ed2", size = 231298, upload-time = "2025-10-06T05:37:11.993Z" }, + { url = "https://files.pythonhosted.org/packages/3a/3b/d9b1e0b0eed36e70477ffb8360c49c85c8ca8ef9700a4e6711f39a6e8b45/frozenlist-1.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:778a11b15673f6f1df23d9586f83c4846c471a8af693a22e066508b77d201ec8", size = 232015, upload-time = "2025-10-06T05:37:13.194Z" }, + { url = "https://files.pythonhosted.org/packages/dc/94/be719d2766c1138148564a3960fc2c06eb688da592bdc25adcf856101be7/frozenlist-1.8.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686", size = 225038, upload-time = "2025-10-06T05:37:14.577Z" }, + { url = "https://files.pythonhosted.org/packages/e4/09/6712b6c5465f083f52f50cf74167b92d4ea2f50e46a9eea0523d658454ae/frozenlist-1.8.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:97260ff46b207a82a7567b581ab4190bd4dfa09f4db8a8b49d1a958f6aa4940e", size = 240130, upload-time = "2025-10-06T05:37:15.781Z" }, + { url = "https://files.pythonhosted.org/packages/f8/d4/cd065cdcf21550b54f3ce6a22e143ac9e4836ca42a0de1022da8498eac89/frozenlist-1.8.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:54b2077180eb7f83dd52c40b2750d0a9f175e06a42e3213ce047219de902717a", size = 242845, upload-time = "2025-10-06T05:37:17.037Z" }, + { url = "https://files.pythonhosted.org/packages/62/c3/f57a5c8c70cd1ead3d5d5f776f89d33110b1addae0ab010ad774d9a44fb9/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2f05983daecab868a31e1da44462873306d3cbfd76d1f0b5b69c473d21dbb128", size = 229131, upload-time = "2025-10-06T05:37:18.221Z" }, + { url = "https://files.pythonhosted.org/packages/6c/52/232476fe9cb64f0742f3fde2b7d26c1dac18b6d62071c74d4ded55e0ef94/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:33f48f51a446114bc5d251fb2954ab0164d5be02ad3382abcbfe07e2531d650f", size = 240542, upload-time = "2025-10-06T05:37:19.771Z" }, + { url = "https://files.pythonhosted.org/packages/5f/85/07bf3f5d0fb5414aee5f47d33c6f5c77bfe49aac680bfece33d4fdf6a246/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:154e55ec0655291b5dd1b8731c637ecdb50975a2ae70c606d100750a540082f7", size = 237308, upload-time = "2025-10-06T05:37:20.969Z" }, + { url = "https://files.pythonhosted.org/packages/11/99/ae3a33d5befd41ac0ca2cc7fd3aa707c9c324de2e89db0e0f45db9a64c26/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:4314debad13beb564b708b4a496020e5306c7333fa9a3ab90374169a20ffab30", size = 238210, upload-time = "2025-10-06T05:37:22.252Z" }, + { url = "https://files.pythonhosted.org/packages/b2/60/b1d2da22f4970e7a155f0adde9b1435712ece01b3cd45ba63702aea33938/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:073f8bf8becba60aa931eb3bc420b217bb7d5b8f4750e6f8b3be7f3da85d38b7", size = 231972, upload-time = "2025-10-06T05:37:23.5Z" }, + { url = "https://files.pythonhosted.org/packages/3f/ab/945b2f32de889993b9c9133216c068b7fcf257d8595a0ac420ac8677cab0/frozenlist-1.8.0-cp314-cp314-win32.whl", hash = "sha256:bac9c42ba2ac65ddc115d930c78d24ab8d4f465fd3fc473cdedfccadb9429806", size = 40536, upload-time = "2025-10-06T05:37:25.581Z" }, + { url = "https://files.pythonhosted.org/packages/59/ad/9caa9b9c836d9ad6f067157a531ac48b7d36499f5036d4141ce78c230b1b/frozenlist-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:3e0761f4d1a44f1d1a47996511752cf3dcec5bbdd9cc2b4fe595caf97754b7a0", size = 44330, upload-time = "2025-10-06T05:37:26.928Z" }, + { url = "https://files.pythonhosted.org/packages/82/13/e6950121764f2676f43534c555249f57030150260aee9dcf7d64efda11dd/frozenlist-1.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:d1eaff1d00c7751b7c6662e9c5ba6eb2c17a2306ba5e2a37f24ddf3cc953402b", size = 40627, upload-time = "2025-10-06T05:37:28.075Z" }, + { url = "https://files.pythonhosted.org/packages/c0/c7/43200656ecc4e02d3f8bc248df68256cd9572b3f0017f0a0c4e93440ae23/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d3bb933317c52d7ea5004a1c442eef86f426886fba134ef8cf4226ea6ee1821d", size = 89238, upload-time = "2025-10-06T05:37:29.373Z" }, + { url = "https://files.pythonhosted.org/packages/d1/29/55c5f0689b9c0fb765055629f472c0de484dcaf0acee2f7707266ae3583c/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8009897cdef112072f93a0efdce29cd819e717fd2f649ee3016efd3cd885a7ed", size = 50738, upload-time = "2025-10-06T05:37:30.792Z" }, + { url = "https://files.pythonhosted.org/packages/ba/7d/b7282a445956506fa11da8c2db7d276adcbf2b17d8bb8407a47685263f90/frozenlist-1.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2c5dcbbc55383e5883246d11fd179782a9d07a986c40f49abe89ddf865913930", size = 51739, upload-time = "2025-10-06T05:37:32.127Z" }, + { url = "https://files.pythonhosted.org/packages/62/1c/3d8622e60d0b767a5510d1d3cf21065b9db874696a51ea6d7a43180a259c/frozenlist-1.8.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:39ecbc32f1390387d2aa4f5a995e465e9e2f79ba3adcac92d68e3e0afae6657c", size = 284186, upload-time = "2025-10-06T05:37:33.21Z" }, + { url = "https://files.pythonhosted.org/packages/2d/14/aa36d5f85a89679a85a1d44cd7a6657e0b1c75f61e7cad987b203d2daca8/frozenlist-1.8.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92db2bf818d5cc8d9c1f1fc56b897662e24ea5adb36ad1f1d82875bd64e03c24", size = 292196, upload-time = "2025-10-06T05:37:36.107Z" }, + { url = "https://files.pythonhosted.org/packages/05/23/6bde59eb55abd407d34f77d39a5126fb7b4f109a3f611d3929f14b700c66/frozenlist-1.8.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2dc43a022e555de94c3b68a4ef0b11c4f747d12c024a520c7101709a2144fb37", size = 273830, upload-time = "2025-10-06T05:37:37.663Z" }, + { url = "https://files.pythonhosted.org/packages/d2/3f/22cff331bfad7a8afa616289000ba793347fcd7bc275f3b28ecea2a27909/frozenlist-1.8.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb89a7f2de3602cfed448095bab3f178399646ab7c61454315089787df07733a", size = 294289, upload-time = "2025-10-06T05:37:39.261Z" }, + { url = "https://files.pythonhosted.org/packages/a4/89/5b057c799de4838b6c69aa82b79705f2027615e01be996d2486a69ca99c4/frozenlist-1.8.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:33139dc858c580ea50e7e60a1b0ea003efa1fd42e6ec7fdbad78fff65fad2fd2", size = 300318, upload-time = "2025-10-06T05:37:43.213Z" }, + { url = "https://files.pythonhosted.org/packages/30/de/2c22ab3eb2a8af6d69dc799e48455813bab3690c760de58e1bf43b36da3e/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:168c0969a329b416119507ba30b9ea13688fafffac1b7822802537569a1cb0ef", size = 282814, upload-time = "2025-10-06T05:37:45.337Z" }, + { url = "https://files.pythonhosted.org/packages/59/f7/970141a6a8dbd7f556d94977858cfb36fa9b66e0892c6dd780d2219d8cd8/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:28bd570e8e189d7f7b001966435f9dac6718324b5be2990ac496cf1ea9ddb7fe", size = 291762, upload-time = "2025-10-06T05:37:46.657Z" }, + { url = "https://files.pythonhosted.org/packages/c1/15/ca1adae83a719f82df9116d66f5bb28bb95557b3951903d39135620ef157/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b2a095d45c5d46e5e79ba1e5b9cb787f541a8dee0433836cea4b96a2c439dcd8", size = 289470, upload-time = "2025-10-06T05:37:47.946Z" }, + { url = "https://files.pythonhosted.org/packages/ac/83/dca6dc53bf657d371fbc88ddeb21b79891e747189c5de990b9dfff2ccba1/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:eab8145831a0d56ec9c4139b6c3e594c7a83c2c8be25d5bcf2d86136a532287a", size = 289042, upload-time = "2025-10-06T05:37:49.499Z" }, + { url = "https://files.pythonhosted.org/packages/96/52/abddd34ca99be142f354398700536c5bd315880ed0a213812bc491cff5e4/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:974b28cf63cc99dfb2188d8d222bc6843656188164848c4f679e63dae4b0708e", size = 283148, upload-time = "2025-10-06T05:37:50.745Z" }, + { url = "https://files.pythonhosted.org/packages/af/d3/76bd4ed4317e7119c2b7f57c3f6934aba26d277acc6309f873341640e21f/frozenlist-1.8.0-cp314-cp314t-win32.whl", hash = "sha256:342c97bf697ac5480c0a7ec73cd700ecfa5a8a40ac923bd035484616efecc2df", size = 44676, upload-time = "2025-10-06T05:37:52.222Z" }, + { url = "https://files.pythonhosted.org/packages/89/76/c615883b7b521ead2944bb3480398cbb07e12b7b4e4d073d3752eb721558/frozenlist-1.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:06be8f67f39c8b1dc671f5d83aaefd3358ae5cdcf8314552c57e7ed3e6475bdd", size = 49451, upload-time = "2025-10-06T05:37:53.425Z" }, + { url = "https://files.pythonhosted.org/packages/e0/a3/5982da14e113d07b325230f95060e2169f5311b1017ea8af2a29b374c289/frozenlist-1.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:102e6314ca4da683dca92e3b1355490fed5f313b768500084fbe6371fddfdb79", size = 42507, upload-time = "2025-10-06T05:37:54.513Z" }, + { url = "https://files.pythonhosted.org/packages/c2/59/ae5cdac87a00962122ea37bb346d41b66aec05f9ce328fa2b9e216f8967b/frozenlist-1.8.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d8b7138e5cd0647e4523d6685b0eac5d4be9a184ae9634492f25c6eb38c12a47", size = 86967, upload-time = "2025-10-06T05:37:55.607Z" }, + { url = "https://files.pythonhosted.org/packages/8a/10/17059b2db5a032fd9323c41c39e9d1f5f9d0c8f04d1e4e3e788573086e61/frozenlist-1.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a6483e309ca809f1efd154b4d37dc6d9f61037d6c6a81c2dc7a15cb22c8c5dca", size = 49984, upload-time = "2025-10-06T05:37:57.049Z" }, + { url = "https://files.pythonhosted.org/packages/4b/de/ad9d82ca8e5fa8f0c636e64606553c79e2b859ad253030b62a21fe9986f5/frozenlist-1.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1b9290cf81e95e93fdf90548ce9d3c1211cf574b8e3f4b3b7cb0537cf2227068", size = 50240, upload-time = "2025-10-06T05:37:58.145Z" }, + { url = "https://files.pythonhosted.org/packages/4e/45/3dfb7767c2a67d123650122b62ce13c731b6c745bc14424eea67678b508c/frozenlist-1.8.0-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:59a6a5876ca59d1b63af8cd5e7ffffb024c3dc1e9cf9301b21a2e76286505c95", size = 219472, upload-time = "2025-10-06T05:37:59.239Z" }, + { url = "https://files.pythonhosted.org/packages/0b/bf/5bf23d913a741b960d5c1dac7c1985d8a2a1d015772b2d18ea168b08e7ff/frozenlist-1.8.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6dc4126390929823e2d2d9dc79ab4046ed74680360fc5f38b585c12c66cdf459", size = 221531, upload-time = "2025-10-06T05:38:00.521Z" }, + { url = "https://files.pythonhosted.org/packages/d0/03/27ec393f3b55860859f4b74cdc8c2a4af3dbf3533305e8eacf48a4fd9a54/frozenlist-1.8.0-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:332db6b2563333c5671fecacd085141b5800cb866be16d5e3eb15a2086476675", size = 219211, upload-time = "2025-10-06T05:38:01.842Z" }, + { url = "https://files.pythonhosted.org/packages/3a/ad/0fd00c404fa73fe9b169429e9a972d5ed807973c40ab6b3cf9365a33d360/frozenlist-1.8.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9ff15928d62a0b80bb875655c39bf517938c7d589554cbd2669be42d97c2cb61", size = 231775, upload-time = "2025-10-06T05:38:03.384Z" }, + { url = "https://files.pythonhosted.org/packages/8a/c3/86962566154cb4d2995358bc8331bfc4ea19d07db1a96f64935a1607f2b6/frozenlist-1.8.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7bf6cdf8e07c8151fba6fe85735441240ec7f619f935a5205953d58009aef8c6", size = 236631, upload-time = "2025-10-06T05:38:04.609Z" }, + { url = "https://files.pythonhosted.org/packages/ea/9e/6ffad161dbd83782d2c66dc4d378a9103b31770cb1e67febf43aea42d202/frozenlist-1.8.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:48e6d3f4ec5c7273dfe83ff27c91083c6c9065af655dc2684d2c200c94308bb5", size = 218632, upload-time = "2025-10-06T05:38:05.917Z" }, + { url = "https://files.pythonhosted.org/packages/58/b2/4677eee46e0a97f9b30735e6ad0bf6aba3e497986066eb68807ac85cf60f/frozenlist-1.8.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:1a7607e17ad33361677adcd1443edf6f5da0ce5e5377b798fba20fae194825f3", size = 235967, upload-time = "2025-10-06T05:38:07.614Z" }, + { url = "https://files.pythonhosted.org/packages/05/f3/86e75f8639c5a93745ca7addbbc9de6af56aebb930d233512b17e46f6493/frozenlist-1.8.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:5a3a935c3a4e89c733303a2d5a7c257ea44af3a56c8202df486b7f5de40f37e1", size = 228799, upload-time = "2025-10-06T05:38:08.845Z" }, + { url = "https://files.pythonhosted.org/packages/30/00/39aad3a7f0d98f5eb1d99a3c311215674ed87061aecee7851974b335c050/frozenlist-1.8.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:940d4a017dbfed9daf46a3b086e1d2167e7012ee297fef9e1c545c4d022f5178", size = 230566, upload-time = "2025-10-06T05:38:10.52Z" }, + { url = "https://files.pythonhosted.org/packages/0d/4d/aa144cac44568d137846ddc4d5210fb5d9719eb1d7ec6fa2728a54b5b94a/frozenlist-1.8.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b9be22a69a014bc47e78072d0ecae716f5eb56c15238acca0f43d6eb8e4a5bda", size = 217715, upload-time = "2025-10-06T05:38:11.832Z" }, + { url = "https://files.pythonhosted.org/packages/64/4c/8f665921667509d25a0dd72540513bc86b356c95541686f6442a3283019f/frozenlist-1.8.0-cp39-cp39-win32.whl", hash = "sha256:1aa77cb5697069af47472e39612976ed05343ff2e84a3dcf15437b232cbfd087", size = 39933, upload-time = "2025-10-06T05:38:13.061Z" }, + { url = "https://files.pythonhosted.org/packages/79/bd/bcc926f87027fad5e59926ff12d136e1082a115025d33c032d1cd69ab377/frozenlist-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:7398c222d1d405e796970320036b1b563892b65809d9e5261487bb2c7f7b5c6a", size = 44121, upload-time = "2025-10-06T05:38:14.572Z" }, + { url = "https://files.pythonhosted.org/packages/4c/07/9c2e4eb7584af4b705237b971b89a4155a8e57599c4483a131a39256a9a0/frozenlist-1.8.0-cp39-cp39-win_arm64.whl", hash = "sha256:b4f3b365f31c6cd4af24545ca0a244a53688cad8834e32f56831c4923b50a103", size = 40312, upload-time = "2025-10-06T05:38:15.699Z" }, + { url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409, upload-time = "2025-10-06T05:38:16.721Z" }, +] + +[[package]] +name = "griffe" +version = "1.14.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.10'", +] +dependencies = [ + { name = "colorama", marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ec/d7/6c09dd7ce4c7837e4cdb11dce980cb45ae3cd87677298dc3b781b6bce7d3/griffe-1.14.0.tar.gz", hash = "sha256:9d2a15c1eca966d68e00517de5d69dd1bc5c9f2335ef6c1775362ba5b8651a13", size = 424684, upload-time = "2025-09-05T15:02:29.167Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/b1/9ff6578d789a89812ff21e4e0f80ffae20a65d5dd84e7a17873fe3b365be/griffe-1.14.0-py3-none-any.whl", hash = "sha256:0e9d52832cccf0f7188cfe585ba962d2674b241c01916d780925df34873bceb0", size = 144439, upload-time = "2025-09-05T15:02:27.511Z" }, +] + +[[package]] +name = "griffe" +version = "2.0.2" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14' and extra != 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and python_full_version < '3.14' and extra != 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and extra == 'group-10-cloudflare-pydantic-v1' and extra != 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and extra != 'group-10-cloudflare-pydantic-v1' and extra != 'group-10-cloudflare-pydantic-v2'", +] +dependencies = [ + { name = "griffecli", marker = "python_full_version >= '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "griffelib", marker = "python_full_version >= '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4a/49/eb6d2935e27883af92c930ed40cc4c69bcd32c402be43b8ca4ab20510f67/griffe-2.0.2.tar.gz", hash = "sha256:c5d56326d159f274492e9bf93a9895cec101155d944caa66d0fc4e0c13751b92", size = 293757, upload-time = "2026-03-27T11:34:52.205Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/c0/2bb018eecf9a83c68db9cd9fffd9dab25f102ad30ed869451046e46d1187/griffe-2.0.2-py3-none-any.whl", hash = "sha256:2b31816460aee1996af26050a1fc6927a2e5936486856707f55508e4c9b5960b", size = 5141, upload-time = "2026-03-27T11:34:47.721Z" }, +] + +[[package]] +name = "griffecli" +version = "2.0.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "python_full_version >= '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "griffelib", marker = "python_full_version >= '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/79/e0/6a7d661d71bb043656a109b91d84a42b5342752542074ec83b16a6eb97f0/griffecli-2.0.2.tar.gz", hash = "sha256:40a1ad4181fc39685d025e119ae2c5b669acdc1f19b705fb9bf971f4e6f6dffb", size = 56281, upload-time = "2026-03-27T11:34:50.087Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2e/e8/90d93356c88ac34c20cb5edffca68138df55ca9bbd1a06eccfbcec8fdbe5/griffecli-2.0.2-py3-none-any.whl", hash = "sha256:0d44d39e59afa81e288a3e1c3bf352cc4fa537483326ac06b8bb6a51fd8303a0", size = 9500, upload-time = "2026-03-27T11:34:48.81Z" }, +] + +[[package]] +name = "griffelib" +version = "2.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9d/82/74f4a3310cdabfbb10da554c3a672847f1ed33c6f61dd472681ce7f1fe67/griffelib-2.0.2.tar.gz", hash = "sha256:3cf20b3bc470e83763ffbf236e0076b1211bac1bc67de13daf494640f2de707e", size = 166461, upload-time = "2026-03-27T11:34:51.091Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/11/8c/c9138d881c79aa0ea9ed83cbd58d5ca75624378b38cee225dcf5c42cc91f/griffelib-2.0.2-py3-none-any.whl", hash = "sha256:925c857658fb1ba40c0772c37acbc2ab650bd794d9c1b9726922e36ea4117ea1", size = 142357, upload-time = "2026-03-27T11:34:46.275Z" }, +] + +[[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.12.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "anyio", version = "4.13.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-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.12" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohttp" }, + { name = "httpx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/63/2c/b894861cecf030fb45675ea24aa55b5722e97c602a163d872fca66c5a6d8/httpx_aiohttp-0.1.12.tar.gz", hash = "sha256:81feec51fd82c0ecfa0e9aaf1b1a6c2591260d5e2bcbeb7eb0277a78e610df2c", size = 275945, upload-time = "2025-12-12T10:12:15.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/16/8d/85c9701e9af72ca132a1783e2a54364a90c6da832304416a30fc11196ab2/httpx_aiohttp-0.1.12-py3-none-any.whl", hash = "sha256:5b0eac39a7f360fa7867a60bcb46bb1024eada9c01cbfecdb54dc1edb3fb7141", size = 6367, upload-time = "2025-12-12T10:12:14.018Z" }, +] + +[[package]] +name = "idna" +version = "3.13" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ce/cc/762dfb036166873f0059f3b7de4565e1b5bc3d6f28a414c13da27e442f99/idna-3.13.tar.gz", hash = "sha256:585ea8fe5d69b9181ec1afba340451fba6ba764af97026f92a91d4eef164a242", size = 194210, upload-time = "2026-04-22T16:42:42.314Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/13/ad7d7ca3808a898b4612b6fe93cde56b53f3034dcde235acb1f0e1df24c6/idna-3.13-py3-none-any.whl", hash = "sha256:892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3", size = 68629, upload-time = "2026-04-22T16:42:40.909Z" }, +] + +[[package]] +name = "importlib-metadata" +version = "8.7.1" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.10'", +] +dependencies = [ + { name = "zipp", marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f3/49/3b30cad09e7771a4982d9975a8cbf64f00d4a1ececb53297f1d9a7be1b10/importlib_metadata-8.7.1.tar.gz", hash = "sha256:49fef1ae6440c182052f407c8d34a68f72efc36db9ca90dc0113398f2fdde8bb", size = 57107, upload-time = "2025-12-21T10:00:19.278Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl", hash = "sha256:5a1f80bf1daa489495071efbb095d75a634cf28a8bc299581244063b53176151", size = 27865, upload-time = "2025-12-21T10:00:18.329Z" }, +] + +[[package]] +name = "importlib-metadata" +version = "9.0.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14' and extra != 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and python_full_version < '3.14' and extra != 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and extra == 'group-10-cloudflare-pydantic-v1' and extra != 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and extra != 'group-10-cloudflare-pydantic-v1' and extra != 'group-10-cloudflare-pydantic-v2'", +] +dependencies = [ + { name = "zipp", marker = "python_full_version >= '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a9/01/15bb152d77b21318514a96f43af312635eb2500c96b55398d020c93d86ea/importlib_metadata-9.0.0.tar.gz", hash = "sha256:a4f57ab599e6a2e3016d7595cfd72eb4661a5106e787a95bcc90c7105b831efc", size = 56405, upload-time = "2026-03-20T06:42:56.999Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/3d/2d244233ac4f76e38533cfcb2991c9eb4c7bf688ae0a036d30725b8faafe/importlib_metadata-9.0.0-py3-none-any.whl", hash = "sha256:2d21d1cc5a017bd0559e36150c21c830ab1dc304dedd1b7ea85d20f45ef3edd7", size = 27789, upload-time = "2026-03-20T06:42:55.665Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.10'", +] +sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14' and extra != 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and python_full_version < '3.14' and extra != 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and extra == 'group-10-cloudflare-pydantic-v1' and extra != 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and extra != 'group-10-cloudflare-pydantic-v1' and extra != 'group-10-cloudflare-pydantic-v2'", +] +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.10'", +] +dependencies = [ + { name = "mdurl", marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload-time = "2023-06-03T06:41:14.443Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528, upload-time = "2023-06-03T06:41:11.019Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.0.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14' and extra != 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and python_full_version < '3.14' and extra != 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and extra == 'group-10-cloudflare-pydantic-v1' and extra != 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and extra != 'group-10-cloudflare-pydantic-v1' and extra != 'group-10-cloudflare-pydantic-v2'", +] +dependencies = [ + { name = "mdurl", marker = "python_full_version >= '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "multidict" +version = "6.7.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.11' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1a/c2/c2d94cbe6ac1753f3fc980da97b3d930efe1da3af3c9f5125354436c073d/multidict-6.7.1.tar.gz", hash = "sha256:ec6652a1bee61c53a3e5776b6049172c53b6aaba34f18c9ad04f82712bac623d", size = 102010, upload-time = "2026-01-26T02:46:45.979Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/84/0b/19348d4c98980c4851d2f943f8ebafdece2ae7ef737adcfa5994ce8e5f10/multidict-6.7.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c93c3db7ea657dd4637d57e74ab73de31bccefe144d3d4ce370052035bc85fb5", size = 77176, upload-time = "2026-01-26T02:42:59.784Z" }, + { url = "https://files.pythonhosted.org/packages/ef/04/9de3f8077852e3d438215c81e9b691244532d2e05b4270e89ce67b7d103c/multidict-6.7.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:974e72a2474600827abaeda71af0c53d9ebbc3c2eb7da37b37d7829ae31232d8", size = 44996, upload-time = "2026-01-26T02:43:01.674Z" }, + { url = "https://files.pythonhosted.org/packages/31/5c/08c7f7fe311f32e83f7621cd3f99d805f45519cd06fafb247628b861da7d/multidict-6.7.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cdea2e7b2456cfb6694fb113066fd0ec7ea4d67e3a35e1f4cbeea0b448bf5872", size = 44631, upload-time = "2026-01-26T02:43:03.169Z" }, + { url = "https://files.pythonhosted.org/packages/b7/7f/0e3b1390ae772f27501199996b94b52ceeb64fe6f9120a32c6c3f6b781be/multidict-6.7.1-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:17207077e29342fdc2c9a82e4b306f1127bf1ea91f8b71e02d4798a70bb99991", size = 242561, upload-time = "2026-01-26T02:43:04.733Z" }, + { url = "https://files.pythonhosted.org/packages/dd/f4/8719f4f167586af317b69dd3e90f913416c91ca610cac79a45c53f590312/multidict-6.7.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d4f49cb5661344764e4c7c7973e92a47a59b8fc19b6523649ec9dc4960e58a03", size = 242223, upload-time = "2026-01-26T02:43:06.695Z" }, + { url = "https://files.pythonhosted.org/packages/47/ab/7c36164cce64a6ad19c6d9a85377b7178ecf3b89f8fd589c73381a5eedfd/multidict-6.7.1-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a9fc4caa29e2e6ae408d1c450ac8bf19892c5fca83ee634ecd88a53332c59981", size = 222322, upload-time = "2026-01-26T02:43:08.472Z" }, + { url = "https://files.pythonhosted.org/packages/f5/79/a25add6fb38035b5337bc5734f296d9afc99163403bbcf56d4170f97eb62/multidict-6.7.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c5f0c21549ab432b57dcc82130f388d84ad8179824cc3f223d5e7cfbfd4143f6", size = 254005, upload-time = "2026-01-26T02:43:10.127Z" }, + { url = "https://files.pythonhosted.org/packages/4a/7b/64a87cf98e12f756fc8bd444b001232ffff2be37288f018ad0d3f0aae931/multidict-6.7.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7dfb78d966b2c906ae1d28ccf6e6712a3cd04407ee5088cd276fe8cb42186190", size = 251173, upload-time = "2026-01-26T02:43:11.731Z" }, + { url = "https://files.pythonhosted.org/packages/4b/ac/b605473de2bb404e742f2cc3583d12aedb2352a70e49ae8fce455b50c5aa/multidict-6.7.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9b0d9b91d1aa44db9c1f1ecd0d9d2ae610b2f4f856448664e01a3b35899f3f92", size = 243273, upload-time = "2026-01-26T02:43:13.063Z" }, + { url = "https://files.pythonhosted.org/packages/03/65/11492d6a0e259783720f3bc1d9ea55579a76f1407e31ed44045c99542004/multidict-6.7.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:dd96c01a9dcd4889dcfcf9eb5544ca0c77603f239e3ffab0524ec17aea9a93ee", size = 238956, upload-time = "2026-01-26T02:43:14.843Z" }, + { url = "https://files.pythonhosted.org/packages/5f/a7/7ee591302af64e7c196fb63fe856c788993c1372df765102bd0448e7e165/multidict-6.7.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:067343c68cd6612d375710f895337b3a98a033c94f14b9a99eff902f205424e2", size = 233477, upload-time = "2026-01-26T02:43:16.025Z" }, + { url = "https://files.pythonhosted.org/packages/9c/99/c109962d58756c35fd9992fed7f2355303846ea2ff054bb5f5e9d6b888de/multidict-6.7.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5884a04f4ff56c6120f6ccf703bdeb8b5079d808ba604d4d53aec0d55dc33568", size = 243615, upload-time = "2026-01-26T02:43:17.84Z" }, + { url = "https://files.pythonhosted.org/packages/d5/5f/1973e7c771c86e93dcfe1c9cc55a5481b610f6614acfc28c0d326fe6bfad/multidict-6.7.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8affcf1c98b82bc901702eb73b6947a1bfa170823c153fe8a47b5f5f02e48e40", size = 249930, upload-time = "2026-01-26T02:43:19.06Z" }, + { url = "https://files.pythonhosted.org/packages/5d/a5/f170fc2268c3243853580203378cd522446b2df632061e0a5409817854c7/multidict-6.7.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:0d17522c37d03e85c8098ec8431636309b2682cf12e58f4dbc76121fb50e4962", size = 243807, upload-time = "2026-01-26T02:43:20.286Z" }, + { url = "https://files.pythonhosted.org/packages/de/01/73856fab6d125e5bc652c3986b90e8699a95e84b48d72f39ade6c0e74a8c/multidict-6.7.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:24c0cf81544ca5e17cfcb6e482e7a82cd475925242b308b890c9452a074d4505", size = 239103, upload-time = "2026-01-26T02:43:21.508Z" }, + { url = "https://files.pythonhosted.org/packages/e7/46/f1220bd9944d8aa40d8ccff100eeeee19b505b857b6f603d6078cb5315b0/multidict-6.7.1-cp310-cp310-win32.whl", hash = "sha256:d82dd730a95e6643802f4454b8fdecdf08667881a9c5670db85bc5a56693f122", size = 41416, upload-time = "2026-01-26T02:43:22.703Z" }, + { url = "https://files.pythonhosted.org/packages/68/00/9b38e272a770303692fc406c36e1a4c740f401522d5787691eb38a8925a8/multidict-6.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:cf37cbe5ced48d417ba045aca1b21bafca67489452debcde94778a576666a1df", size = 46022, upload-time = "2026-01-26T02:43:23.77Z" }, + { url = "https://files.pythonhosted.org/packages/64/65/d8d42490c02ee07b6bbe00f7190d70bb4738b3cce7629aaf9f213ef730dd/multidict-6.7.1-cp310-cp310-win_arm64.whl", hash = "sha256:59bc83d3f66b41dac1e7460aac1d196edc70c9ba3094965c467715a70ecb46db", size = 43238, upload-time = "2026-01-26T02:43:24.882Z" }, + { url = "https://files.pythonhosted.org/packages/ce/f1/a90635c4f88fb913fbf4ce660b83b7445b7a02615bda034b2f8eb38fd597/multidict-6.7.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7ff981b266af91d7b4b3793ca3382e53229088d193a85dfad6f5f4c27fc73e5d", size = 76626, upload-time = "2026-01-26T02:43:26.485Z" }, + { url = "https://files.pythonhosted.org/packages/a6/9b/267e64eaf6fc637a15b35f5de31a566634a2740f97d8d094a69d34f524a4/multidict-6.7.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:844c5bca0b5444adb44a623fb0a1310c2f4cd41f402126bb269cd44c9b3f3e1e", size = 44706, upload-time = "2026-01-26T02:43:27.607Z" }, + { url = "https://files.pythonhosted.org/packages/dd/a4/d45caf2b97b035c57267791ecfaafbd59c68212004b3842830954bb4b02e/multidict-6.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f2a0a924d4c2e9afcd7ec64f9de35fcd96915149b2216e1cb2c10a56df483855", size = 44356, upload-time = "2026-01-26T02:43:28.661Z" }, + { url = "https://files.pythonhosted.org/packages/fd/d2/0a36c8473f0cbaeadd5db6c8b72d15bbceeec275807772bfcd059bef487d/multidict-6.7.1-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:8be1802715a8e892c784c0197c2ace276ea52702a0ede98b6310c8f255a5afb3", size = 244355, upload-time = "2026-01-26T02:43:31.165Z" }, + { url = "https://files.pythonhosted.org/packages/5d/16/8c65be997fd7dd311b7d39c7b6e71a0cb449bad093761481eccbbe4b42a2/multidict-6.7.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2e2d2ed645ea29f31c4c7ea1552fcfd7cb7ba656e1eafd4134a6620c9f5fdd9e", size = 246433, upload-time = "2026-01-26T02:43:32.581Z" }, + { url = "https://files.pythonhosted.org/packages/01/fb/4dbd7e848d2799c6a026ec88ad39cf2b8416aa167fcc903baa55ecaa045c/multidict-6.7.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:95922cee9a778659e91db6497596435777bd25ed116701a4c034f8e46544955a", size = 225376, upload-time = "2026-01-26T02:43:34.417Z" }, + { url = "https://files.pythonhosted.org/packages/b6/8a/4a3a6341eac3830f6053062f8fbc9a9e54407c80755b3f05bc427295c2d0/multidict-6.7.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6b83cabdc375ffaaa15edd97eb7c0c672ad788e2687004990074d7d6c9b140c8", size = 257365, upload-time = "2026-01-26T02:43:35.741Z" }, + { url = "https://files.pythonhosted.org/packages/f7/a2/dd575a69c1aa206e12d27d0770cdf9b92434b48a9ef0cd0d1afdecaa93c4/multidict-6.7.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:38fb49540705369bab8484db0689d86c0a33a0a9f2c1b197f506b71b4b6c19b0", size = 254747, upload-time = "2026-01-26T02:43:36.976Z" }, + { url = "https://files.pythonhosted.org/packages/5a/56/21b27c560c13822ed93133f08aa6372c53a8e067f11fbed37b4adcdac922/multidict-6.7.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:439cbebd499f92e9aa6793016a8acaa161dfa749ae86d20960189f5398a19144", size = 246293, upload-time = "2026-01-26T02:43:38.258Z" }, + { url = "https://files.pythonhosted.org/packages/5a/a4/23466059dc3854763423d0ad6c0f3683a379d97673b1b89ec33826e46728/multidict-6.7.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6d3bc717b6fe763b8be3f2bee2701d3c8eb1b2a8ae9f60910f1b2860c82b6c49", size = 242962, upload-time = "2026-01-26T02:43:40.034Z" }, + { url = "https://files.pythonhosted.org/packages/1f/67/51dd754a3524d685958001e8fa20a0f5f90a6a856e0a9dcabff69be3dbb7/multidict-6.7.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:619e5a1ac57986dbfec9f0b301d865dddf763696435e2962f6d9cf2fdff2bb71", size = 237360, upload-time = "2026-01-26T02:43:41.752Z" }, + { url = "https://files.pythonhosted.org/packages/64/3f/036dfc8c174934d4b55d86ff4f978e558b0e585cef70cfc1ad01adc6bf18/multidict-6.7.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0b38ebffd9be37c1170d33bc0f36f4f262e0a09bc1aac1c34c7aa51a7293f0b3", size = 245940, upload-time = "2026-01-26T02:43:43.042Z" }, + { url = "https://files.pythonhosted.org/packages/3d/20/6214d3c105928ebc353a1c644a6ef1408bc5794fcb4f170bb524a3c16311/multidict-6.7.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:10ae39c9cfe6adedcdb764f5e8411d4a92b055e35573a2eaa88d3323289ef93c", size = 253502, upload-time = "2026-01-26T02:43:44.371Z" }, + { url = "https://files.pythonhosted.org/packages/b1/e2/c653bc4ae1be70a0f836b82172d643fcf1dade042ba2676ab08ec08bff0f/multidict-6.7.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:25167cc263257660290fba06b9318d2026e3c910be240a146e1f66dd114af2b0", size = 247065, upload-time = "2026-01-26T02:43:45.745Z" }, + { url = "https://files.pythonhosted.org/packages/c8/11/a854b4154cd3bd8b1fd375e8a8ca9d73be37610c361543d56f764109509b/multidict-6.7.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:128441d052254f42989ef98b7b6a6ecb1e6f708aa962c7984235316db59f50fa", size = 241870, upload-time = "2026-01-26T02:43:47.054Z" }, + { url = "https://files.pythonhosted.org/packages/13/bf/9676c0392309b5fdae322333d22a829715b570edb9baa8016a517b55b558/multidict-6.7.1-cp311-cp311-win32.whl", hash = "sha256:d62b7f64ffde3b99d06b707a280db04fb3855b55f5a06df387236051d0668f4a", size = 41302, upload-time = "2026-01-26T02:43:48.753Z" }, + { url = "https://files.pythonhosted.org/packages/c9/68/f16a3a8ba6f7b6dc92a1f19669c0810bd2c43fc5a02da13b1cbf8e253845/multidict-6.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:bdbf9f3b332abd0cdb306e7c2113818ab1e922dc84b8f8fd06ec89ed2a19ab8b", size = 45981, upload-time = "2026-01-26T02:43:49.921Z" }, + { url = "https://files.pythonhosted.org/packages/ac/ad/9dd5305253fa00cd3c7555dbef69d5bf4133debc53b87ab8d6a44d411665/multidict-6.7.1-cp311-cp311-win_arm64.whl", hash = "sha256:b8c990b037d2fff2f4e33d3f21b9b531c5745b33a49a7d6dbe7a177266af44f6", size = 43159, upload-time = "2026-01-26T02:43:51.635Z" }, + { url = "https://files.pythonhosted.org/packages/8d/9c/f20e0e2cf80e4b2e4b1c365bf5fe104ee633c751a724246262db8f1a0b13/multidict-6.7.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:a90f75c956e32891a4eda3639ce6dd86e87105271f43d43442a3aedf3cddf172", size = 76893, upload-time = "2026-01-26T02:43:52.754Z" }, + { url = "https://files.pythonhosted.org/packages/fe/cf/18ef143a81610136d3da8193da9d80bfe1cb548a1e2d1c775f26b23d024a/multidict-6.7.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3fccb473e87eaa1382689053e4a4618e7ba7b9b9b8d6adf2027ee474597128cd", size = 45456, upload-time = "2026-01-26T02:43:53.893Z" }, + { url = "https://files.pythonhosted.org/packages/a9/65/1caac9d4cd32e8433908683446eebc953e82d22b03d10d41a5f0fefe991b/multidict-6.7.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b0fa96985700739c4c7853a43c0b3e169360d6855780021bfc6d0f1ce7c123e7", size = 43872, upload-time = "2026-01-26T02:43:55.041Z" }, + { url = "https://files.pythonhosted.org/packages/cf/3b/d6bd75dc4f3ff7c73766e04e705b00ed6dbbaccf670d9e05a12b006f5a21/multidict-6.7.1-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cb2a55f408c3043e42b40cc8eecd575afa27b7e0b956dfb190de0f8499a57a53", size = 251018, upload-time = "2026-01-26T02:43:56.198Z" }, + { url = "https://files.pythonhosted.org/packages/fd/80/c959c5933adedb9ac15152e4067c702a808ea183a8b64cf8f31af8ad3155/multidict-6.7.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eb0ce7b2a32d09892b3dd6cc44877a0d02a33241fafca5f25c8b6b62374f8b75", size = 258883, upload-time = "2026-01-26T02:43:57.499Z" }, + { url = "https://files.pythonhosted.org/packages/86/85/7ed40adafea3d4f1c8b916e3b5cc3a8e07dfcdcb9cd72800f4ed3ca1b387/multidict-6.7.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c3a32d23520ee37bf327d1e1a656fec76a2edd5c038bf43eddfa0572ec49c60b", size = 242413, upload-time = "2026-01-26T02:43:58.755Z" }, + { url = "https://files.pythonhosted.org/packages/d2/57/b8565ff533e48595503c785f8361ff9a4fde4d67de25c207cd0ba3befd03/multidict-6.7.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9c90fed18bffc0189ba814749fdcc102b536e83a9f738a9003e569acd540a733", size = 268404, upload-time = "2026-01-26T02:44:00.216Z" }, + { url = "https://files.pythonhosted.org/packages/e0/50/9810c5c29350f7258180dfdcb2e52783a0632862eb334c4896ac717cebcb/multidict-6.7.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:da62917e6076f512daccfbbde27f46fed1c98fee202f0559adec8ee0de67f71a", size = 269456, upload-time = "2026-01-26T02:44:02.202Z" }, + { url = "https://files.pythonhosted.org/packages/f3/8d/5e5be3ced1d12966fefb5c4ea3b2a5b480afcea36406559442c6e31d4a48/multidict-6.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bfde23ef6ed9db7eaee6c37dcec08524cb43903c60b285b172b6c094711b3961", size = 256322, upload-time = "2026-01-26T02:44:03.56Z" }, + { url = "https://files.pythonhosted.org/packages/31/6e/d8a26d81ac166a5592782d208dd90dfdc0a7a218adaa52b45a672b46c122/multidict-6.7.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3758692429e4e32f1ba0df23219cd0b4fc0a52f476726fff9337d1a57676a582", size = 253955, upload-time = "2026-01-26T02:44:04.845Z" }, + { url = "https://files.pythonhosted.org/packages/59/4c/7c672c8aad41534ba619bcd4ade7a0dc87ed6b8b5c06149b85d3dd03f0cd/multidict-6.7.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:398c1478926eca669f2fd6a5856b6de9c0acf23a2cb59a14c0ba5844fa38077e", size = 251254, upload-time = "2026-01-26T02:44:06.133Z" }, + { url = "https://files.pythonhosted.org/packages/7b/bd/84c24de512cbafbdbc39439f74e967f19570ce7924e3007174a29c348916/multidict-6.7.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c102791b1c4f3ab36ce4101154549105a53dc828f016356b3e3bcae2e3a039d3", size = 252059, upload-time = "2026-01-26T02:44:07.518Z" }, + { url = "https://files.pythonhosted.org/packages/fa/ba/f5449385510825b73d01c2d4087bf6d2fccc20a2d42ac34df93191d3dd03/multidict-6.7.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:a088b62bd733e2ad12c50dad01b7d0166c30287c166e137433d3b410add807a6", size = 263588, upload-time = "2026-01-26T02:44:09.382Z" }, + { url = "https://files.pythonhosted.org/packages/d7/11/afc7c677f68f75c84a69fe37184f0f82fce13ce4b92f49f3db280b7e92b3/multidict-6.7.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3d51ff4785d58d3f6c91bdbffcb5e1f7ddfda557727043aa20d20ec4f65e324a", size = 259642, upload-time = "2026-01-26T02:44:10.73Z" }, + { url = "https://files.pythonhosted.org/packages/2b/17/ebb9644da78c4ab36403739e0e6e0e30ebb135b9caf3440825001a0bddcb/multidict-6.7.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fc5907494fccf3e7d3f94f95c91d6336b092b5fc83811720fae5e2765890dfba", size = 251377, upload-time = "2026-01-26T02:44:12.042Z" }, + { url = "https://files.pythonhosted.org/packages/ca/a4/840f5b97339e27846c46307f2530a2805d9d537d8b8bd416af031cad7fa0/multidict-6.7.1-cp312-cp312-win32.whl", hash = "sha256:28ca5ce2fd9716631133d0e9a9b9a745ad7f60bac2bccafb56aa380fc0b6c511", size = 41887, upload-time = "2026-01-26T02:44:14.245Z" }, + { url = "https://files.pythonhosted.org/packages/80/31/0b2517913687895f5904325c2069d6a3b78f66cc641a86a2baf75a05dcbb/multidict-6.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:fcee94dfbd638784645b066074b338bc9cc155d4b4bffa4adce1615c5a426c19", size = 46053, upload-time = "2026-01-26T02:44:15.371Z" }, + { url = "https://files.pythonhosted.org/packages/0c/5b/aba28e4ee4006ae4c7df8d327d31025d760ffa992ea23812a601d226e682/multidict-6.7.1-cp312-cp312-win_arm64.whl", hash = "sha256:ba0a9fb644d0c1a2194cf7ffb043bd852cea63a57f66fbd33959f7dae18517bf", size = 43307, upload-time = "2026-01-26T02:44:16.852Z" }, + { url = "https://files.pythonhosted.org/packages/f2/22/929c141d6c0dba87d3e1d38fbdf1ba8baba86b7776469f2bc2d3227a1e67/multidict-6.7.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2b41f5fed0ed563624f1c17630cb9941cf2309d4df00e494b551b5f3e3d67a23", size = 76174, upload-time = "2026-01-26T02:44:18.509Z" }, + { url = "https://files.pythonhosted.org/packages/c7/75/bc704ae15fee974f8fccd871305e254754167dce5f9e42d88a2def741a1d/multidict-6.7.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:84e61e3af5463c19b67ced91f6c634effb89ef8bfc5ca0267f954451ed4bb6a2", size = 45116, upload-time = "2026-01-26T02:44:19.745Z" }, + { url = "https://files.pythonhosted.org/packages/79/76/55cd7186f498ed080a18440c9013011eb548f77ae1b297206d030eb1180a/multidict-6.7.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:935434b9853c7c112eee7ac891bc4cb86455aa631269ae35442cb316790c1445", size = 43524, upload-time = "2026-01-26T02:44:21.571Z" }, + { url = "https://files.pythonhosted.org/packages/e9/3c/414842ef8d5a1628d68edee29ba0e5bcf235dbfb3ccd3ea303a7fe8c72ff/multidict-6.7.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:432feb25a1cb67fe82a9680b4d65fb542e4635cb3166cd9c01560651ad60f177", size = 249368, upload-time = "2026-01-26T02:44:22.803Z" }, + { url = "https://files.pythonhosted.org/packages/f6/32/befed7f74c458b4a525e60519fe8d87eef72bb1e99924fa2b0f9d97a221e/multidict-6.7.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e82d14e3c948952a1a85503817e038cba5905a3352de76b9a465075d072fba23", size = 256952, upload-time = "2026-01-26T02:44:24.306Z" }, + { url = "https://files.pythonhosted.org/packages/03/d6/c878a44ba877f366630c860fdf74bfb203c33778f12b6ac274936853c451/multidict-6.7.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4cfb48c6ea66c83bcaaf7e4dfa7ec1b6bbcf751b7db85a328902796dfde4c060", size = 240317, upload-time = "2026-01-26T02:44:25.772Z" }, + { url = "https://files.pythonhosted.org/packages/68/49/57421b4d7ad2e9e60e25922b08ceb37e077b90444bde6ead629095327a6f/multidict-6.7.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1d540e51b7e8e170174555edecddbd5538105443754539193e3e1061864d444d", size = 267132, upload-time = "2026-01-26T02:44:27.648Z" }, + { url = "https://files.pythonhosted.org/packages/b7/fe/ec0edd52ddbcea2a2e89e174f0206444a61440b40f39704e64dc807a70bd/multidict-6.7.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:273d23f4b40f3dce4d6c8a821c741a86dec62cded82e1175ba3d99be128147ed", size = 268140, upload-time = "2026-01-26T02:44:29.588Z" }, + { url = "https://files.pythonhosted.org/packages/b0/73/6e1b01cbeb458807aa0831742232dbdd1fa92bfa33f52a3f176b4ff3dc11/multidict-6.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d624335fd4fa1c08a53f8b4be7676ebde19cd092b3895c421045ca87895b429", size = 254277, upload-time = "2026-01-26T02:44:30.902Z" }, + { url = "https://files.pythonhosted.org/packages/6a/b2/5fb8c124d7561a4974c342bc8c778b471ebbeb3cc17df696f034a7e9afe7/multidict-6.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:12fad252f8b267cc75b66e8fc51b3079604e8d43a75428ffe193cd9e2195dfd6", size = 252291, upload-time = "2026-01-26T02:44:32.31Z" }, + { url = "https://files.pythonhosted.org/packages/5a/96/51d4e4e06bcce92577fcd488e22600bd38e4fd59c20cb49434d054903bd2/multidict-6.7.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:03ede2a6ffbe8ef936b92cb4529f27f42be7f56afcdab5ab739cd5f27fb1cbf9", size = 250156, upload-time = "2026-01-26T02:44:33.734Z" }, + { url = "https://files.pythonhosted.org/packages/db/6b/420e173eec5fba721a50e2a9f89eda89d9c98fded1124f8d5c675f7a0c0f/multidict-6.7.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:90efbcf47dbe33dcf643a1e400d67d59abeac5db07dc3f27d6bdeae497a2198c", size = 249742, upload-time = "2026-01-26T02:44:35.222Z" }, + { url = "https://files.pythonhosted.org/packages/44/a3/ec5b5bd98f306bc2aa297b8c6f11a46714a56b1e6ef5ebda50a4f5d7c5fb/multidict-6.7.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:5c4b9bfc148f5a91be9244d6264c53035c8a0dcd2f51f1c3c6e30e30ebaa1c84", size = 262221, upload-time = "2026-01-26T02:44:36.604Z" }, + { url = "https://files.pythonhosted.org/packages/cd/f7/e8c0d0da0cd1e28d10e624604e1a36bcc3353aaebdfdc3a43c72bc683a12/multidict-6.7.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:401c5a650f3add2472d1d288c26deebc540f99e2fb83e9525007a74cd2116f1d", size = 258664, upload-time = "2026-01-26T02:44:38.008Z" }, + { url = "https://files.pythonhosted.org/packages/52/da/151a44e8016dd33feed44f730bd856a66257c1ee7aed4f44b649fb7edeb3/multidict-6.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:97891f3b1b3ffbded884e2916cacf3c6fc87b66bb0dde46f7357404750559f33", size = 249490, upload-time = "2026-01-26T02:44:39.386Z" }, + { url = "https://files.pythonhosted.org/packages/87/af/a3b86bf9630b732897f6fc3f4c4714b90aa4361983ccbdcd6c0339b21b0c/multidict-6.7.1-cp313-cp313-win32.whl", hash = "sha256:e1c5988359516095535c4301af38d8a8838534158f649c05dd1050222321bcb3", size = 41695, upload-time = "2026-01-26T02:44:41.318Z" }, + { url = "https://files.pythonhosted.org/packages/b2/35/e994121b0e90e46134673422dd564623f93304614f5d11886b1b3e06f503/multidict-6.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:960c83bf01a95b12b08fd54324a4eb1d5b52c88932b5cba5d6e712bb3ed12eb5", size = 45884, upload-time = "2026-01-26T02:44:42.488Z" }, + { url = "https://files.pythonhosted.org/packages/ca/61/42d3e5dbf661242a69c97ea363f2d7b46c567da8eadef8890022be6e2ab0/multidict-6.7.1-cp313-cp313-win_arm64.whl", hash = "sha256:563fe25c678aaba333d5399408f5ec3c383ca5b663e7f774dd179a520b8144df", size = 43122, upload-time = "2026-01-26T02:44:43.664Z" }, + { url = "https://files.pythonhosted.org/packages/6d/b3/e6b21c6c4f314bb956016b0b3ef2162590a529b84cb831c257519e7fde44/multidict-6.7.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:c76c4bec1538375dad9d452d246ca5368ad6e1c9039dadcf007ae59c70619ea1", size = 83175, upload-time = "2026-01-26T02:44:44.894Z" }, + { url = "https://files.pythonhosted.org/packages/fb/76/23ecd2abfe0957b234f6c960f4ade497f55f2c16aeb684d4ecdbf1c95791/multidict-6.7.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:57b46b24b5d5ebcc978da4ec23a819a9402b4228b8a90d9c656422b4bdd8a963", size = 48460, upload-time = "2026-01-26T02:44:46.106Z" }, + { url = "https://files.pythonhosted.org/packages/c4/57/a0ed92b23f3a042c36bc4227b72b97eca803f5f1801c1ab77c8a212d455e/multidict-6.7.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e954b24433c768ce78ab7929e84ccf3422e46deb45a4dc9f93438f8217fa2d34", size = 46930, upload-time = "2026-01-26T02:44:47.278Z" }, + { url = "https://files.pythonhosted.org/packages/b5/66/02ec7ace29162e447f6382c495dc95826bf931d3818799bbef11e8f7df1a/multidict-6.7.1-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3bd231490fa7217cc832528e1cd8752a96f0125ddd2b5749390f7c3ec8721b65", size = 242582, upload-time = "2026-01-26T02:44:48.604Z" }, + { url = "https://files.pythonhosted.org/packages/58/18/64f5a795e7677670e872673aca234162514696274597b3708b2c0d276cce/multidict-6.7.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:253282d70d67885a15c8a7716f3a73edf2d635793ceda8173b9ecc21f2fb8292", size = 250031, upload-time = "2026-01-26T02:44:50.544Z" }, + { url = "https://files.pythonhosted.org/packages/c8/ed/e192291dbbe51a8290c5686f482084d31bcd9d09af24f63358c3d42fd284/multidict-6.7.1-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0b4c48648d7649c9335cf1927a8b87fa692de3dcb15faa676c6a6f1f1aabda43", size = 228596, upload-time = "2026-01-26T02:44:51.951Z" }, + { url = "https://files.pythonhosted.org/packages/1e/7e/3562a15a60cf747397e7f2180b0a11dc0c38d9175a650e75fa1b4d325e15/multidict-6.7.1-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:98bc624954ec4d2c7cb074b8eefc2b5d0ce7d482e410df446414355d158fe4ca", size = 257492, upload-time = "2026-01-26T02:44:53.902Z" }, + { url = "https://files.pythonhosted.org/packages/24/02/7d0f9eae92b5249bb50ac1595b295f10e263dd0078ebb55115c31e0eaccd/multidict-6.7.1-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1b99af4d9eec0b49927b4402bcbb58dea89d3e0db8806a4086117019939ad3dd", size = 255899, upload-time = "2026-01-26T02:44:55.316Z" }, + { url = "https://files.pythonhosted.org/packages/00/e3/9b60ed9e23e64c73a5cde95269ef1330678e9c6e34dd4eb6b431b85b5a10/multidict-6.7.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6aac4f16b472d5b7dc6f66a0d49dd57b0e0902090be16594dc9ebfd3d17c47e7", size = 247970, upload-time = "2026-01-26T02:44:56.783Z" }, + { url = "https://files.pythonhosted.org/packages/3e/06/538e58a63ed5cfb0bd4517e346b91da32fde409d839720f664e9a4ae4f9d/multidict-6.7.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:21f830fe223215dffd51f538e78c172ed7c7f60c9b96a2bf05c4848ad49921c3", size = 245060, upload-time = "2026-01-26T02:44:58.195Z" }, + { url = "https://files.pythonhosted.org/packages/b2/2f/d743a3045a97c895d401e9bd29aaa09b94f5cbdf1bd561609e5a6c431c70/multidict-6.7.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:f5dd81c45b05518b9aa4da4aa74e1c93d715efa234fd3e8a179df611cc85e5f4", size = 235888, upload-time = "2026-01-26T02:44:59.57Z" }, + { url = "https://files.pythonhosted.org/packages/38/83/5a325cac191ab28b63c52f14f1131f3b0a55ba3b9aa65a6d0bf2a9b921a0/multidict-6.7.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:eb304767bca2bb92fb9c5bd33cedc95baee5bb5f6c88e63706533a1c06ad08c8", size = 243554, upload-time = "2026-01-26T02:45:01.054Z" }, + { url = "https://files.pythonhosted.org/packages/20/1f/9d2327086bd15da2725ef6aae624208e2ef828ed99892b17f60c344e57ed/multidict-6.7.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:c9035dde0f916702850ef66460bc4239d89d08df4d02023a5926e7446724212c", size = 252341, upload-time = "2026-01-26T02:45:02.484Z" }, + { url = "https://files.pythonhosted.org/packages/e8/2c/2a1aa0280cf579d0f6eed8ee5211c4f1730bd7e06c636ba2ee6aafda302e/multidict-6.7.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:af959b9beeb66c822380f222f0e0a1889331597e81f1ded7f374f3ecb0fd6c52", size = 246391, upload-time = "2026-01-26T02:45:03.862Z" }, + { url = "https://files.pythonhosted.org/packages/e5/03/7ca022ffc36c5a3f6e03b179a5ceb829be9da5783e6fe395f347c0794680/multidict-6.7.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:41f2952231456154ee479651491e94118229844dd7226541788be783be2b5108", size = 243422, upload-time = "2026-01-26T02:45:05.296Z" }, + { url = "https://files.pythonhosted.org/packages/dc/1d/b31650eab6c5778aceed46ba735bd97f7c7d2f54b319fa916c0f96e7805b/multidict-6.7.1-cp313-cp313t-win32.whl", hash = "sha256:df9f19c28adcb40b6aae30bbaa1478c389efd50c28d541d76760199fc1037c32", size = 47770, upload-time = "2026-01-26T02:45:06.754Z" }, + { url = "https://files.pythonhosted.org/packages/ac/5b/2d2d1d522e51285bd61b1e20df8f47ae1a9d80839db0b24ea783b3832832/multidict-6.7.1-cp313-cp313t-win_amd64.whl", hash = "sha256:d54ecf9f301853f2c5e802da559604b3e95bb7a3b01a9c295c6ee591b9882de8", size = 53109, upload-time = "2026-01-26T02:45:08.044Z" }, + { url = "https://files.pythonhosted.org/packages/3d/a3/cc409ba012c83ca024a308516703cf339bdc4b696195644a7215a5164a24/multidict-6.7.1-cp313-cp313t-win_arm64.whl", hash = "sha256:5a37ca18e360377cfda1d62f5f382ff41f2b8c4ccb329ed974cc2e1643440118", size = 45573, upload-time = "2026-01-26T02:45:09.349Z" }, + { url = "https://files.pythonhosted.org/packages/91/cc/db74228a8be41884a567e88a62fd589a913708fcf180d029898c17a9a371/multidict-6.7.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8f333ec9c5eb1b7105e3b84b53141e66ca05a19a605368c55450b6ba208cb9ee", size = 75190, upload-time = "2026-01-26T02:45:10.651Z" }, + { url = "https://files.pythonhosted.org/packages/d5/22/492f2246bb5b534abd44804292e81eeaf835388901f0c574bac4eeec73c5/multidict-6.7.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:a407f13c188f804c759fc6a9f88286a565c242a76b27626594c133b82883b5c2", size = 44486, upload-time = "2026-01-26T02:45:11.938Z" }, + { url = "https://files.pythonhosted.org/packages/f1/4f/733c48f270565d78b4544f2baddc2fb2a245e5a8640254b12c36ac7ac68e/multidict-6.7.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0e161ddf326db5577c3a4cc2d8648f81456e8a20d40415541587a71620d7a7d1", size = 43219, upload-time = "2026-01-26T02:45:14.346Z" }, + { url = "https://files.pythonhosted.org/packages/24/bb/2c0c2287963f4259c85e8bcbba9182ced8d7fca65c780c38e99e61629d11/multidict-6.7.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:1e3a8bb24342a8201d178c3b4984c26ba81a577c80d4d525727427460a50c22d", size = 245132, upload-time = "2026-01-26T02:45:15.712Z" }, + { url = "https://files.pythonhosted.org/packages/a7/f9/44d4b3064c65079d2467888794dea218d1601898ac50222ab8a9a8094460/multidict-6.7.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97231140a50f5d447d3164f994b86a0bed7cd016e2682f8650d6a9158e14fd31", size = 252420, upload-time = "2026-01-26T02:45:17.293Z" }, + { url = "https://files.pythonhosted.org/packages/8b/13/78f7275e73fa17b24c9a51b0bd9d73ba64bb32d0ed51b02a746eb876abe7/multidict-6.7.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6b10359683bd8806a200fd2909e7c8ca3a7b24ec1d8132e483d58e791d881048", size = 233510, upload-time = "2026-01-26T02:45:19.356Z" }, + { url = "https://files.pythonhosted.org/packages/4b/25/8167187f62ae3cbd52da7893f58cb036b47ea3fb67138787c76800158982/multidict-6.7.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:283ddac99f7ac25a4acadbf004cb5ae34480bbeb063520f70ce397b281859362", size = 264094, upload-time = "2026-01-26T02:45:20.834Z" }, + { url = "https://files.pythonhosted.org/packages/a1/e7/69a3a83b7b030cf283fb06ce074a05a02322359783424d7edf0f15fe5022/multidict-6.7.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:538cec1e18c067d0e6103aa9a74f9e832904c957adc260e61cd9d8cf0c3b3d37", size = 260786, upload-time = "2026-01-26T02:45:22.818Z" }, + { url = "https://files.pythonhosted.org/packages/fe/3b/8ec5074bcfc450fe84273713b4b0a0dd47c0249358f5d82eb8104ffe2520/multidict-6.7.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7eee46ccb30ff48a1e35bb818cc90846c6be2b68240e42a78599166722cea709", size = 248483, upload-time = "2026-01-26T02:45:24.368Z" }, + { url = "https://files.pythonhosted.org/packages/48/5a/d5a99e3acbca0e29c5d9cba8f92ceb15dce78bab963b308ae692981e3a5d/multidict-6.7.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fa263a02f4f2dd2d11a7b1bb4362aa7cb1049f84a9235d31adf63f30143469a0", size = 248403, upload-time = "2026-01-26T02:45:25.982Z" }, + { url = "https://files.pythonhosted.org/packages/35/48/e58cd31f6c7d5102f2a4bf89f96b9cf7e00b6c6f3d04ecc44417c00a5a3c/multidict-6.7.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:2e1425e2f99ec5bd36c15a01b690a1a2456209c5deed58f95469ffb46039ccbb", size = 240315, upload-time = "2026-01-26T02:45:27.487Z" }, + { url = "https://files.pythonhosted.org/packages/94/33/1cd210229559cb90b6786c30676bb0c58249ff42f942765f88793b41fdce/multidict-6.7.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:497394b3239fc6f0e13a78a3e1b61296e72bf1c5f94b4c4eb80b265c37a131cd", size = 245528, upload-time = "2026-01-26T02:45:28.991Z" }, + { url = "https://files.pythonhosted.org/packages/64/f2/6e1107d226278c876c783056b7db43d800bb64c6131cec9c8dfb6903698e/multidict-6.7.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:233b398c29d3f1b9676b4b6f75c518a06fcb2ea0b925119fb2c1bc35c05e1601", size = 258784, upload-time = "2026-01-26T02:45:30.503Z" }, + { url = "https://files.pythonhosted.org/packages/4d/c1/11f664f14d525e4a1b5327a82d4de61a1db604ab34c6603bb3c2cc63ad34/multidict-6.7.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:93b1818e4a6e0930454f0f2af7dfce69307ca03cdcfb3739bf4d91241967b6c1", size = 251980, upload-time = "2026-01-26T02:45:32.603Z" }, + { url = "https://files.pythonhosted.org/packages/e1/9f/75a9ac888121d0c5bbd4ecf4eead45668b1766f6baabfb3b7f66a410e231/multidict-6.7.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f33dc2a3abe9249ea5d8360f969ec7f4142e7ac45ee7014d8f8d5acddf178b7b", size = 243602, upload-time = "2026-01-26T02:45:34.043Z" }, + { url = "https://files.pythonhosted.org/packages/9a/e7/50bf7b004cc8525d80dbbbedfdc7aed3e4c323810890be4413e589074032/multidict-6.7.1-cp314-cp314-win32.whl", hash = "sha256:3ab8b9d8b75aef9df299595d5388b14530839f6422333357af1339443cff777d", size = 40930, upload-time = "2026-01-26T02:45:36.278Z" }, + { url = "https://files.pythonhosted.org/packages/e0/bf/52f25716bbe93745595800f36fb17b73711f14da59ed0bb2eba141bc9f0f/multidict-6.7.1-cp314-cp314-win_amd64.whl", hash = "sha256:5e01429a929600e7dab7b166062d9bb54a5eed752384c7384c968c2afab8f50f", size = 45074, upload-time = "2026-01-26T02:45:37.546Z" }, + { url = "https://files.pythonhosted.org/packages/97/ab/22803b03285fa3a525f48217963da3a65ae40f6a1b6f6cf2768879e208f9/multidict-6.7.1-cp314-cp314-win_arm64.whl", hash = "sha256:4885cb0e817aef5d00a2e8451d4665c1808378dc27c2705f1bf4ef8505c0d2e5", size = 42471, upload-time = "2026-01-26T02:45:38.889Z" }, + { url = "https://files.pythonhosted.org/packages/e0/6d/f9293baa6146ba9507e360ea0292b6422b016907c393e2f63fc40ab7b7b5/multidict-6.7.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:0458c978acd8e6ea53c81eefaddbbee9c6c5e591f41b3f5e8e194780fe026581", size = 82401, upload-time = "2026-01-26T02:45:40.254Z" }, + { url = "https://files.pythonhosted.org/packages/7a/68/53b5494738d83558d87c3c71a486504d8373421c3e0dbb6d0db48ad42ee0/multidict-6.7.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:c0abd12629b0af3cf590982c0b413b1e7395cd4ec026f30986818ab95bfaa94a", size = 48143, upload-time = "2026-01-26T02:45:41.635Z" }, + { url = "https://files.pythonhosted.org/packages/37/e8/5284c53310dcdc99ce5d66563f6e5773531a9b9fe9ec7a615e9bc306b05f/multidict-6.7.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:14525a5f61d7d0c94b368a42cff4c9a4e7ba2d52e2672a7b23d84dc86fb02b0c", size = 46507, upload-time = "2026-01-26T02:45:42.99Z" }, + { url = "https://files.pythonhosted.org/packages/e4/fc/6800d0e5b3875568b4083ecf5f310dcf91d86d52573160834fb4bfcf5e4f/multidict-6.7.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:17307b22c217b4cf05033dabefe68255a534d637c6c9b0cc8382718f87be4262", size = 239358, upload-time = "2026-01-26T02:45:44.376Z" }, + { url = "https://files.pythonhosted.org/packages/41/75/4ad0973179361cdf3a113905e6e088173198349131be2b390f9fa4da5fc6/multidict-6.7.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7a7e590ff876a3eaf1c02a4dfe0724b6e69a9e9de6d8f556816f29c496046e59", size = 246884, upload-time = "2026-01-26T02:45:47.167Z" }, + { url = "https://files.pythonhosted.org/packages/c3/9c/095bb28b5da139bd41fb9a5d5caff412584f377914bd8787c2aa98717130/multidict-6.7.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5fa6a95dfee63893d80a34758cd0e0c118a30b8dcb46372bf75106c591b77889", size = 225878, upload-time = "2026-01-26T02:45:48.698Z" }, + { url = "https://files.pythonhosted.org/packages/07/d0/c0a72000243756e8f5a277b6b514fa005f2c73d481b7d9e47cd4568aa2e4/multidict-6.7.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a0543217a6a017692aa6ae5cc39adb75e587af0f3a82288b1492eb73dd6cc2a4", size = 253542, upload-time = "2026-01-26T02:45:50.164Z" }, + { url = "https://files.pythonhosted.org/packages/c0/6b/f69da15289e384ecf2a68837ec8b5ad8c33e973aa18b266f50fe55f24b8c/multidict-6.7.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f99fe611c312b3c1c0ace793f92464d8cd263cc3b26b5721950d977b006b6c4d", size = 252403, upload-time = "2026-01-26T02:45:51.779Z" }, + { url = "https://files.pythonhosted.org/packages/a2/76/b9669547afa5a1a25cd93eaca91c0da1c095b06b6d2d8ec25b713588d3a1/multidict-6.7.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9004d8386d133b7e6135679424c91b0b854d2d164af6ea3f289f8f2761064609", size = 244889, upload-time = "2026-01-26T02:45:53.27Z" }, + { url = "https://files.pythonhosted.org/packages/7e/a9/a50d2669e506dad33cfc45b5d574a205587b7b8a5f426f2fbb2e90882588/multidict-6.7.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e628ef0e6859ffd8273c69412a2465c4be4a9517d07261b33334b5ec6f3c7489", size = 241982, upload-time = "2026-01-26T02:45:54.919Z" }, + { url = "https://files.pythonhosted.org/packages/c5/bb/1609558ad8b456b4827d3c5a5b775c93b87878fd3117ed3db3423dfbce1b/multidict-6.7.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:841189848ba629c3552035a6a7f5bf3b02eb304e9fea7492ca220a8eda6b0e5c", size = 232415, upload-time = "2026-01-26T02:45:56.981Z" }, + { url = "https://files.pythonhosted.org/packages/d8/59/6f61039d2aa9261871e03ab9dc058a550d240f25859b05b67fd70f80d4b3/multidict-6.7.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:ce1bbd7d780bb5a0da032e095c951f7014d6b0a205f8318308140f1a6aba159e", size = 240337, upload-time = "2026-01-26T02:45:58.698Z" }, + { url = "https://files.pythonhosted.org/packages/a1/29/fdc6a43c203890dc2ae9249971ecd0c41deaedfe00d25cb6564b2edd99eb/multidict-6.7.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b26684587228afed0d50cf804cc71062cc9c1cdf55051c4c6345d372947b268c", size = 248788, upload-time = "2026-01-26T02:46:00.862Z" }, + { url = "https://files.pythonhosted.org/packages/a9/14/a153a06101323e4cf086ecee3faadba52ff71633d471f9685c42e3736163/multidict-6.7.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:9f9af11306994335398293f9958071019e3ab95e9a707dc1383a35613f6abcb9", size = 242842, upload-time = "2026-01-26T02:46:02.824Z" }, + { url = "https://files.pythonhosted.org/packages/41/5f/604ae839e64a4a6efc80db94465348d3b328ee955e37acb24badbcd24d83/multidict-6.7.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b4938326284c4f1224178a560987b6cf8b4d38458b113d9b8c1db1a836e640a2", size = 240237, upload-time = "2026-01-26T02:46:05.898Z" }, + { url = "https://files.pythonhosted.org/packages/5f/60/c3a5187bf66f6fb546ff4ab8fb5a077cbdd832d7b1908d4365c7f74a1917/multidict-6.7.1-cp314-cp314t-win32.whl", hash = "sha256:98655c737850c064a65e006a3df7c997cd3b220be4ec8fe26215760b9697d4d7", size = 48008, upload-time = "2026-01-26T02:46:07.468Z" }, + { url = "https://files.pythonhosted.org/packages/0c/f7/addf1087b860ac60e6f382240f64fb99f8bfb532bb06f7c542b83c29ca61/multidict-6.7.1-cp314-cp314t-win_amd64.whl", hash = "sha256:497bde6223c212ba11d462853cfa4f0ae6ef97465033e7dc9940cdb3ab5b48e5", size = 53542, upload-time = "2026-01-26T02:46:08.809Z" }, + { url = "https://files.pythonhosted.org/packages/4c/81/4629d0aa32302ef7b2ec65c75a728cc5ff4fa410c50096174c1632e70b3e/multidict-6.7.1-cp314-cp314t-win_arm64.whl", hash = "sha256:2bbd113e0d4af5db41d5ebfe9ccaff89de2120578164f86a5d17d5a576d1e5b2", size = 44719, upload-time = "2026-01-26T02:46:11.146Z" }, + { url = "https://files.pythonhosted.org/packages/9e/ee/74525ebe3eb5fddcd6735fc03cbea3feeed4122b53bc798ac32d297ac9ae/multidict-6.7.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:65573858d27cdeaca41893185677dc82395159aa28875a8867af66532d413a8f", size = 77107, upload-time = "2026-01-26T02:46:12.608Z" }, + { url = "https://files.pythonhosted.org/packages/f0/9a/ce8744e777a74b3050b1bf56be3eed1053b3457302ea055f1ea437200a23/multidict-6.7.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c524c6fb8fc342793708ab111c4dbc90ff9abd568de220432500e47e990c0358", size = 44943, upload-time = "2026-01-26T02:46:14.016Z" }, + { url = "https://files.pythonhosted.org/packages/83/9c/1d2a283d9c6f31e260cb6c2fccadc3edcf6c4c14ee0929cd2af4d2606dd7/multidict-6.7.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aa23b001d968faef416ff70dc0f1ab045517b9b42a90edd3e9bcdb06479e31d5", size = 44603, upload-time = "2026-01-26T02:46:15.391Z" }, + { url = "https://files.pythonhosted.org/packages/87/9d/3b186201671583d8e8d6d79c07481a5aafd0ba7575e3d8566baec80c1e82/multidict-6.7.1-cp39-cp39-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:6704fa2b7453b2fb121740555fa1ee20cd98c4d011120caf4d2b8d4e7c76eec0", size = 240573, upload-time = "2026-01-26T02:46:16.783Z" }, + { url = "https://files.pythonhosted.org/packages/42/7d/a52f5d4d0754311d1ac78478e34dff88de71259a8585e05ee14e5f877caf/multidict-6.7.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:121a34e5bfa410cdf2c8c49716de160de3b1dbcd86b49656f5681e4543bcd1a8", size = 240106, upload-time = "2026-01-26T02:46:18.432Z" }, + { url = "https://files.pythonhosted.org/packages/84/9f/d80118e6c30ff55b7d171bdc5520aad4b9626e657520b8d7c8ca8c2fad12/multidict-6.7.1-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:026d264228bcd637d4e060844e39cdc60f86c479e463d49075dedc21b18fbbe0", size = 219418, upload-time = "2026-01-26T02:46:20.526Z" }, + { url = "https://files.pythonhosted.org/packages/c7/bd/896e60b3457f194de77c7de64f9acce9f75da0518a5230ce1df534f6747b/multidict-6.7.1-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0e697826df7eb63418ee190fd06ce9f1803593bb4b9517d08c60d9b9a7f69d8f", size = 252124, upload-time = "2026-01-26T02:46:22.157Z" }, + { url = "https://files.pythonhosted.org/packages/f4/de/ba6b30447c36a37078d0ba604aa12c1a52887af0c355236ca6e0a9d5286f/multidict-6.7.1-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bb08271280173720e9fea9ede98e5231defcbad90f1624bea26f32ec8a956e2f", size = 249402, upload-time = "2026-01-26T02:46:23.718Z" }, + { url = "https://files.pythonhosted.org/packages/c2/b2/50a383c96230e432895a2fd3bcfe1b65785899598259d871d5de6b93180c/multidict-6.7.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c6b3228e1d80af737b72925ce5fb4daf5a335e49cd7ab77ed7b9fdfbf58c526e", size = 240346, upload-time = "2026-01-26T02:46:25.393Z" }, + { url = "https://files.pythonhosted.org/packages/89/37/16d391fd8da544b1489306e38a46785fa41dd0f0ef766837ed7d4676dde0/multidict-6.7.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:3943debf0fbb57bdde5901695c11094a9a36723e5c03875f87718ee15ca2f4d2", size = 237010, upload-time = "2026-01-26T02:46:27.408Z" }, + { url = "https://files.pythonhosted.org/packages/b0/24/3152ee026eda86d5d3e3685182911e6951af7a016579da931080ce6ac9ad/multidict-6.7.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:98c5787b0a0d9a41d9311eae44c3b76e6753def8d8870ab501320efe75a6a5f8", size = 232018, upload-time = "2026-01-26T02:46:29.941Z" }, + { url = "https://files.pythonhosted.org/packages/9c/1f/48d3c27a72be7fd23a55d8847193c459959bf35a5bb5844530dab00b739b/multidict-6.7.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:08ccb2a6dc72009093ebe7f3f073e5ec5964cba9a706fa94b1a1484039b87941", size = 241498, upload-time = "2026-01-26T02:46:32.052Z" }, + { url = "https://files.pythonhosted.org/packages/1a/45/413643ae2952d0decdf6c1250f86d08a43e143271441e81027e38d598bd7/multidict-6.7.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:eb351f72c26dc9abe338ca7294661aa22969ad8ffe7ef7d5541d19f368dc854a", size = 247957, upload-time = "2026-01-26T02:46:33.666Z" }, + { url = "https://files.pythonhosted.org/packages/50/f8/f1d0ac23df15e0470776388bdb261506f63af1f81d28bacb5e262d6e12b6/multidict-6.7.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ac1c665bad8b5d762f5f85ebe4d94130c26965f11de70c708c75671297c776de", size = 241651, upload-time = "2026-01-26T02:46:35.7Z" }, + { url = "https://files.pythonhosted.org/packages/2c/c9/1a2a18f383cf129add66b6c36b75c3911a7ba95cf26cb141482de085cc12/multidict-6.7.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1fa6609d0364f4f6f58351b4659a1f3e0e898ba2a8c5cac04cb2c7bc556b0bc5", size = 236371, upload-time = "2026-01-26T02:46:37.37Z" }, + { url = "https://files.pythonhosted.org/packages/bb/aa/77d87e3fca31325b87e0eb72d5fe9a7472dcb51391a42df7ac1f3842f6c0/multidict-6.7.1-cp39-cp39-win32.whl", hash = "sha256:6f77ce314a29263e67adadc7e7c1bc699fcb3a305059ab973d038f87caa42ed0", size = 41426, upload-time = "2026-01-26T02:46:39.026Z" }, + { url = "https://files.pythonhosted.org/packages/e3/b3/e8863e6a2da15a9d7e98976ff402e871b7352c76566df6c18d0378e0d9cf/multidict-6.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:f537b55778cd3cbee430abe3131255d3a78202e0f9ea7ffc6ada893a4bcaeea4", size = 46180, upload-time = "2026-01-26T02:46:40.422Z" }, + { url = "https://files.pythonhosted.org/packages/93/d3/dd4fa951ad5b5fa216bf30054d705683d13405eea7459833d78f31b74c9c/multidict-6.7.1-cp39-cp39-win_arm64.whl", hash = "sha256:749aa54f578f2e5f439538706a475aa844bfa8ef75854b1401e6e528e4937cf9", size = 43231, upload-time = "2026-01-26T02:46:41.945Z" }, + { url = "https://files.pythonhosted.org/packages/81/08/7036c080d7117f28a4af526d794aab6a84463126db031b007717c1a6676e/multidict-6.7.1-py3-none-any.whl", hash = "sha256:55d97cc6dae627efa6a6e548885712d4864b81110ac76fa4e534c03819fa4a56", size = 12319, upload-time = "2026-01-26T02:46:44.004Z" }, +] + +[[package]] +name = "mypy" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mypy-extensions" }, + { name = "pathspec" }, + { name = "tomli", marker = "python_full_version < '3.11' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1e/e3/034322d5a779685218ed69286c32faa505247f1f096251ef66c8fd203b08/mypy-1.17.0.tar.gz", hash = "sha256:e5d7ccc08ba089c06e2f5629c660388ef1fee708444f1dee0b9203fa031dee03", size = 3352114, upload-time = "2025-07-14T20:34:30.181Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/31/e762baa3b73905c856d45ab77b4af850e8159dffffd86a52879539a08c6b/mypy-1.17.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f8e08de6138043108b3b18f09d3f817a4783912e48828ab397ecf183135d84d6", size = 10998313, upload-time = "2025-07-14T20:33:24.519Z" }, + { url = "https://files.pythonhosted.org/packages/1c/c1/25b2f0d46fb7e0b5e2bee61ec3a47fe13eff9e3c2f2234f144858bbe6485/mypy-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ce4a17920ec144647d448fc43725b5873548b1aae6c603225626747ededf582d", size = 10128922, upload-time = "2025-07-14T20:34:06.414Z" }, + { url = "https://files.pythonhosted.org/packages/02/78/6d646603a57aa8a2886df1b8881fe777ea60f28098790c1089230cd9c61d/mypy-1.17.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6ff25d151cc057fdddb1cb1881ef36e9c41fa2a5e78d8dd71bee6e4dcd2bc05b", size = 11913524, upload-time = "2025-07-14T20:33:19.109Z" }, + { url = "https://files.pythonhosted.org/packages/4f/19/dae6c55e87ee426fb76980f7e78484450cad1c01c55a1dc4e91c930bea01/mypy-1.17.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93468cf29aa9a132bceb103bd8475f78cacde2b1b9a94fd978d50d4bdf616c9a", size = 12650527, upload-time = "2025-07-14T20:32:44.095Z" }, + { url = "https://files.pythonhosted.org/packages/86/e1/f916845a235235a6c1e4d4d065a3930113767001d491b8b2e1b61ca56647/mypy-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:98189382b310f16343151f65dd7e6867386d3e35f7878c45cfa11383d175d91f", size = 12897284, upload-time = "2025-07-14T20:33:38.168Z" }, + { url = "https://files.pythonhosted.org/packages/ae/dc/414760708a4ea1b096bd214d26a24e30ac5e917ef293bc33cdb6fe22d2da/mypy-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:c004135a300ab06a045c1c0d8e3f10215e71d7b4f5bb9a42ab80236364429937", size = 9506493, upload-time = "2025-07-14T20:34:01.093Z" }, + { url = "https://files.pythonhosted.org/packages/d4/24/82efb502b0b0f661c49aa21cfe3e1999ddf64bf5500fc03b5a1536a39d39/mypy-1.17.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9d4fe5c72fd262d9c2c91c1117d16aac555e05f5beb2bae6a755274c6eec42be", size = 10914150, upload-time = "2025-07-14T20:31:51.985Z" }, + { url = "https://files.pythonhosted.org/packages/03/96/8ef9a6ff8cedadff4400e2254689ca1dc4b420b92c55255b44573de10c54/mypy-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d96b196e5c16f41b4f7736840e8455958e832871990c7ba26bf58175e357ed61", size = 10039845, upload-time = "2025-07-14T20:32:30.527Z" }, + { url = "https://files.pythonhosted.org/packages/df/32/7ce359a56be779d38021d07941cfbb099b41411d72d827230a36203dbb81/mypy-1.17.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:73a0ff2dd10337ceb521c080d4147755ee302dcde6e1a913babd59473904615f", size = 11837246, upload-time = "2025-07-14T20:32:01.28Z" }, + { url = "https://files.pythonhosted.org/packages/82/16/b775047054de4d8dbd668df9137707e54b07fe18c7923839cd1e524bf756/mypy-1.17.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:24cfcc1179c4447854e9e406d3af0f77736d631ec87d31c6281ecd5025df625d", size = 12571106, upload-time = "2025-07-14T20:34:26.942Z" }, + { url = "https://files.pythonhosted.org/packages/a1/cf/fa33eaf29a606102c8d9ffa45a386a04c2203d9ad18bf4eef3e20c43ebc8/mypy-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3c56f180ff6430e6373db7a1d569317675b0a451caf5fef6ce4ab365f5f2f6c3", size = 12759960, upload-time = "2025-07-14T20:33:42.882Z" }, + { url = "https://files.pythonhosted.org/packages/94/75/3f5a29209f27e739ca57e6350bc6b783a38c7621bdf9cac3ab8a08665801/mypy-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:eafaf8b9252734400f9b77df98b4eee3d2eecab16104680d51341c75702cad70", size = 9503888, upload-time = "2025-07-14T20:32:34.392Z" }, + { url = "https://files.pythonhosted.org/packages/12/e9/e6824ed620bbf51d3bf4d6cbbe4953e83eaf31a448d1b3cfb3620ccb641c/mypy-1.17.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f986f1cab8dbec39ba6e0eaa42d4d3ac6686516a5d3dccd64be095db05ebc6bb", size = 11086395, upload-time = "2025-07-14T20:34:11.452Z" }, + { url = "https://files.pythonhosted.org/packages/ba/51/a4afd1ae279707953be175d303f04a5a7bd7e28dc62463ad29c1c857927e/mypy-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:51e455a54d199dd6e931cd7ea987d061c2afbaf0960f7f66deef47c90d1b304d", size = 10120052, upload-time = "2025-07-14T20:33:09.897Z" }, + { url = "https://files.pythonhosted.org/packages/8a/71/19adfeac926ba8205f1d1466d0d360d07b46486bf64360c54cb5a2bd86a8/mypy-1.17.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3204d773bab5ff4ebbd1f8efa11b498027cd57017c003ae970f310e5b96be8d8", size = 11861806, upload-time = "2025-07-14T20:32:16.028Z" }, + { url = "https://files.pythonhosted.org/packages/0b/64/d6120eca3835baf7179e6797a0b61d6c47e0bc2324b1f6819d8428d5b9ba/mypy-1.17.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1051df7ec0886fa246a530ae917c473491e9a0ba6938cfd0ec2abc1076495c3e", size = 12744371, upload-time = "2025-07-14T20:33:33.503Z" }, + { url = "https://files.pythonhosted.org/packages/1f/dc/56f53b5255a166f5bd0f137eed960e5065f2744509dfe69474ff0ba772a5/mypy-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f773c6d14dcc108a5b141b4456b0871df638eb411a89cd1c0c001fc4a9d08fc8", size = 12914558, upload-time = "2025-07-14T20:33:56.961Z" }, + { url = "https://files.pythonhosted.org/packages/69/ac/070bad311171badc9add2910e7f89271695a25c136de24bbafc7eded56d5/mypy-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:1619a485fd0e9c959b943c7b519ed26b712de3002d7de43154a489a2d0fd817d", size = 9585447, upload-time = "2025-07-14T20:32:20.594Z" }, + { url = "https://files.pythonhosted.org/packages/be/7b/5f8ab461369b9e62157072156935cec9d272196556bdc7c2ff5f4c7c0f9b/mypy-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2c41aa59211e49d717d92b3bb1238c06d387c9325d3122085113c79118bebb06", size = 11070019, upload-time = "2025-07-14T20:32:07.99Z" }, + { url = "https://files.pythonhosted.org/packages/9c/f8/c49c9e5a2ac0badcc54beb24e774d2499748302c9568f7f09e8730e953fa/mypy-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0e69db1fb65b3114f98c753e3930a00514f5b68794ba80590eb02090d54a5d4a", size = 10114457, upload-time = "2025-07-14T20:33:47.285Z" }, + { url = "https://files.pythonhosted.org/packages/89/0c/fb3f9c939ad9beed3e328008b3fb90b20fda2cddc0f7e4c20dbefefc3b33/mypy-1.17.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:03ba330b76710f83d6ac500053f7727270b6b8553b0423348ffb3af6f2f7b889", size = 11857838, upload-time = "2025-07-14T20:33:14.462Z" }, + { url = "https://files.pythonhosted.org/packages/4c/66/85607ab5137d65e4f54d9797b77d5a038ef34f714929cf8ad30b03f628df/mypy-1.17.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:037bc0f0b124ce46bfde955c647f3e395c6174476a968c0f22c95a8d2f589bba", size = 12731358, upload-time = "2025-07-14T20:32:25.579Z" }, + { url = "https://files.pythonhosted.org/packages/73/d0/341dbbfb35ce53d01f8f2969facbb66486cee9804048bf6c01b048127501/mypy-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c38876106cb6132259683632b287238858bd58de267d80defb6f418e9ee50658", size = 12917480, upload-time = "2025-07-14T20:34:21.868Z" }, + { url = "https://files.pythonhosted.org/packages/64/63/70c8b7dbfc520089ac48d01367a97e8acd734f65bd07813081f508a8c94c/mypy-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:d30ba01c0f151998f367506fab31c2ac4527e6a7b2690107c7a7f9e3cb419a9c", size = 9589666, upload-time = "2025-07-14T20:34:16.841Z" }, + { url = "https://files.pythonhosted.org/packages/9f/a0/6263dd11941231f688f0a8f2faf90ceac1dc243d148d314a089d2fe25108/mypy-1.17.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:63e751f1b5ab51d6f3d219fe3a2fe4523eaa387d854ad06906c63883fde5b1ab", size = 10988185, upload-time = "2025-07-14T20:33:04.797Z" }, + { url = "https://files.pythonhosted.org/packages/02/13/b8f16d6b0dc80277129559c8e7dbc9011241a0da8f60d031edb0e6e9ac8f/mypy-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f7fb09d05e0f1c329a36dcd30e27564a3555717cde87301fae4fb542402ddfad", size = 10120169, upload-time = "2025-07-14T20:32:38.84Z" }, + { url = "https://files.pythonhosted.org/packages/14/ef/978ba79df0d65af680e20d43121363cf643eb79b04bf3880d01fc8afeb6f/mypy-1.17.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b72c34ce05ac3a1361ae2ebb50757fb6e3624032d91488d93544e9f82db0ed6c", size = 11918121, upload-time = "2025-07-14T20:33:52.328Z" }, + { url = "https://files.pythonhosted.org/packages/f4/10/55ef70b104151a0d8280474f05268ff0a2a79be8d788d5e647257d121309/mypy-1.17.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:434ad499ad8dde8b2f6391ddfa982f41cb07ccda8e3c67781b1bfd4e5f9450a8", size = 12648821, upload-time = "2025-07-14T20:32:59.631Z" }, + { url = "https://files.pythonhosted.org/packages/26/8c/7781fcd2e1eef48fbedd3a422c21fe300a8e03ed5be2eb4bd10246a77f4e/mypy-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f105f61a5eff52e137fd73bee32958b2add9d9f0a856f17314018646af838e97", size = 12896955, upload-time = "2025-07-14T20:32:49.543Z" }, + { url = "https://files.pythonhosted.org/packages/78/13/03ac759dabe86e98ca7b6681f114f90ee03f3ff8365a57049d311bd4a4e3/mypy-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:ba06254a5a22729853209550d80f94e28690d5530c661f9416a68ac097b13fc4", size = 9512957, upload-time = "2025-07-14T20:33:28.619Z" }, + { url = "https://files.pythonhosted.org/packages/e3/fc/ee058cc4316f219078464555873e99d170bde1d9569abd833300dbeb484a/mypy-1.17.0-py3-none-any.whl", hash = "sha256:15d9d0018237ab058e5de3d8fce61b6fa72cc59cc78fd91f1b474bce12abf496", size = 2283195, upload-time = "2025-07-14T20:31:54.753Z" }, +] + +[[package]] +name = "mypy-extensions" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, +] + +[[package]] +name = "nodeenv" +version = "1.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/24/bf/d1bda4f6168e0b2e9e5958945e01910052158313224ada5ce1fb2e1113b8/nodeenv-1.10.0.tar.gz", hash = "sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb", size = 55611, upload-time = "2025-12-20T14:08:54.006Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438, upload-time = "2025-12-20T14:08:52.782Z" }, +] + +[[package]] +name = "packaging" +version = "26.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, +] + +[[package]] +name = "pathspec" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5a/82/42f767fc1c1143d6fd36efb827202a2d997a375e160a71eb2888a925aac1/pathspec-1.1.1.tar.gz", hash = "sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a", size = 135180, upload-time = "2026-04-27T01:46:08.907Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl", hash = "sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189", size = 57328, upload-time = "2026-04-27T01:46:07.06Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "propcache" +version = "0.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9e/da/e9fc233cf63743258bff22b3dfa7ea5baef7b5bc324af47a0ad89b8ffc6f/propcache-0.4.1.tar.gz", hash = "sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d", size = 46442, upload-time = "2025-10-08T19:49:02.291Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/0e/934b541323035566a9af292dba85a195f7b78179114f2c6ebb24551118a9/propcache-0.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7c2d1fa3201efaf55d730400d945b5b3ab6e672e100ba0f9a409d950ab25d7db", size = 79534, upload-time = "2025-10-08T19:46:02.083Z" }, + { url = "https://files.pythonhosted.org/packages/a1/6b/db0d03d96726d995dc7171286c6ba9d8d14251f37433890f88368951a44e/propcache-0.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1eb2994229cc8ce7fe9b3db88f5465f5fd8651672840b2e426b88cdb1a30aac8", size = 45526, upload-time = "2025-10-08T19:46:03.884Z" }, + { url = "https://files.pythonhosted.org/packages/e4/c3/82728404aea669e1600f304f2609cde9e665c18df5a11cdd57ed73c1dceb/propcache-0.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:66c1f011f45a3b33d7bcb22daed4b29c0c9e2224758b6be00686731e1b46f925", size = 47263, upload-time = "2025-10-08T19:46:05.405Z" }, + { url = "https://files.pythonhosted.org/packages/df/1b/39313ddad2bf9187a1432654c38249bab4562ef535ef07f5eb6eb04d0b1b/propcache-0.4.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9a52009f2adffe195d0b605c25ec929d26b36ef986ba85244891dee3b294df21", size = 201012, upload-time = "2025-10-08T19:46:07.165Z" }, + { url = "https://files.pythonhosted.org/packages/5b/01/f1d0b57d136f294a142acf97f4ed58c8e5b974c21e543000968357115011/propcache-0.4.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5d4e2366a9c7b837555cf02fb9be2e3167d333aff716332ef1b7c3a142ec40c5", size = 209491, upload-time = "2025-10-08T19:46:08.909Z" }, + { url = "https://files.pythonhosted.org/packages/a1/c8/038d909c61c5bb039070b3fb02ad5cccdb1dde0d714792e251cdb17c9c05/propcache-0.4.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9d2b6caef873b4f09e26ea7e33d65f42b944837563a47a94719cc3544319a0db", size = 215319, upload-time = "2025-10-08T19:46:10.7Z" }, + { url = "https://files.pythonhosted.org/packages/08/57/8c87e93142b2c1fa2408e45695205a7ba05fb5db458c0bf5c06ba0e09ea6/propcache-0.4.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2b16ec437a8c8a965ecf95739448dd938b5c7f56e67ea009f4300d8df05f32b7", size = 196856, upload-time = "2025-10-08T19:46:12.003Z" }, + { url = "https://files.pythonhosted.org/packages/42/df/5615fec76aa561987a534759b3686008a288e73107faa49a8ae5795a9f7a/propcache-0.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:296f4c8ed03ca7476813fe666c9ea97869a8d7aec972618671b33a38a5182ef4", size = 193241, upload-time = "2025-10-08T19:46:13.495Z" }, + { url = "https://files.pythonhosted.org/packages/d5/21/62949eb3a7a54afe8327011c90aca7e03547787a88fb8bd9726806482fea/propcache-0.4.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:1f0978529a418ebd1f49dad413a2b68af33f85d5c5ca5c6ca2a3bed375a7ac60", size = 190552, upload-time = "2025-10-08T19:46:14.938Z" }, + { url = "https://files.pythonhosted.org/packages/30/ee/ab4d727dd70806e5b4de96a798ae7ac6e4d42516f030ee60522474b6b332/propcache-0.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fd138803047fb4c062b1c1dd95462f5209456bfab55c734458f15d11da288f8f", size = 200113, upload-time = "2025-10-08T19:46:16.695Z" }, + { url = "https://files.pythonhosted.org/packages/8a/0b/38b46208e6711b016aa8966a3ac793eee0d05c7159d8342aa27fc0bc365e/propcache-0.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8c9b3cbe4584636d72ff556d9036e0c9317fa27b3ac1f0f558e7e84d1c9c5900", size = 200778, upload-time = "2025-10-08T19:46:18.023Z" }, + { url = "https://files.pythonhosted.org/packages/cf/81/5abec54355ed344476bee711e9f04815d4b00a311ab0535599204eecc257/propcache-0.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f93243fdc5657247533273ac4f86ae106cc6445a0efacb9a1bfe982fcfefd90c", size = 193047, upload-time = "2025-10-08T19:46:19.449Z" }, + { url = "https://files.pythonhosted.org/packages/ec/b6/1f237c04e32063cb034acd5f6ef34ef3a394f75502e72703545631ab1ef6/propcache-0.4.1-cp310-cp310-win32.whl", hash = "sha256:a0ee98db9c5f80785b266eb805016e36058ac72c51a064040f2bc43b61101cdb", size = 38093, upload-time = "2025-10-08T19:46:20.643Z" }, + { url = "https://files.pythonhosted.org/packages/a6/67/354aac4e0603a15f76439caf0427781bcd6797f370377f75a642133bc954/propcache-0.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:1cdb7988c4e5ac7f6d175a28a9aa0c94cb6f2ebe52756a3c0cda98d2809a9e37", size = 41638, upload-time = "2025-10-08T19:46:21.935Z" }, + { url = "https://files.pythonhosted.org/packages/e0/e1/74e55b9fd1a4c209ff1a9a824bf6c8b3d1fc5a1ac3eabe23462637466785/propcache-0.4.1-cp310-cp310-win_arm64.whl", hash = "sha256:d82ad62b19645419fe79dd63b3f9253e15b30e955c0170e5cebc350c1844e581", size = 38229, upload-time = "2025-10-08T19:46:23.368Z" }, + { url = "https://files.pythonhosted.org/packages/8c/d4/4e2c9aaf7ac2242b9358f98dccd8f90f2605402f5afeff6c578682c2c491/propcache-0.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:60a8fda9644b7dfd5dece8c61d8a85e271cb958075bfc4e01083c148b61a7caf", size = 80208, upload-time = "2025-10-08T19:46:24.597Z" }, + { url = "https://files.pythonhosted.org/packages/c2/21/d7b68e911f9c8e18e4ae43bdbc1e1e9bbd971f8866eb81608947b6f585ff/propcache-0.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c30b53e7e6bda1d547cabb47c825f3843a0a1a42b0496087bb58d8fedf9f41b5", size = 45777, upload-time = "2025-10-08T19:46:25.733Z" }, + { url = "https://files.pythonhosted.org/packages/d3/1d/11605e99ac8ea9435651ee71ab4cb4bf03f0949586246476a25aadfec54a/propcache-0.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e", size = 47647, upload-time = "2025-10-08T19:46:27.304Z" }, + { url = "https://files.pythonhosted.org/packages/58/1a/3c62c127a8466c9c843bccb503d40a273e5cc69838805f322e2826509e0d/propcache-0.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3d902a36df4e5989763425a8ab9e98cd8ad5c52c823b34ee7ef307fd50582566", size = 214929, upload-time = "2025-10-08T19:46:28.62Z" }, + { url = "https://files.pythonhosted.org/packages/56/b9/8fa98f850960b367c4b8fe0592e7fc341daa7a9462e925228f10a60cf74f/propcache-0.4.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a9695397f85973bb40427dedddf70d8dc4a44b22f1650dd4af9eedf443d45165", size = 221778, upload-time = "2025-10-08T19:46:30.358Z" }, + { url = "https://files.pythonhosted.org/packages/46/a6/0ab4f660eb59649d14b3d3d65c439421cf2f87fe5dd68591cbe3c1e78a89/propcache-0.4.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2bb07ffd7eaad486576430c89f9b215f9e4be68c4866a96e97db9e97fead85dc", size = 228144, upload-time = "2025-10-08T19:46:32.607Z" }, + { url = "https://files.pythonhosted.org/packages/52/6a/57f43e054fb3d3a56ac9fc532bc684fc6169a26c75c353e65425b3e56eef/propcache-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fd6f30fdcf9ae2a70abd34da54f18da086160e4d7d9251f81f3da0ff84fc5a48", size = 210030, upload-time = "2025-10-08T19:46:33.969Z" }, + { url = "https://files.pythonhosted.org/packages/40/e2/27e6feebb5f6b8408fa29f5efbb765cd54c153ac77314d27e457a3e993b7/propcache-0.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fc38cba02d1acba4e2869eef1a57a43dfbd3d49a59bf90dda7444ec2be6a5570", size = 208252, upload-time = "2025-10-08T19:46:35.309Z" }, + { url = "https://files.pythonhosted.org/packages/9e/f8/91c27b22ccda1dbc7967f921c42825564fa5336a01ecd72eb78a9f4f53c2/propcache-0.4.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:67fad6162281e80e882fb3ec355398cf72864a54069d060321f6cd0ade95fe85", size = 202064, upload-time = "2025-10-08T19:46:36.993Z" }, + { url = "https://files.pythonhosted.org/packages/f2/26/7f00bd6bd1adba5aafe5f4a66390f243acab58eab24ff1a08bebb2ef9d40/propcache-0.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f10207adf04d08bec185bae14d9606a1444715bc99180f9331c9c02093e1959e", size = 212429, upload-time = "2025-10-08T19:46:38.398Z" }, + { url = "https://files.pythonhosted.org/packages/84/89/fd108ba7815c1117ddca79c228f3f8a15fc82a73bca8b142eb5de13b2785/propcache-0.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e9b0d8d0845bbc4cfcdcbcdbf5086886bc8157aa963c31c777ceff7846c77757", size = 216727, upload-time = "2025-10-08T19:46:39.732Z" }, + { url = "https://files.pythonhosted.org/packages/79/37/3ec3f7e3173e73f1d600495d8b545b53802cbf35506e5732dd8578db3724/propcache-0.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:981333cb2f4c1896a12f4ab92a9cc8f09ea664e9b7dbdc4eff74627af3a11c0f", size = 205097, upload-time = "2025-10-08T19:46:41.025Z" }, + { url = "https://files.pythonhosted.org/packages/61/b0/b2631c19793f869d35f47d5a3a56fb19e9160d3c119f15ac7344fc3ccae7/propcache-0.4.1-cp311-cp311-win32.whl", hash = "sha256:f1d2f90aeec838a52f1c1a32fe9a619fefd5e411721a9117fbf82aea638fe8a1", size = 38084, upload-time = "2025-10-08T19:46:42.693Z" }, + { url = "https://files.pythonhosted.org/packages/f4/78/6cce448e2098e9f3bfc91bb877f06aa24b6ccace872e39c53b2f707c4648/propcache-0.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6", size = 41637, upload-time = "2025-10-08T19:46:43.778Z" }, + { url = "https://files.pythonhosted.org/packages/9c/e9/754f180cccd7f51a39913782c74717c581b9cc8177ad0e949f4d51812383/propcache-0.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:e53f3a38d3510c11953f3e6a33f205c6d1b001129f972805ca9b42fc308bc239", size = 38064, upload-time = "2025-10-08T19:46:44.872Z" }, + { url = "https://files.pythonhosted.org/packages/a2/0f/f17b1b2b221d5ca28b4b876e8bb046ac40466513960646bda8e1853cdfa2/propcache-0.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2", size = 80061, upload-time = "2025-10-08T19:46:46.075Z" }, + { url = "https://files.pythonhosted.org/packages/76/47/8ccf75935f51448ba9a16a71b783eb7ef6b9ee60f5d14c7f8a8a79fbeed7/propcache-0.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403", size = 46037, upload-time = "2025-10-08T19:46:47.23Z" }, + { url = "https://files.pythonhosted.org/packages/0a/b6/5c9a0e42df4d00bfb4a3cbbe5cf9f54260300c88a0e9af1f47ca5ce17ac0/propcache-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207", size = 47324, upload-time = "2025-10-08T19:46:48.384Z" }, + { url = "https://files.pythonhosted.org/packages/9e/d3/6c7ee328b39a81ee877c962469f1e795f9db87f925251efeb0545e0020d0/propcache-0.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72", size = 225505, upload-time = "2025-10-08T19:46:50.055Z" }, + { url = "https://files.pythonhosted.org/packages/01/5d/1c53f4563490b1d06a684742cc6076ef944bc6457df6051b7d1a877c057b/propcache-0.4.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367", size = 230242, upload-time = "2025-10-08T19:46:51.815Z" }, + { url = "https://files.pythonhosted.org/packages/20/e1/ce4620633b0e2422207c3cb774a0ee61cac13abc6217763a7b9e2e3f4a12/propcache-0.4.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4", size = 238474, upload-time = "2025-10-08T19:46:53.208Z" }, + { url = "https://files.pythonhosted.org/packages/46/4b/3aae6835b8e5f44ea6a68348ad90f78134047b503765087be2f9912140ea/propcache-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf", size = 221575, upload-time = "2025-10-08T19:46:54.511Z" }, + { url = "https://files.pythonhosted.org/packages/6e/a5/8a5e8678bcc9d3a1a15b9a29165640d64762d424a16af543f00629c87338/propcache-0.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3", size = 216736, upload-time = "2025-10-08T19:46:56.212Z" }, + { url = "https://files.pythonhosted.org/packages/f1/63/b7b215eddeac83ca1c6b934f89d09a625aa9ee4ba158338854c87210cc36/propcache-0.4.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778", size = 213019, upload-time = "2025-10-08T19:46:57.595Z" }, + { url = "https://files.pythonhosted.org/packages/57/74/f580099a58c8af587cac7ba19ee7cb418506342fbbe2d4a4401661cca886/propcache-0.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6", size = 220376, upload-time = "2025-10-08T19:46:59.067Z" }, + { url = "https://files.pythonhosted.org/packages/c4/ee/542f1313aff7eaf19c2bb758c5d0560d2683dac001a1c96d0774af799843/propcache-0.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9", size = 226988, upload-time = "2025-10-08T19:47:00.544Z" }, + { url = "https://files.pythonhosted.org/packages/8f/18/9c6b015dd9c6930f6ce2229e1f02fb35298b847f2087ea2b436a5bfa7287/propcache-0.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75", size = 215615, upload-time = "2025-10-08T19:47:01.968Z" }, + { url = "https://files.pythonhosted.org/packages/80/9e/e7b85720b98c45a45e1fca6a177024934dc9bc5f4d5dd04207f216fc33ed/propcache-0.4.1-cp312-cp312-win32.whl", hash = "sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8", size = 38066, upload-time = "2025-10-08T19:47:03.503Z" }, + { url = "https://files.pythonhosted.org/packages/54/09/d19cff2a5aaac632ec8fc03737b223597b1e347416934c1b3a7df079784c/propcache-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db", size = 41655, upload-time = "2025-10-08T19:47:04.973Z" }, + { url = "https://files.pythonhosted.org/packages/68/ab/6b5c191bb5de08036a8c697b265d4ca76148efb10fa162f14af14fb5f076/propcache-0.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1", size = 37789, upload-time = "2025-10-08T19:47:06.077Z" }, + { url = "https://files.pythonhosted.org/packages/bf/df/6d9c1b6ac12b003837dde8a10231a7344512186e87b36e855bef32241942/propcache-0.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf", size = 77750, upload-time = "2025-10-08T19:47:07.648Z" }, + { url = "https://files.pythonhosted.org/packages/8b/e8/677a0025e8a2acf07d3418a2e7ba529c9c33caf09d3c1f25513023c1db56/propcache-0.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311", size = 44780, upload-time = "2025-10-08T19:47:08.851Z" }, + { url = "https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74", size = 46308, upload-time = "2025-10-08T19:47:09.982Z" }, + { url = "https://files.pythonhosted.org/packages/2d/48/c5ac64dee5262044348d1d78a5f85dd1a57464a60d30daee946699963eb3/propcache-0.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe", size = 208182, upload-time = "2025-10-08T19:47:11.319Z" }, + { url = "https://files.pythonhosted.org/packages/c6/0c/cd762dd011a9287389a6a3eb43aa30207bde253610cca06824aeabfe9653/propcache-0.4.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af", size = 211215, upload-time = "2025-10-08T19:47:13.146Z" }, + { url = "https://files.pythonhosted.org/packages/30/3e/49861e90233ba36890ae0ca4c660e95df565b2cd15d4a68556ab5865974e/propcache-0.4.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c", size = 218112, upload-time = "2025-10-08T19:47:14.913Z" }, + { url = "https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f", size = 204442, upload-time = "2025-10-08T19:47:16.277Z" }, + { url = "https://files.pythonhosted.org/packages/50/a6/4282772fd016a76d3e5c0df58380a5ea64900afd836cec2c2f662d1b9bb3/propcache-0.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1", size = 199398, upload-time = "2025-10-08T19:47:17.962Z" }, + { url = "https://files.pythonhosted.org/packages/3e/ec/d8a7cd406ee1ddb705db2139f8a10a8a427100347bd698e7014351c7af09/propcache-0.4.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24", size = 196920, upload-time = "2025-10-08T19:47:19.355Z" }, + { url = "https://files.pythonhosted.org/packages/f6/6c/f38ab64af3764f431e359f8baf9e0a21013e24329e8b85d2da32e8ed07ca/propcache-0.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa", size = 203748, upload-time = "2025-10-08T19:47:21.338Z" }, + { url = "https://files.pythonhosted.org/packages/d6/e3/fa846bd70f6534d647886621388f0a265254d30e3ce47e5c8e6e27dbf153/propcache-0.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61", size = 205877, upload-time = "2025-10-08T19:47:23.059Z" }, + { url = "https://files.pythonhosted.org/packages/e2/39/8163fc6f3133fea7b5f2827e8eba2029a0277ab2c5beee6c1db7b10fc23d/propcache-0.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66", size = 199437, upload-time = "2025-10-08T19:47:24.445Z" }, + { url = "https://files.pythonhosted.org/packages/93/89/caa9089970ca49c7c01662bd0eeedfe85494e863e8043565aeb6472ce8fe/propcache-0.4.1-cp313-cp313-win32.whl", hash = "sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81", size = 37586, upload-time = "2025-10-08T19:47:25.736Z" }, + { url = "https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e", size = 40790, upload-time = "2025-10-08T19:47:26.847Z" }, + { url = "https://files.pythonhosted.org/packages/59/1b/e71ae98235f8e2ba5004d8cb19765a74877abf189bc53fc0c80d799e56c3/propcache-0.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1", size = 37158, upload-time = "2025-10-08T19:47:27.961Z" }, + { url = "https://files.pythonhosted.org/packages/83/ce/a31bbdfc24ee0dcbba458c8175ed26089cf109a55bbe7b7640ed2470cfe9/propcache-0.4.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b", size = 81451, upload-time = "2025-10-08T19:47:29.445Z" }, + { url = "https://files.pythonhosted.org/packages/25/9c/442a45a470a68456e710d96cacd3573ef26a1d0a60067e6a7d5e655621ed/propcache-0.4.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566", size = 46374, upload-time = "2025-10-08T19:47:30.579Z" }, + { url = "https://files.pythonhosted.org/packages/f4/bf/b1d5e21dbc3b2e889ea4327044fb16312a736d97640fb8b6aa3f9c7b3b65/propcache-0.4.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835", size = 48396, upload-time = "2025-10-08T19:47:31.79Z" }, + { url = "https://files.pythonhosted.org/packages/f4/04/5b4c54a103d480e978d3c8a76073502b18db0c4bc17ab91b3cb5092ad949/propcache-0.4.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e", size = 275950, upload-time = "2025-10-08T19:47:33.481Z" }, + { url = "https://files.pythonhosted.org/packages/b4/c1/86f846827fb969c4b78b0af79bba1d1ea2156492e1b83dea8b8a6ae27395/propcache-0.4.1-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859", size = 273856, upload-time = "2025-10-08T19:47:34.906Z" }, + { url = "https://files.pythonhosted.org/packages/36/1d/fc272a63c8d3bbad6878c336c7a7dea15e8f2d23a544bda43205dfa83ada/propcache-0.4.1-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b", size = 280420, upload-time = "2025-10-08T19:47:36.338Z" }, + { url = "https://files.pythonhosted.org/packages/07/0c/01f2219d39f7e53d52e5173bcb09c976609ba30209912a0680adfb8c593a/propcache-0.4.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0", size = 263254, upload-time = "2025-10-08T19:47:37.692Z" }, + { url = "https://files.pythonhosted.org/packages/2d/18/cd28081658ce597898f0c4d174d4d0f3c5b6d4dc27ffafeef835c95eb359/propcache-0.4.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af", size = 261205, upload-time = "2025-10-08T19:47:39.659Z" }, + { url = "https://files.pythonhosted.org/packages/7a/71/1f9e22eb8b8316701c2a19fa1f388c8a3185082607da8e406a803c9b954e/propcache-0.4.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393", size = 247873, upload-time = "2025-10-08T19:47:41.084Z" }, + { url = "https://files.pythonhosted.org/packages/4a/65/3d4b61f36af2b4eddba9def857959f1016a51066b4f1ce348e0cf7881f58/propcache-0.4.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874", size = 262739, upload-time = "2025-10-08T19:47:42.51Z" }, + { url = "https://files.pythonhosted.org/packages/2a/42/26746ab087faa77c1c68079b228810436ccd9a5ce9ac85e2b7307195fd06/propcache-0.4.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7", size = 263514, upload-time = "2025-10-08T19:47:43.927Z" }, + { url = "https://files.pythonhosted.org/packages/94/13/630690fe201f5502d2403dd3cfd451ed8858fe3c738ee88d095ad2ff407b/propcache-0.4.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1", size = 257781, upload-time = "2025-10-08T19:47:45.448Z" }, + { url = "https://files.pythonhosted.org/packages/92/f7/1d4ec5841505f423469efbfc381d64b7b467438cd5a4bbcbb063f3b73d27/propcache-0.4.1-cp313-cp313t-win32.whl", hash = "sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717", size = 41396, upload-time = "2025-10-08T19:47:47.202Z" }, + { url = "https://files.pythonhosted.org/packages/48/f0/615c30622316496d2cbbc29f5985f7777d3ada70f23370608c1d3e081c1f/propcache-0.4.1-cp313-cp313t-win_amd64.whl", hash = "sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37", size = 44897, upload-time = "2025-10-08T19:47:48.336Z" }, + { url = "https://files.pythonhosted.org/packages/fd/ca/6002e46eccbe0e33dcd4069ef32f7f1c9e243736e07adca37ae8c4830ec3/propcache-0.4.1-cp313-cp313t-win_arm64.whl", hash = "sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a", size = 39789, upload-time = "2025-10-08T19:47:49.876Z" }, + { url = "https://files.pythonhosted.org/packages/8e/5c/bca52d654a896f831b8256683457ceddd490ec18d9ec50e97dfd8fc726a8/propcache-0.4.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12", size = 78152, upload-time = "2025-10-08T19:47:51.051Z" }, + { url = "https://files.pythonhosted.org/packages/65/9b/03b04e7d82a5f54fb16113d839f5ea1ede58a61e90edf515f6577c66fa8f/propcache-0.4.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c", size = 44869, upload-time = "2025-10-08T19:47:52.594Z" }, + { url = "https://files.pythonhosted.org/packages/b2/fa/89a8ef0468d5833a23fff277b143d0573897cf75bd56670a6d28126c7d68/propcache-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded", size = 46596, upload-time = "2025-10-08T19:47:54.073Z" }, + { url = "https://files.pythonhosted.org/packages/86/bd/47816020d337f4a746edc42fe8d53669965138f39ee117414c7d7a340cfe/propcache-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641", size = 206981, upload-time = "2025-10-08T19:47:55.715Z" }, + { url = "https://files.pythonhosted.org/packages/df/f6/c5fa1357cc9748510ee55f37173eb31bfde6d94e98ccd9e6f033f2fc06e1/propcache-0.4.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4", size = 211490, upload-time = "2025-10-08T19:47:57.499Z" }, + { url = "https://files.pythonhosted.org/packages/80/1e/e5889652a7c4a3846683401a48f0f2e5083ce0ec1a8a5221d8058fbd1adf/propcache-0.4.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44", size = 215371, upload-time = "2025-10-08T19:47:59.317Z" }, + { url = "https://files.pythonhosted.org/packages/b2/f2/889ad4b2408f72fe1a4f6a19491177b30ea7bf1a0fd5f17050ca08cfc882/propcache-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d", size = 201424, upload-time = "2025-10-08T19:48:00.67Z" }, + { url = "https://files.pythonhosted.org/packages/27/73/033d63069b57b0812c8bd19f311faebeceb6ba31b8f32b73432d12a0b826/propcache-0.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b", size = 197566, upload-time = "2025-10-08T19:48:02.604Z" }, + { url = "https://files.pythonhosted.org/packages/dc/89/ce24f3dc182630b4e07aa6d15f0ff4b14ed4b9955fae95a0b54c58d66c05/propcache-0.4.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e", size = 193130, upload-time = "2025-10-08T19:48:04.499Z" }, + { url = "https://files.pythonhosted.org/packages/a9/24/ef0d5fd1a811fb5c609278d0209c9f10c35f20581fcc16f818da959fc5b4/propcache-0.4.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f", size = 202625, upload-time = "2025-10-08T19:48:06.213Z" }, + { url = "https://files.pythonhosted.org/packages/f5/02/98ec20ff5546f68d673df2f7a69e8c0d076b5abd05ca882dc7ee3a83653d/propcache-0.4.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49", size = 204209, upload-time = "2025-10-08T19:48:08.432Z" }, + { url = "https://files.pythonhosted.org/packages/a0/87/492694f76759b15f0467a2a93ab68d32859672b646aa8a04ce4864e7932d/propcache-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144", size = 197797, upload-time = "2025-10-08T19:48:09.968Z" }, + { url = "https://files.pythonhosted.org/packages/ee/36/66367de3575db1d2d3f3d177432bd14ee577a39d3f5d1b3d5df8afe3b6e2/propcache-0.4.1-cp314-cp314-win32.whl", hash = "sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f", size = 38140, upload-time = "2025-10-08T19:48:11.232Z" }, + { url = "https://files.pythonhosted.org/packages/0c/2a/a758b47de253636e1b8aef181c0b4f4f204bf0dd964914fb2af90a95b49b/propcache-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153", size = 41257, upload-time = "2025-10-08T19:48:12.707Z" }, + { url = "https://files.pythonhosted.org/packages/34/5e/63bd5896c3fec12edcbd6f12508d4890d23c265df28c74b175e1ef9f4f3b/propcache-0.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992", size = 38097, upload-time = "2025-10-08T19:48:13.923Z" }, + { url = "https://files.pythonhosted.org/packages/99/85/9ff785d787ccf9bbb3f3106f79884a130951436f58392000231b4c737c80/propcache-0.4.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f", size = 81455, upload-time = "2025-10-08T19:48:15.16Z" }, + { url = "https://files.pythonhosted.org/packages/90/85/2431c10c8e7ddb1445c1f7c4b54d886e8ad20e3c6307e7218f05922cad67/propcache-0.4.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393", size = 46372, upload-time = "2025-10-08T19:48:16.424Z" }, + { url = "https://files.pythonhosted.org/packages/01/20/b0972d902472da9bcb683fa595099911f4d2e86e5683bcc45de60dd05dc3/propcache-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0", size = 48411, upload-time = "2025-10-08T19:48:17.577Z" }, + { url = "https://files.pythonhosted.org/packages/e2/e3/7dc89f4f21e8f99bad3d5ddb3a3389afcf9da4ac69e3deb2dcdc96e74169/propcache-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a", size = 275712, upload-time = "2025-10-08T19:48:18.901Z" }, + { url = "https://files.pythonhosted.org/packages/20/67/89800c8352489b21a8047c773067644e3897f02ecbbd610f4d46b7f08612/propcache-0.4.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be", size = 273557, upload-time = "2025-10-08T19:48:20.762Z" }, + { url = "https://files.pythonhosted.org/packages/e2/a1/b52b055c766a54ce6d9c16d9aca0cad8059acd9637cdf8aa0222f4a026ef/propcache-0.4.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc", size = 280015, upload-time = "2025-10-08T19:48:22.592Z" }, + { url = "https://files.pythonhosted.org/packages/48/c8/33cee30bd890672c63743049f3c9e4be087e6780906bfc3ec58528be59c1/propcache-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a", size = 262880, upload-time = "2025-10-08T19:48:23.947Z" }, + { url = "https://files.pythonhosted.org/packages/0c/b1/8f08a143b204b418285c88b83d00edbd61afbc2c6415ffafc8905da7038b/propcache-0.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89", size = 260938, upload-time = "2025-10-08T19:48:25.656Z" }, + { url = "https://files.pythonhosted.org/packages/cf/12/96e4664c82ca2f31e1c8dff86afb867348979eb78d3cb8546a680287a1e9/propcache-0.4.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726", size = 247641, upload-time = "2025-10-08T19:48:27.207Z" }, + { url = "https://files.pythonhosted.org/packages/18/ed/e7a9cfca28133386ba52278136d42209d3125db08d0a6395f0cba0c0285c/propcache-0.4.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367", size = 262510, upload-time = "2025-10-08T19:48:28.65Z" }, + { url = "https://files.pythonhosted.org/packages/f5/76/16d8bf65e8845dd62b4e2b57444ab81f07f40caa5652b8969b87ddcf2ef6/propcache-0.4.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36", size = 263161, upload-time = "2025-10-08T19:48:30.133Z" }, + { url = "https://files.pythonhosted.org/packages/e7/70/c99e9edb5d91d5ad8a49fa3c1e8285ba64f1476782fed10ab251ff413ba1/propcache-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455", size = 257393, upload-time = "2025-10-08T19:48:31.567Z" }, + { url = "https://files.pythonhosted.org/packages/08/02/87b25304249a35c0915d236575bc3574a323f60b47939a2262b77632a3ee/propcache-0.4.1-cp314-cp314t-win32.whl", hash = "sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85", size = 42546, upload-time = "2025-10-08T19:48:32.872Z" }, + { url = "https://files.pythonhosted.org/packages/cb/ef/3c6ecf8b317aa982f309835e8f96987466123c6e596646d4e6a1dfcd080f/propcache-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1", size = 46259, upload-time = "2025-10-08T19:48:34.226Z" }, + { url = "https://files.pythonhosted.org/packages/c4/2d/346e946d4951f37eca1e4f55be0f0174c52cd70720f84029b02f296f4a38/propcache-0.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9", size = 40428, upload-time = "2025-10-08T19:48:35.441Z" }, + { url = "https://files.pythonhosted.org/packages/9b/01/0ebaec9003f5d619a7475165961f8e3083cf8644d704b60395df3601632d/propcache-0.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3d233076ccf9e450c8b3bc6720af226b898ef5d051a2d145f7d765e6e9f9bcff", size = 80277, upload-time = "2025-10-08T19:48:36.647Z" }, + { url = "https://files.pythonhosted.org/packages/34/58/04af97ac586b4ef6b9026c3fd36ee7798b737a832f5d3440a4280dcebd3a/propcache-0.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:357f5bb5c377a82e105e44bd3d52ba22b616f7b9773714bff93573988ef0a5fb", size = 45865, upload-time = "2025-10-08T19:48:37.859Z" }, + { url = "https://files.pythonhosted.org/packages/7c/19/b65d98ae21384518b291d9939e24a8aeac4fdb5101b732576f8f7540e834/propcache-0.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cbc3b6dfc728105b2a57c06791eb07a94229202ea75c59db644d7d496b698cac", size = 47636, upload-time = "2025-10-08T19:48:39.038Z" }, + { url = "https://files.pythonhosted.org/packages/b3/0f/317048c6d91c356c7154dca5af019e6effeb7ee15fa6a6db327cc19e12b4/propcache-0.4.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:182b51b421f0501952d938dc0b0eb45246a5b5153c50d42b495ad5fb7517c888", size = 201126, upload-time = "2025-10-08T19:48:40.774Z" }, + { url = "https://files.pythonhosted.org/packages/71/69/0b2a7a5a6ee83292b4b997dbd80549d8ce7d40b6397c1646c0d9495f5a85/propcache-0.4.1-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4b536b39c5199b96fc6245eb5fb796c497381d3942f169e44e8e392b29c9ebcc", size = 209837, upload-time = "2025-10-08T19:48:42.167Z" }, + { url = "https://files.pythonhosted.org/packages/a5/92/c699ac495a6698df6e497fc2de27af4b6ace10d8e76528357ce153722e45/propcache-0.4.1-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:db65d2af507bbfbdcedb254a11149f894169d90488dd3e7190f7cdcb2d6cd57a", size = 215578, upload-time = "2025-10-08T19:48:43.56Z" }, + { url = "https://files.pythonhosted.org/packages/b3/ee/14de81c5eb02c0ee4f500b4e39c4e1bd0677c06e72379e6ab18923c773fc/propcache-0.4.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fd2dbc472da1f772a4dae4fa24be938a6c544671a912e30529984dd80400cd88", size = 197187, upload-time = "2025-10-08T19:48:45.309Z" }, + { url = "https://files.pythonhosted.org/packages/1d/94/48dce9aaa6d8dd5a0859bad75158ec522546d4ac23f8e2f05fac469477dd/propcache-0.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:daede9cd44e0f8bdd9e6cc9a607fc81feb80fae7a5fc6cecaff0e0bb32e42d00", size = 193478, upload-time = "2025-10-08T19:48:47.743Z" }, + { url = "https://files.pythonhosted.org/packages/60/b5/0516b563e801e1ace212afde869a0596a0d7115eec0b12d296d75633fb29/propcache-0.4.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:71b749281b816793678ae7f3d0d84bd36e694953822eaad408d682efc5ca18e0", size = 190650, upload-time = "2025-10-08T19:48:49.373Z" }, + { url = "https://files.pythonhosted.org/packages/24/89/e0f7d4a5978cd56f8cd67735f74052f257dc471ec901694e430f0d1572fe/propcache-0.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:0002004213ee1f36cfb3f9a42b5066100c44276b9b72b4e1504cddd3d692e86e", size = 200251, upload-time = "2025-10-08T19:48:51.4Z" }, + { url = "https://files.pythonhosted.org/packages/06/7d/a1fac863d473876ed4406c914f2e14aa82d2f10dd207c9e16fc383cc5a24/propcache-0.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:fe49d0a85038f36ba9e3ffafa1103e61170b28e95b16622e11be0a0ea07c6781", size = 200919, upload-time = "2025-10-08T19:48:53.227Z" }, + { url = "https://files.pythonhosted.org/packages/c3/4e/f86a256ff24944cf5743e4e6c6994e3526f6acfcfb55e21694c2424f758c/propcache-0.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:99d43339c83aaf4d32bda60928231848eee470c6bda8d02599cc4cebe872d183", size = 193211, upload-time = "2025-10-08T19:48:55.027Z" }, + { url = "https://files.pythonhosted.org/packages/6e/3f/3fbad5f4356b068f1b047d300a6ff2c66614d7030f078cd50be3fec04228/propcache-0.4.1-cp39-cp39-win32.whl", hash = "sha256:a129e76735bc792794d5177069691c3217898b9f5cee2b2661471e52ffe13f19", size = 38314, upload-time = "2025-10-08T19:48:56.792Z" }, + { url = "https://files.pythonhosted.org/packages/a4/45/d78d136c3a3d215677abb886785aae744da2c3005bcb99e58640c56529b1/propcache-0.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:948dab269721ae9a87fd16c514a0a2c2a1bdb23a9a61b969b0f9d9ee2968546f", size = 41912, upload-time = "2025-10-08T19:48:57.995Z" }, + { url = "https://files.pythonhosted.org/packages/fc/2a/b0632941f25139f4e58450b307242951f7c2717a5704977c6d5323a800af/propcache-0.4.1-cp39-cp39-win_arm64.whl", hash = "sha256:5fd37c406dd6dc85aa743e214cef35dc54bbdd1419baac4f6ae5e5b1a2976938", size = 38450, upload-time = "2025-10-08T19:48:59.349Z" }, + { url = "https://files.pythonhosted.org/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload-time = "2025-10-08T19:49:00.792Z" }, +] + +[[package]] +name = "pydantic" +version = "1.10.26" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.10'", + "python_full_version < '3.10'", +] +dependencies = [ + { name = "typing-extensions", marker = "extra == 'group-10-cloudflare-pydantic-v1'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7b/da/fd89f987a376c807cd81ea0eff4589aade783bbb702637b4734ef2c743a2/pydantic-1.10.26.tar.gz", hash = "sha256:8c6aa39b494c5af092e690127c283d84f363ac36017106a9e66cb33a22ac412e", size = 357906, upload-time = "2025-12-18T15:47:46.557Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/08/2587a6d4314e7539eec84acd062cb7b037638edb57a0335d20e4c5b8878c/pydantic-1.10.26-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f7ae36fa0ecef8d39884120f212e16c06bb096a38f523421278e2f39c1784546", size = 2444588, upload-time = "2025-12-18T15:46:28.882Z" }, + { url = "https://files.pythonhosted.org/packages/47/e6/10df5f08c105bcbb4adbee7d1108ff4b347702b110fed058f6a03f1c6b73/pydantic-1.10.26-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d95a76cf503f0f72ed7812a91de948440b2bf564269975738a4751e4fadeb572", size = 2255972, upload-time = "2025-12-18T15:46:31.72Z" }, + { url = "https://files.pythonhosted.org/packages/ba/7d/fdb961e7adc2c31f394feba6f560ef2c74c446f0285e2c2eb87d2b7206c7/pydantic-1.10.26-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a943ce8e00ad708ed06a1d9df5b4fd28f5635a003b82a4908ece6f24c0b18464", size = 2857175, upload-time = "2025-12-18T15:46:34Z" }, + { url = "https://files.pythonhosted.org/packages/8f/6c/f21e27dda475d4c562bd01b5874284dd3180f336c1e669413b743ca8b278/pydantic-1.10.26-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:465ad8edb29b15c10b779b16431fe8e77c380098badf6db367b7a1d3e572cf53", size = 2947001, upload-time = "2025-12-18T15:46:35.922Z" }, + { url = "https://files.pythonhosted.org/packages/6d/f6/27ea206232cbb6ec24dc4e4e8888a9a734f96a1eaf13504be4b30ef26aa7/pydantic-1.10.26-cp310-cp310-win_amd64.whl", hash = "sha256:80e6be6272839c8a7641d26ad569ab77772809dd78f91d0068dc0fc97f071945", size = 2066217, upload-time = "2025-12-18T15:46:37.614Z" }, + { url = "https://files.pythonhosted.org/packages/1d/c1/d521e64c8130e1ad9d22c270bed3fabcc0940c9539b076b639c88fd32a8d/pydantic-1.10.26-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:116233e53889bcc536f617e38c1b8337d7fa9c280f0fd7a4045947515a785637", size = 2428347, upload-time = "2025-12-18T15:46:39.41Z" }, + { url = "https://files.pythonhosted.org/packages/2c/08/f4b804a00c16e3ea994cb640a7c25c579b4f1fa674cde6a19fa0dfb0ae4f/pydantic-1.10.26-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c3cfdd361addb6eb64ccd26ac356ad6514cee06a61ab26b27e16b5ed53108f77", size = 2212605, upload-time = "2025-12-18T15:46:41.006Z" }, + { url = "https://files.pythonhosted.org/packages/5d/78/0df4b9efef29bbc5e39f247fcba99060d15946b4463d82a5589cf7923d71/pydantic-1.10.26-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0e4451951a9a93bf9a90576f3e25240b47ee49ab5236adccb8eff6ac943adf0f", size = 2753560, upload-time = "2025-12-18T15:46:43.215Z" }, + { url = "https://files.pythonhosted.org/packages/68/66/6ab6c1d3a116d05d2508fce64f96e35242938fac07544d611e11d0d363a0/pydantic-1.10.26-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9858ed44c6bea5f29ffe95308db9e62060791c877766c67dd5f55d072c8612b5", size = 2859235, upload-time = "2025-12-18T15:46:45.112Z" }, + { url = "https://files.pythonhosted.org/packages/61/4e/f1676bb0fcdf6ed2ce4670d7d1fc1d6c3a06d84497644acfbe02649503f1/pydantic-1.10.26-cp311-cp311-win_amd64.whl", hash = "sha256:ac1089f723e2106ebde434377d31239e00870a7563245072968e5af5cc4d33df", size = 2066646, upload-time = "2025-12-18T15:46:46.816Z" }, + { url = "https://files.pythonhosted.org/packages/02/6c/cd97a5a776c4515e6ee2ae81c2f2c5be51376dda6c31f965d7746ce0019f/pydantic-1.10.26-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:468d5b9cacfcaadc76ed0a4645354ab6f263ec01a63fb6d05630ea1df6ae453f", size = 2433795, upload-time = "2025-12-18T15:46:49.321Z" }, + { url = "https://files.pythonhosted.org/packages/47/12/de20affa30dcef728fcf9cc98e13ff4438c7a630de8d2f90eb38eba0891c/pydantic-1.10.26-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2c1b0b914be31671000ca25cf7ea17fcaaa68cfeadf6924529c5c5aa24b7ab1f", size = 2227387, upload-time = "2025-12-18T15:46:50.877Z" }, + { url = "https://files.pythonhosted.org/packages/7b/1d/9d65dcc5b8c17ba590f1f9f486e9306346831902318b7ee93f63516f4003/pydantic-1.10.26-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:15b13b9f8ba8867095769e1156e0d7fbafa1f65b898dd40fd1c02e34430973cb", size = 2629594, upload-time = "2025-12-18T15:46:53.42Z" }, + { url = "https://files.pythonhosted.org/packages/3f/76/acb41409356789e23e1a7ef58f93821410c96409183ce314ddb58d97f23e/pydantic-1.10.26-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad7025ca324ae263d4313998e25078dcaec5f9ed0392c06dedb57e053cc8086b", size = 2745305, upload-time = "2025-12-18T15:46:55.987Z" }, + { url = "https://files.pythonhosted.org/packages/22/72/a98c0c5e527a66057d969fedd61675223c7975ade61acebbca9f1abd6dc0/pydantic-1.10.26-cp312-cp312-win_amd64.whl", hash = "sha256:4482b299874dabb88a6c3759e3d85c6557c407c3b586891f7d808d8a38b66b9c", size = 1937647, upload-time = "2025-12-18T15:46:57.905Z" }, + { url = "https://files.pythonhosted.org/packages/28/b9/17a5a5a421c23ac27486b977724a42c9d5f8b7f0f4aab054251066223900/pydantic-1.10.26-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1ae7913bb40a96c87e3d3f6fe4e918ef53bf181583de4e71824360a9b11aef1c", size = 2494599, upload-time = "2025-12-18T15:47:00.209Z" }, + { url = "https://files.pythonhosted.org/packages/e6/8e/6e3bd4241076cf227b443d7577245dd5d181ecf40b3182fcb908bc8c197d/pydantic-1.10.26-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8154c13f58d4de5d3a856bb6c909c7370f41fb876a5952a503af6b975265f4ba", size = 2254391, upload-time = "2025-12-18T15:47:02.268Z" }, + { url = "https://files.pythonhosted.org/packages/a8/30/a1c4092eda2145ecbead6c92db489b223e101e1ba0da82576d0cf73dd422/pydantic-1.10.26-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f8af0507bf6118b054a9765fb2e402f18a8b70c964f420d95b525eb711122d62", size = 2609445, upload-time = "2025-12-18T15:47:04.909Z" }, + { url = "https://files.pythonhosted.org/packages/3a/2a/0491f1729ee4b7b6bc859ec22f69752f0c09bee1b66ac6f5f701136f34c3/pydantic-1.10.26-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:dcb5a7318fb43189fde6af6f21ac7149c4bcbcfffc54bc87b5becddc46084847", size = 2732124, upload-time = "2025-12-18T15:47:07.464Z" }, + { url = "https://files.pythonhosted.org/packages/2a/56/b59f3b2f84e1df2b04ae768a1bb04d9f0288ff71b67cdcbb07683757b2c0/pydantic-1.10.26-cp313-cp313-win_amd64.whl", hash = "sha256:71cde228bc0600cf8619f0ee62db050d1880dcc477eba0e90b23011b4ee0f314", size = 1939888, upload-time = "2025-12-18T15:47:09.618Z" }, + { url = "https://files.pythonhosted.org/packages/d2/8b/0c3dc02d4b97790b0f199bf933f677c14e7be4a8d21307c5f2daae06aa41/pydantic-1.10.26-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:6b40730cc81d53d515dc0b8bb5c9b43fadb9bed46de4a3c03bd95e8571616dba", size = 2502689, upload-time = "2025-12-18T15:47:12.308Z" }, + { url = "https://files.pythonhosted.org/packages/d4/9d/d31aeea45542b2ae4b09ecba92b88aaba696b801c31919811aa979a1242d/pydantic-1.10.26-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c3bbb9c0eecdf599e4db9b372fa9cc55be12e80a0d9c6d307950a39050cb0e37", size = 2269494, upload-time = "2025-12-18T15:47:14.53Z" }, + { url = "https://files.pythonhosted.org/packages/78/c1/3a4d069593283ca4dd0006039ba33644e21e432cddc09da706ac50441610/pydantic-1.10.26-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc2e3fe7bc4993626ef6b6fa855defafa1d6f8996aa1caef2deb83c5ac4d043a", size = 2620047, upload-time = "2025-12-18T15:47:17.089Z" }, + { url = "https://files.pythonhosted.org/packages/e0/0e/340c3d29197d99c15ab04093d43bb9c9d0fd17c2a34b80cb9d36ed732b09/pydantic-1.10.26-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:36d9e46b588aaeb1dcd2409fa4c467fe0b331f3cc9f227b03a7a00643704e962", size = 2747625, upload-time = "2025-12-18T15:47:19.21Z" }, + { url = "https://files.pythonhosted.org/packages/1e/58/f12ab3727339b172c830b32151919456b67787cdfe8808b2568b322fb15c/pydantic-1.10.26-cp314-cp314-win_amd64.whl", hash = "sha256:81ce3c8616d12a7be31b4aadfd3434f78f6b44b75adbfaec2fe1ad4f7f999b8c", size = 1976436, upload-time = "2025-12-18T15:47:21.384Z" }, + { url = "https://files.pythonhosted.org/packages/e1/8a/3a5a6267d5f03617b5c0f1985aa9fdfbafd33a50ef6dadd866a15ed4d123/pydantic-1.10.26-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:502b9d30d18a2dfaf81b7302f6ba0e5853474b1c96212449eb4db912cb604b7d", size = 2457039, upload-time = "2025-12-18T15:47:34.584Z" }, + { url = "https://files.pythonhosted.org/packages/f3/fa/343ac0db26918a033ac6256c036d72c3b6eb1196b7de622e2e8a94b19079/pydantic-1.10.26-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0d8f6087bf697dec3bf7ffcd7fe8362674f16519f3151789f33cbe8f1d19fc15", size = 2266441, upload-time = "2025-12-18T15:47:36.807Z" }, + { url = "https://files.pythonhosted.org/packages/fc/36/1ab48136578608dba2f2a62e452f3db2083b474d4e49be5749c6ae0c123c/pydantic-1.10.26-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:dd40a99c358419910c85e6f5d22f9c56684c25b5e7abc40879b3b4a52f34ae90", size = 2869383, upload-time = "2025-12-18T15:47:38.883Z" }, + { url = "https://files.pythonhosted.org/packages/a2/25/41dbf1bffc31eb242cece8080561a4133eaeb513372dec36a84477a3fb71/pydantic-1.10.26-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ce3293b86ca9f4125df02ff0a70be91bc7946522467cbd98e7f1493f340616ba", size = 2963582, upload-time = "2025-12-18T15:47:40.854Z" }, + { url = "https://files.pythonhosted.org/packages/61/2f/f072ae160a300c85eb9f059915101fd33dacf12d8df08c2b804acb3b95d1/pydantic-1.10.26-cp39-cp39-win_amd64.whl", hash = "sha256:1a4e3062b71ab1d5df339ba12c48f9ed5817c5de6cb92a961dd5c64bb32e7b96", size = 2075530, upload-time = "2025-12-18T15:47:43.181Z" }, + { url = "https://files.pythonhosted.org/packages/1f/98/556e82f00b98486def0b8af85da95e69d2be7e367cf2431408e108bc3095/pydantic-1.10.26-py3-none-any.whl", hash = "sha256:c43ad70dc3ce7787543d563792426a16fd7895e14be4b194b5665e36459dd917", size = 166975, upload-time = "2025-12-18T15:47:44.927Z" }, +] + +[[package]] +name = "pydantic" +version = "2.13.3" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14' and extra != 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and python_full_version < '3.14' and extra != 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2'", + "python_full_version < '3.10' and extra != 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and extra != 'group-10-cloudflare-pydantic-v1' and extra != 'group-10-cloudflare-pydantic-v2'", + "python_full_version < '3.10' and extra != 'group-10-cloudflare-pydantic-v1' and extra != 'group-10-cloudflare-pydantic-v2'", +] +dependencies = [ + { name = "annotated-types", marker = "extra == 'group-10-cloudflare-pydantic-v2' or extra != 'group-10-cloudflare-pydantic-v1'" }, + { name = "pydantic-core", marker = "extra == 'group-10-cloudflare-pydantic-v2' or extra != 'group-10-cloudflare-pydantic-v1'" }, + { name = "typing-extensions", marker = "extra == 'group-10-cloudflare-pydantic-v2' or extra != 'group-10-cloudflare-pydantic-v1'" }, + { name = "typing-inspection", marker = "extra == 'group-10-cloudflare-pydantic-v2' or extra != 'group-10-cloudflare-pydantic-v1'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d9/e4/40d09941a2cebcb20609b86a559817d5b9291c49dd6f8c87e5feffbe703a/pydantic-2.13.3.tar.gz", hash = "sha256:af09e9d1d09f4e7fe37145c1f577e1d61ceb9a41924bf0094a36506285d0a84d", size = 844068, upload-time = "2026-04-20T14:46:43.632Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f3/0a/fd7d723f8f8153418fb40cf9c940e82004fce7e987026b08a68a36dd3fe7/pydantic-2.13.3-py3-none-any.whl", hash = "sha256:6db14ac8dfc9a1e57f87ea2c0de670c251240f43cb0c30a5130e9720dc612927", size = 471981, upload-time = "2026-04-20T14:46:41.402Z" }, +] + +[[package]] +name = "pydantic-core" +version = "2.46.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "extra == 'group-10-cloudflare-pydantic-v2' or extra != 'group-10-cloudflare-pydantic-v1'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2a/ef/f7abb56c49382a246fd2ce9c799691e3c3e7175ec74b14d99e798bcddb1a/pydantic_core-2.46.3.tar.gz", hash = "sha256:41c178f65b8c29807239d47e6050262eb6bf84eb695e41101e62e38df4a5bc2c", size = 471412, upload-time = "2026-04-20T14:40:56.672Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/98/b50eb9a411e87483b5c65dba4fa430a06bac4234d3403a40e5a9905ebcd0/pydantic_core-2.46.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:1da3786b8018e60349680720158cc19161cc3b4bdd815beb0a321cd5ce1ad5b1", size = 2108971, upload-time = "2026-04-20T14:43:51.945Z" }, + { url = "https://files.pythonhosted.org/packages/08/4b/f364b9d161718ff2217160a4b5d41ce38de60aed91c3689ebffa1c939d23/pydantic_core-2.46.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cc0988cb29d21bf4a9d5cf2ef970b5c0e38d8d8e107a493278c05dc6c1dda69f", size = 1949588, upload-time = "2026-04-20T14:44:10.386Z" }, + { url = "https://files.pythonhosted.org/packages/8f/8b/30bd03ee83b2f5e29f5ba8e647ab3c456bf56f2ec72fdbcc0215484a0854/pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27f9067c3bfadd04c55484b89c0d267981b2f3512850f6f66e1e74204a4e4ce3", size = 1975986, upload-time = "2026-04-20T14:43:57.106Z" }, + { url = "https://files.pythonhosted.org/packages/3c/54/13ccf954d84ec275d5d023d5786e4aa48840bc9f161f2838dc98e1153518/pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a642ac886ecf6402d9882d10c405dcf4b902abeb2972cd5fb4a48c83cd59279a", size = 2055830, upload-time = "2026-04-20T14:44:15.499Z" }, + { url = "https://files.pythonhosted.org/packages/be/0e/65f38125e660fdbd72aa858e7dfae893645cfa0e7b13d333e174a367cd23/pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:79f561438481f28681584b89e2effb22855e2179880314bcddbf5968e935e807", size = 2222340, upload-time = "2026-04-20T14:41:51.353Z" }, + { url = "https://files.pythonhosted.org/packages/d1/88/f3ab7739efe0e7e80777dbb84c59eb98518e3f57ea433206194c2e425272/pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57a973eae4665352a47cf1a99b4ee864620f2fe663a217d7a8da68a1f3a5bfda", size = 2280727, upload-time = "2026-04-20T14:41:30.461Z" }, + { url = "https://files.pythonhosted.org/packages/2a/6d/c228219080817bec4982f9531cadb18da6aaa770fdeb114f49c237ac2c9f/pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83d002b97072a53ea150d63e0a3adfae5670cef5aa8a6e490240e482d3b22e57", size = 2092158, upload-time = "2026-04-20T14:44:07.305Z" }, + { url = "https://files.pythonhosted.org/packages/0f/b1/525a16711e7c6d61635fac3b0bd54600b5c5d9f60c6fc5aaab26b64a2297/pydantic_core-2.46.3-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:b40ddd51e7c44b28cfaef746c9d3c506d658885e0a46f9eeef2ee815cbf8e045", size = 2116626, upload-time = "2026-04-20T14:42:34.118Z" }, + { url = "https://files.pythonhosted.org/packages/ef/7c/17d30673351439a6951bf54f564cf2443ab00ae264ec9df00e2efd710eb5/pydantic_core-2.46.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ac5ec7fb9b87f04ee839af2d53bcadea57ded7d229719f56c0ed895bff987943", size = 2160691, upload-time = "2026-04-20T14:41:14.023Z" }, + { url = "https://files.pythonhosted.org/packages/86/66/af8adbcbc0886ead7f1a116606a534d75a307e71e6e08226000d51b880d2/pydantic_core-2.46.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a3b11c812f61b3129c4905781a2601dfdfdea5fe1e6c1cfb696b55d14e9c054f", size = 2182543, upload-time = "2026-04-20T14:40:48.886Z" }, + { url = "https://files.pythonhosted.org/packages/b0/37/6de71e0f54c54a4190010f57deb749e1ddf75c568ada3b1320b70067f121/pydantic_core-2.46.3-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:1108da631e602e5b3c38d6d04fe5bb3bfa54349e6918e3ca6cf570b2e2b2f9d4", size = 2324513, upload-time = "2026-04-20T14:42:36.121Z" }, + { url = "https://files.pythonhosted.org/packages/51/b1/9fc74ce94f603d5ef59ff258ca9c2c8fb902fb548d340a96f77f4d1c3b7f/pydantic_core-2.46.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:de885175515bcfa98ae618c1df7a072f13d179f81376c8007112af20567fd08a", size = 2361853, upload-time = "2026-04-20T14:43:24.886Z" }, + { url = "https://files.pythonhosted.org/packages/40/d0/4c652fc592db35f100279ee751d5a145aca1b9a7984b9684ba7c1b5b0535/pydantic_core-2.46.3-cp310-cp310-win32.whl", hash = "sha256:d11058e3201527d41bc6b545c79187c9e4bf85e15a236a6007f0e991518882b7", size = 1980465, upload-time = "2026-04-20T14:44:46.239Z" }, + { url = "https://files.pythonhosted.org/packages/27/b8/a920453c38afbe1f355e1ea0b0d94a0a3e0b0879d32d793108755fa171d5/pydantic_core-2.46.3-cp310-cp310-win_amd64.whl", hash = "sha256:3612edf65c8ea67ac13616c4d23af12faef1ae435a8a93e5934c2a0cbbdd1fd6", size = 2073884, upload-time = "2026-04-20T14:43:01.201Z" }, + { url = "https://files.pythonhosted.org/packages/22/a2/1ba90a83e85a3f94c796b184f3efde9c72f2830dcda493eea8d59ba78e6d/pydantic_core-2.46.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ab124d49d0459b2373ecf54118a45c28a1e6d4192a533fbc915e70f556feb8e5", size = 2106740, upload-time = "2026-04-20T14:41:20.932Z" }, + { url = "https://files.pythonhosted.org/packages/b6/f6/99ae893c89a0b9d3daec9f95487aa676709aa83f67643b3f0abaf4ab628a/pydantic_core-2.46.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cca67d52a5c7a16aed2b3999e719c4bcf644074eac304a5d3d62dd70ae7d4b2c", size = 1948293, upload-time = "2026-04-20T14:43:42.115Z" }, + { url = "https://files.pythonhosted.org/packages/3e/b8/2e8e636dc9e3f16c2e16bf0849e24be82c5ee82c603c65fc0326666328fc/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c024e08c0ba23e6fd68c771a521e9d6a792f2ebb0fa734296b36394dc30390e", size = 1973222, upload-time = "2026-04-20T14:41:57.841Z" }, + { url = "https://files.pythonhosted.org/packages/34/36/0e730beec4d83c5306f417afbd82ff237d9a21e83c5edf675f31ed84c1fe/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6645ce7eec4928e29a1e3b3d5c946621d105d3e79f0c9cddf07c2a9770949287", size = 2053852, upload-time = "2026-04-20T14:40:43.077Z" }, + { url = "https://files.pythonhosted.org/packages/4b/f0/3071131f47e39136a17814576e0fada9168569f7f8c0e6ac4d1ede6a4958/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a712c7118e6c5ea96562f7b488435172abb94a3c53c22c9efc1412264a45cbbe", size = 2221134, upload-time = "2026-04-20T14:43:03.349Z" }, + { url = "https://files.pythonhosted.org/packages/2f/a9/a2dc023eec5aa4b02a467874bad32e2446957d2adcab14e107eab502e978/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69a868ef3ff206343579021c40faf3b1edc64b1cc508ff243a28b0a514ccb050", size = 2279785, upload-time = "2026-04-20T14:41:19.285Z" }, + { url = "https://files.pythonhosted.org/packages/0a/44/93f489d16fb63fbd41c670441536541f6e8cfa1e5a69f40bc9c5d30d8c90/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc7e8c32db809aa0f6ea1d6869ebc8518a65d5150fdfad8bcae6a49ae32a22e2", size = 2089404, upload-time = "2026-04-20T14:43:10.108Z" }, + { url = "https://files.pythonhosted.org/packages/2a/78/8692e3aa72b2d004f7a5d937f1dfdc8552ba26caf0bec75f342c40f00dec/pydantic_core-2.46.3-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:3481bd1341dc85779ee506bc8e1196a277ace359d89d28588a9468c3ecbe63fa", size = 2114898, upload-time = "2026-04-20T14:44:51.475Z" }, + { url = "https://files.pythonhosted.org/packages/6a/62/e83133f2e7832532060175cebf1f13748f4c7e7e7165cdd1f611f174494b/pydantic_core-2.46.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8690eba565c6d68ffd3a8655525cbdd5246510b44a637ee2c6c03a7ebfe64d3c", size = 2157856, upload-time = "2026-04-20T14:43:46.64Z" }, + { url = "https://files.pythonhosted.org/packages/6d/ec/6a500e3ad7718ee50583fae79c8651f5d37e3abce1fa9ae177ae65842c53/pydantic_core-2.46.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4de88889d7e88d50d40ee5b39d5dac0bcaef9ba91f7e536ac064e6b2834ecccf", size = 2180168, upload-time = "2026-04-20T14:42:00.302Z" }, + { url = "https://files.pythonhosted.org/packages/d8/53/8267811054b1aa7fc1dc7ded93812372ef79a839f5e23558136a6afbfde1/pydantic_core-2.46.3-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:e480080975c1ef7f780b8f99ed72337e7cc5efea2e518a20a692e8e7b278eb8b", size = 2322885, upload-time = "2026-04-20T14:41:05.253Z" }, + { url = "https://files.pythonhosted.org/packages/c8/c1/1c0acdb3aa0856ddc4ecc55214578f896f2de16f400cf51627eb3c26c1c4/pydantic_core-2.46.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:de3a5c376f8cd94da9a1b8fd3dd1c16c7a7b216ed31dc8ce9fd7a22bf13b836e", size = 2360328, upload-time = "2026-04-20T14:41:43.991Z" }, + { url = "https://files.pythonhosted.org/packages/f0/d0/ef39cd0f4a926814f360e71c1adeab48ad214d9727e4deb48eedfb5bce1a/pydantic_core-2.46.3-cp311-cp311-win32.whl", hash = "sha256:fc331a5314ffddd5385b9ee9d0d2fee0b13c27e0e02dad71b1ae5d6561f51eeb", size = 1979464, upload-time = "2026-04-20T14:43:12.215Z" }, + { url = "https://files.pythonhosted.org/packages/18/9c/f41951b0d858e343f1cf09398b2a7b3014013799744f2c4a8ad6a3eec4f2/pydantic_core-2.46.3-cp311-cp311-win_amd64.whl", hash = "sha256:b5b9c6cf08a8a5e502698f5e153056d12c34b8fb30317e0c5fd06f45162a6346", size = 2070837, upload-time = "2026-04-20T14:41:47.707Z" }, + { url = "https://files.pythonhosted.org/packages/9f/1e/264a17cd582f6ed50950d4d03dd5fefd84e570e238afe1cb3e25cf238769/pydantic_core-2.46.3-cp311-cp311-win_arm64.whl", hash = "sha256:5dfd51cf457482f04ec49491811a2b8fd5b843b64b11eecd2d7a1ee596ea78a6", size = 2053647, upload-time = "2026-04-20T14:42:27.535Z" }, + { url = "https://files.pythonhosted.org/packages/4b/cb/5b47425556ecc1f3fe18ed2a0083188aa46e1dd812b06e406475b3a5d536/pydantic_core-2.46.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:b11b59b3eee90a80a36701ddb4576d9ae31f93f05cb9e277ceaa09e6bf074a67", size = 2101946, upload-time = "2026-04-20T14:40:52.581Z" }, + { url = "https://files.pythonhosted.org/packages/a1/4f/2fb62c2267cae99b815bbf4a7b9283812c88ca3153ef29f7707200f1d4e5/pydantic_core-2.46.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:af8653713055ea18a3abc1537fe2ebc42f5b0bbb768d1eb79fd74eb47c0ac089", size = 1951612, upload-time = "2026-04-20T14:42:42.996Z" }, + { url = "https://files.pythonhosted.org/packages/50/6e/b7348fd30d6556d132cddd5bd79f37f96f2601fe0608afac4f5fb01ec0b3/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:75a519dab6d63c514f3a81053e5266c549679e4aa88f6ec57f2b7b854aceb1b0", size = 1977027, upload-time = "2026-04-20T14:42:02.001Z" }, + { url = "https://files.pythonhosted.org/packages/82/11/31d60ee2b45540d3fb0b29302a393dbc01cd771c473f5b5147bcd353e593/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a6cd87cb1575b1ad05ba98894c5b5c96411ef678fa2f6ed2576607095b8d9789", size = 2063008, upload-time = "2026-04-20T14:44:17.952Z" }, + { url = "https://files.pythonhosted.org/packages/8a/db/3a9d1957181b59258f44a2300ab0f0be9d1e12d662a4f57bb31250455c52/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f80a55484b8d843c8ada81ebf70a682f3f00a3d40e378c06cf17ecb44d280d7d", size = 2233082, upload-time = "2026-04-20T14:40:57.934Z" }, + { url = "https://files.pythonhosted.org/packages/9c/e1/3277c38792aeb5cfb18c2f0c5785a221d9ff4e149abbe1184d53d5f72273/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3861f1731b90c50a3266316b9044f5c9b405eecb8e299b0a7120596334e4fe9c", size = 2304615, upload-time = "2026-04-20T14:42:12.584Z" }, + { url = "https://files.pythonhosted.org/packages/5e/d5/e3d9717c9eba10855325650afd2a9cba8e607321697f18953af9d562da2f/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb528e295ed31570ac3dcc9bfdd6e0150bc11ce6168ac87a8082055cf1a67395", size = 2094380, upload-time = "2026-04-20T14:43:05.522Z" }, + { url = "https://files.pythonhosted.org/packages/a1/20/abac35dedcbfd66c6f0b03e4e3564511771d6c9b7ede10a362d03e110d9b/pydantic_core-2.46.3-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:367508faa4973b992b271ba1494acaab36eb7e8739d1e47be5035fb1ea225396", size = 2135429, upload-time = "2026-04-20T14:41:55.549Z" }, + { url = "https://files.pythonhosted.org/packages/6c/a5/41bfd1df69afad71b5cf0535055bccc73022715ad362edbc124bc1e021d7/pydantic_core-2.46.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ad3c826fe523e4becf4fe39baa44286cff85ef137c729a2c5e269afbfd0905d", size = 2174582, upload-time = "2026-04-20T14:41:45.96Z" }, + { url = "https://files.pythonhosted.org/packages/79/65/38d86ea056b29b2b10734eb23329b7a7672ca604df4f2b6e9c02d4ee22fe/pydantic_core-2.46.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ec638c5d194ef8af27db69f16c954a09797c0dc25015ad6123eb2c73a4d271ca", size = 2187533, upload-time = "2026-04-20T14:40:55.367Z" }, + { url = "https://files.pythonhosted.org/packages/b6/55/a1129141678a2026badc539ad1dee0a71d06f54c2f06a4bd68c030ac781b/pydantic_core-2.46.3-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:28ed528c45446062ee66edb1d33df5d88828ae167de76e773a3c7f64bd14e976", size = 2332985, upload-time = "2026-04-20T14:44:13.05Z" }, + { url = "https://files.pythonhosted.org/packages/d7/60/cb26f4077719f709e54819f4e8e1d43f4091f94e285eb6bd21e1190a7b7c/pydantic_core-2.46.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aed19d0c783886d5bd86d80ae5030006b45e28464218747dcf83dabfdd092c7b", size = 2373670, upload-time = "2026-04-20T14:41:53.421Z" }, + { url = "https://files.pythonhosted.org/packages/6b/7e/c3f21882bdf1d8d086876f81b5e296206c69c6082551d776895de7801fa0/pydantic_core-2.46.3-cp312-cp312-win32.whl", hash = "sha256:06d5d8820cbbdb4147578c1fe7ffcd5b83f34508cb9f9ab76e807be7db6ff0a4", size = 1966722, upload-time = "2026-04-20T14:44:30.588Z" }, + { url = "https://files.pythonhosted.org/packages/57/be/6b5e757b859013ebfbd7adba02f23b428f37c86dcbf78b5bb0b4ffd36e99/pydantic_core-2.46.3-cp312-cp312-win_amd64.whl", hash = "sha256:c3212fda0ee959c1dd04c60b601ec31097aaa893573a3a1abd0a47bcac2968c1", size = 2072970, upload-time = "2026-04-20T14:42:54.248Z" }, + { url = "https://files.pythonhosted.org/packages/bf/f8/a989b21cc75e9a32d24192ef700eea606521221a89faa40c919ce884f2b1/pydantic_core-2.46.3-cp312-cp312-win_arm64.whl", hash = "sha256:f1f8338dd7a7f31761f1f1a3c47503a9a3b34eea3c8b01fa6ee96408affb5e72", size = 2035963, upload-time = "2026-04-20T14:44:20.4Z" }, + { url = "https://files.pythonhosted.org/packages/9b/3c/9b5e8eb9821936d065439c3b0fb1490ffa64163bfe7e1595985a47896073/pydantic_core-2.46.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:12bc98de041458b80c86c56b24df1d23832f3e166cbaff011f25d187f5c62c37", size = 2102109, upload-time = "2026-04-20T14:41:24.219Z" }, + { url = "https://files.pythonhosted.org/packages/91/97/1c41d1f5a19f241d8069f1e249853bcce378cdb76eec8ab636d7bc426280/pydantic_core-2.46.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:85348b8f89d2c3508b65b16c3c33a4da22b8215138d8b996912bb1532868885f", size = 1951820, upload-time = "2026-04-20T14:42:14.236Z" }, + { url = "https://files.pythonhosted.org/packages/30/b4/d03a7ae14571bc2b6b3c7b122441154720619afe9a336fa3a95434df5e2f/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1105677a6df914b1fb71a81b96c8cce7726857e1717d86001f29be06a25ee6f8", size = 1977785, upload-time = "2026-04-20T14:42:31.648Z" }, + { url = "https://files.pythonhosted.org/packages/ae/0c/4086f808834b59e3c8f1aa26df8f4b6d998cdcf354a143d18ef41529d1fe/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:87082cd65669a33adeba5470769e9704c7cf026cc30afb9cc77fd865578ebaad", size = 2062761, upload-time = "2026-04-20T14:40:37.093Z" }, + { url = "https://files.pythonhosted.org/packages/fa/71/a649be5a5064c2df0db06e0a512c2281134ed2fcc981f52a657936a7527c/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:60e5f66e12c4f5212d08522963380eaaeac5ebd795826cfd19b2dfb0c7a52b9c", size = 2232989, upload-time = "2026-04-20T14:42:59.254Z" }, + { url = "https://files.pythonhosted.org/packages/a2/84/7756e75763e810b3a710f4724441d1ecc5883b94aacb07ca71c5fb5cfb69/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b6cdf19bf84128d5e7c37e8a73a0c5c10d51103a650ac585d42dd6ae233f2b7f", size = 2303975, upload-time = "2026-04-20T14:41:32.287Z" }, + { url = "https://files.pythonhosted.org/packages/6c/35/68a762e0c1e31f35fa0dac733cbd9f5b118042853698de9509c8e5bf128b/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:031bb17f4885a43773c8c763089499f242aee2ea85cf17154168775dccdecf35", size = 2095325, upload-time = "2026-04-20T14:42:47.685Z" }, + { url = "https://files.pythonhosted.org/packages/77/bf/1bf8c9a8e91836c926eae5e3e51dce009bf495a60ca56060689d3df3f340/pydantic_core-2.46.3-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:bcf2a8b2982a6673693eae7348ef3d8cf3979c1d63b54fca7c397a635cc68687", size = 2133368, upload-time = "2026-04-20T14:41:22.766Z" }, + { url = "https://files.pythonhosted.org/packages/e5/50/87d818d6bab915984995157ceb2380f5aac4e563dddbed6b56f0ed057aba/pydantic_core-2.46.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28e8cf2f52d72ced402a137145923a762cbb5081e48b34312f7a0c8f55928ec3", size = 2173908, upload-time = "2026-04-20T14:42:52.044Z" }, + { url = "https://files.pythonhosted.org/packages/91/88/a311fb306d0bd6185db41fa14ae888fb81d0baf648a761ae760d30819d33/pydantic_core-2.46.3-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:17eaface65d9fc5abb940003020309c1bf7a211f5f608d7870297c367e6f9022", size = 2186422, upload-time = "2026-04-20T14:43:29.55Z" }, + { url = "https://files.pythonhosted.org/packages/8f/79/28fd0d81508525ab2054fef7c77a638c8b5b0afcbbaeee493cf7c3fef7e1/pydantic_core-2.46.3-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:93fd339f23408a07e98950a89644f92c54d8729719a40b30c0a30bb9ebc55d23", size = 2332709, upload-time = "2026-04-20T14:42:16.134Z" }, + { url = "https://files.pythonhosted.org/packages/b3/21/795bf5fe5c0f379308b8ef19c50dedab2e7711dbc8d0c2acf08f1c7daa05/pydantic_core-2.46.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:23cbdb3aaa74dfe0837975dbf69b469753bbde8eacace524519ffdb6b6e89eb7", size = 2372428, upload-time = "2026-04-20T14:41:10.974Z" }, + { url = "https://files.pythonhosted.org/packages/45/b3/ed14c659cbe7605e3ef063077680a64680aec81eb1a04763a05190d49b7f/pydantic_core-2.46.3-cp313-cp313-win32.whl", hash = "sha256:610eda2e3838f401105e6326ca304f5da1e15393ae25dacae5c5c63f2c275b13", size = 1965601, upload-time = "2026-04-20T14:41:42.128Z" }, + { url = "https://files.pythonhosted.org/packages/ef/bb/adb70d9a762ddd002d723fbf1bd492244d37da41e3af7b74ad212609027e/pydantic_core-2.46.3-cp313-cp313-win_amd64.whl", hash = "sha256:68cc7866ed863db34351294187f9b729964c371ba33e31c26f478471c52e1ed0", size = 2071517, upload-time = "2026-04-20T14:43:36.096Z" }, + { url = "https://files.pythonhosted.org/packages/52/eb/66faefabebfe68bd7788339c9c9127231e680b11906368c67ce112fdb47f/pydantic_core-2.46.3-cp313-cp313-win_arm64.whl", hash = "sha256:f64b5537ac62b231572879cd08ec05600308636a5d63bcbdb15063a466977bec", size = 2035802, upload-time = "2026-04-20T14:43:38.507Z" }, + { url = "https://files.pythonhosted.org/packages/7f/db/a7bcb4940183fda36022cd18ba8dd12f2dff40740ec7b58ce7457befa416/pydantic_core-2.46.3-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:afa3aa644f74e290cdede48a7b0bee37d1c35e71b05105f6b340d484af536d9b", size = 2097614, upload-time = "2026-04-20T14:44:38.374Z" }, + { url = "https://files.pythonhosted.org/packages/24/35/e4066358a22e3e99519db370494c7528f5a2aa1367370e80e27e20283543/pydantic_core-2.46.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ced3310e51aa425f7f77da8bbbb5212616655bedbe82c70944320bc1dbe5e018", size = 1951896, upload-time = "2026-04-20T14:40:53.996Z" }, + { url = "https://files.pythonhosted.org/packages/87/92/37cf4049d1636996e4b888c05a501f40a43ff218983a551d57f9d5e14f0d/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e29908922ce9da1a30b4da490bd1d3d82c01dcfdf864d2a74aacee674d0bfa34", size = 1979314, upload-time = "2026-04-20T14:41:49.446Z" }, + { url = "https://files.pythonhosted.org/packages/d8/36/9ff4d676dfbdfb2d591cf43f3d90ded01e15b1404fd101180ed2d62a2fd3/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c9ff69140423eea8ed2d5477df3ba037f671f5e897d206d921bc9fdc39613e7", size = 2056133, upload-time = "2026-04-20T14:42:23.574Z" }, + { url = "https://files.pythonhosted.org/packages/bc/f0/405b442a4d7ba855b06eec8b2bf9c617d43b8432d099dfdc7bf999293495/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b675ab0a0d5b1c8fdb81195dc5bcefea3f3c240871cdd7ff9a2de8aa50772eb2", size = 2228726, upload-time = "2026-04-20T14:44:22.816Z" }, + { url = "https://files.pythonhosted.org/packages/e7/f8/65cd92dd5a0bd89ba277a98ecbfaf6fc36bbd3300973c7a4b826d6ab1391/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0087084960f209a9a4af50ecd1fb063d9ad3658c07bb81a7a53f452dacbfb2ba", size = 2301214, upload-time = "2026-04-20T14:44:48.792Z" }, + { url = "https://files.pythonhosted.org/packages/fd/86/ef96a4c6e79e7a2d0410826a68fbc0eccc0fd44aa733be199d5fcac3bb87/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed42e6cc8e1b0e2b9b96e2276bad70ae625d10d6d524aed0c93de974ae029f9f", size = 2099927, upload-time = "2026-04-20T14:41:40.196Z" }, + { url = "https://files.pythonhosted.org/packages/6d/53/269caf30e0096e0a8a8f929d1982a27b3879872cca2d917d17c2f9fdf4fe/pydantic_core-2.46.3-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:f1771ce258afb3e4201e67d154edbbae712a76a6081079fe247c2f53c6322c22", size = 2128789, upload-time = "2026-04-20T14:41:15.868Z" }, + { url = "https://files.pythonhosted.org/packages/00/b0/1a6d9b6a587e118482910c244a1c5acf4d192604174132efd12bf0ac486f/pydantic_core-2.46.3-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a7610b6a5242a6c736d8ad47fd5fff87fcfe8f833b281b1c409c3d6835d9227f", size = 2173815, upload-time = "2026-04-20T14:44:25.152Z" }, + { url = "https://files.pythonhosted.org/packages/87/56/e7e00d4041a7e62b5a40815590114db3b535bf3ca0bf4dca9f16cef25246/pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:ff5e7783bcc5476e1db448bf268f11cb257b1c276d3e89f00b5727be86dd0127", size = 2181608, upload-time = "2026-04-20T14:41:28.933Z" }, + { url = "https://files.pythonhosted.org/packages/e8/22/4bd23c3d41f7c185d60808a1de83c76cf5aeabf792f6c636a55c3b1ec7f9/pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:9d2e32edcc143bc01e95300671915d9ca052d4f745aa0a49c48d4803f8a85f2c", size = 2326968, upload-time = "2026-04-20T14:42:03.962Z" }, + { url = "https://files.pythonhosted.org/packages/24/ac/66cd45129e3915e5ade3b292cb3bc7fd537f58f8f8dbdaba6170f7cabb74/pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:6e42d83d1c6b87fa56b521479cff237e626a292f3b31b6345c15a99121b454c1", size = 2369842, upload-time = "2026-04-20T14:41:35.52Z" }, + { url = "https://files.pythonhosted.org/packages/a2/51/dd4248abb84113615473aa20d5545b7c4cd73c8644003b5259686f93996c/pydantic_core-2.46.3-cp314-cp314-win32.whl", hash = "sha256:07bc6d2a28c3adb4f7c6ae46aa4f2d2929af127f587ed44057af50bf1ce0f505", size = 1959661, upload-time = "2026-04-20T14:41:00.042Z" }, + { url = "https://files.pythonhosted.org/packages/20/eb/59980e5f1ae54a3b86372bd9f0fa373ea2d402e8cdcd3459334430f91e91/pydantic_core-2.46.3-cp314-cp314-win_amd64.whl", hash = "sha256:8940562319bc621da30714617e6a7eaa6b98c84e8c685bcdc02d7ed5e7c7c44e", size = 2071686, upload-time = "2026-04-20T14:43:16.471Z" }, + { url = "https://files.pythonhosted.org/packages/8c/db/1cf77e5247047dfee34bc01fa9bca134854f528c8eb053e144298893d370/pydantic_core-2.46.3-cp314-cp314-win_arm64.whl", hash = "sha256:5dcbbcf4d22210ced8f837c96db941bdb078f419543472aca5d9a0bb7cddc7df", size = 2026907, upload-time = "2026-04-20T14:43:31.732Z" }, + { url = "https://files.pythonhosted.org/packages/57/c0/b3df9f6a543276eadba0a48487b082ca1f201745329d97dbfa287034a230/pydantic_core-2.46.3-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:d0fe3dce1e836e418f912c1ad91c73357d03e556a4d286f441bf34fed2dbeecf", size = 2095047, upload-time = "2026-04-20T14:42:37.982Z" }, + { url = "https://files.pythonhosted.org/packages/66/57/886a938073b97556c168fd99e1a7305bb363cd30a6d2c76086bf0587b32a/pydantic_core-2.46.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9ce92e58abc722dac1bf835a6798a60b294e48eb0e625ec9fd994b932ac5feee", size = 1934329, upload-time = "2026-04-20T14:43:49.655Z" }, + { url = "https://files.pythonhosted.org/packages/0b/7c/b42eaa5c34b13b07ecb51da21761297a9b8eb43044c864a035999998f328/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a03e6467f0f5ab796a486146d1b887b2dc5e5f9b3288898c1b1c3ad974e53e4a", size = 1974847, upload-time = "2026-04-20T14:42:10.737Z" }, + { url = "https://files.pythonhosted.org/packages/e6/9b/92b42db6543e7de4f99ae977101a2967b63122d4b6cf7773812da2d7d5b5/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2798b6ba041b9d70acfb9071a2ea13c8456dd1e6a5555798e41ba7b0790e329c", size = 2041742, upload-time = "2026-04-20T14:40:44.262Z" }, + { url = "https://files.pythonhosted.org/packages/0f/19/46fbe1efabb5aa2834b43b9454e70f9a83ad9c338c1291e48bdc4fecf167/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9be3e221bdc6d69abf294dcf7aff6af19c31a5cdcc8f0aa3b14be29df4bd03b1", size = 2236235, upload-time = "2026-04-20T14:41:27.307Z" }, + { url = "https://files.pythonhosted.org/packages/77/da/b3f95bc009ad60ec53120f5d16c6faa8cabdbe8a20d83849a1f2b8728148/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f13936129ce841f2a5ddf6f126fea3c43cd128807b5a59588c37cf10178c2e64", size = 2282633, upload-time = "2026-04-20T14:44:33.271Z" }, + { url = "https://files.pythonhosted.org/packages/cc/6e/401336117722e28f32fb8220df676769d28ebdf08f2f4469646d404c43a3/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28b5f2ef03416facccb1c6ef744c69793175fd27e44ef15669201601cf423acb", size = 2109679, upload-time = "2026-04-20T14:44:41.065Z" }, + { url = "https://files.pythonhosted.org/packages/fc/53/b289f9bc8756a32fe718c46f55afaeaf8d489ee18d1a1e7be1db73f42cc4/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:830d1247d77ad23852314f069e9d7ddafeec5f684baf9d7e7065ed46a049c4e6", size = 2108342, upload-time = "2026-04-20T14:42:50.144Z" }, + { url = "https://files.pythonhosted.org/packages/10/5b/8292fc7c1f9111f1b2b7c1b0dcf1179edcd014fc3ea4517499f50b829d71/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0793c90c1a3c74966e7975eaef3ed30ebdff3260a0f815a62a22adc17e4c01c", size = 2157208, upload-time = "2026-04-20T14:42:08.133Z" }, + { url = "https://files.pythonhosted.org/packages/2b/9e/f80044e9ec07580f057a89fc131f78dda7a58751ddf52bbe05eaf31db50f/pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:d2d0aead851b66f5245ec0c4fb2612ef457f8bbafefdf65a2bf9d6bac6140f47", size = 2167237, upload-time = "2026-04-20T14:42:25.412Z" }, + { url = "https://files.pythonhosted.org/packages/f8/84/6781a1b037f3b96be9227edbd1101f6d3946746056231bf4ac48cdff1a8d/pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:2f40e4246676beb31c5ce77c38a55ca4e465c6b38d11ea1bd935420568e0b1ab", size = 2312540, upload-time = "2026-04-20T14:40:40.313Z" }, + { url = "https://files.pythonhosted.org/packages/3e/db/19c0839feeb728e7df03255581f198dfdf1c2aeb1e174a8420b63c5252e5/pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:cf489cf8986c543939aeee17a09c04d6ffb43bfef8ca16fcbcc5cfdcbed24dba", size = 2369556, upload-time = "2026-04-20T14:41:09.427Z" }, + { url = "https://files.pythonhosted.org/packages/e0/15/3228774cb7cd45f5f721ddf1b2242747f4eb834d0c491f0c02d606f09fed/pydantic_core-2.46.3-cp314-cp314t-win32.whl", hash = "sha256:ffe0883b56cfc05798bf994164d2b2ff03efe2d22022a2bb080f3b626176dd56", size = 1949756, upload-time = "2026-04-20T14:41:25.717Z" }, + { url = "https://files.pythonhosted.org/packages/b8/2a/c79cf53fd91e5a87e30d481809f52f9a60dd221e39de66455cf04deaad37/pydantic_core-2.46.3-cp314-cp314t-win_amd64.whl", hash = "sha256:706d9d0ce9cf4593d07270d8e9f53b161f90c57d315aeec4fb4fd7a8b10240d8", size = 2051305, upload-time = "2026-04-20T14:43:18.627Z" }, + { url = "https://files.pythonhosted.org/packages/0b/db/d8182a7f1d9343a032265aae186eb063fe26ca4c40f256b21e8da4498e89/pydantic_core-2.46.3-cp314-cp314t-win_arm64.whl", hash = "sha256:77706aeb41df6a76568434701e0917da10692da28cb69d5fb6919ce5fdb07374", size = 2026310, upload-time = "2026-04-20T14:41:01.778Z" }, + { url = "https://files.pythonhosted.org/packages/31/75/c1ee7cb5b2277fe1f95837a58fb692eeda7162494fc1ddccb5f23be1d7f6/pydantic_core-2.46.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:fa3eb7c2995aa443687a825bc30395c8521b7c6ec201966e55debfd1128bcceb", size = 2112012, upload-time = "2026-04-20T14:44:35.697Z" }, + { url = "https://files.pythonhosted.org/packages/6b/da/fb883281703dc5f4d68cdc648c503c46c8af5726f428013178d657c75181/pydantic_core-2.46.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3d08782c4045f90724b44c95d35ebec0d67edb8a957a2ac81d5a8e4b8a200495", size = 1953006, upload-time = "2026-04-20T14:43:33.878Z" }, + { url = "https://files.pythonhosted.org/packages/92/47/5d7d7d04204920771086d768ca51306e34b63a31ad80a5f82c9d38dea568/pydantic_core-2.46.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:831eb19aa789a97356979e94c981e5667759301fb708d1c0d5adf1bc0098b873", size = 1980050, upload-time = "2026-04-20T14:41:03.154Z" }, + { url = "https://files.pythonhosted.org/packages/e0/e9/1c52019dd95babcff1bffe40022e8541c0447b8e4a44596a979c7309fa0c/pydantic_core-2.46.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4335e87c7afa436a0dfa899e138d57a72f8aad542e2cf19c36fb428461caabd0", size = 2057165, upload-time = "2026-04-20T14:43:44.507Z" }, + { url = "https://files.pythonhosted.org/packages/6f/0e/e0aac1f35baf80ff8f35d4fa58d85dce248324a764d950460cf5c0569758/pydantic_core-2.46.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99421e7684a60f7f3550a1d159ade5fdff1954baedb6bdd407cba6a307c9f27d", size = 2225133, upload-time = "2026-04-20T14:41:07.334Z" }, + { url = "https://files.pythonhosted.org/packages/d5/df/8eb296b9661574ef26e990856991615c1e1fb1744a10b896bff684a3c99a/pydantic_core-2.46.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd81f6907932ebac3abbe41378dac64b2380db1287e2aa64d8d88f78d170f51a", size = 2282409, upload-time = "2026-04-20T14:43:07.567Z" }, + { url = "https://files.pythonhosted.org/packages/d2/07/888c53b769be71072a1dbd741ec25160579d789ef276fd5bd2045a07b09a/pydantic_core-2.46.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f247596366f4221af52beddd65af1218797771d6989bc891a0b86ccaa019168", size = 2095775, upload-time = "2026-04-20T14:42:21.586Z" }, + { url = "https://files.pythonhosted.org/packages/8a/19/6c32bdb93362b899bf92ac42c824898ab93dd8a23f339cbf5c5098ef61a6/pydantic_core-2.46.3-cp39-cp39-manylinux_2_31_riscv64.whl", hash = "sha256:6dff8cc884679df229ebc6d8eb2321ea6f8e091bc7d4886d4dc2e0e71452843c", size = 2118999, upload-time = "2026-04-20T14:44:43.791Z" }, + { url = "https://files.pythonhosted.org/packages/6b/c6/31d926d003f59a032ff61b62990e378f0fb985aa9d77fd448a6140f7eb5f/pydantic_core-2.46.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68ef2f623dda6d5a9067ac014e406c020c780b2a358930a7e5c1b73702900720", size = 2162368, upload-time = "2026-04-20T14:41:12.529Z" }, + { url = "https://files.pythonhosted.org/packages/4f/a1/48d669051947845ff54f5b7cb6254ccafb23aa284184de6f273145d0e45b/pydantic_core-2.46.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d56bdb4af1767cc15b0386b3c581fdfe659bb9ee4a4f776e92c1cd9d074000d6", size = 2184786, upload-time = "2026-04-20T14:42:40.235Z" }, + { url = "https://files.pythonhosted.org/packages/08/ff/a722cade3d4bd8ed6433a8e84eddf2f993b5fb4a47cade269289cfb4cc0c/pydantic_core-2.46.3-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:91249bcb7c165c2fb2a2f852dbc5c91636e2e218e75d96dfdd517e4078e173dd", size = 2325626, upload-time = "2026-04-20T14:41:37.73Z" }, + { url = "https://files.pythonhosted.org/packages/ad/8a/238e33805d6f3691bcce8739db7d0376a2388e1b3f2c8db2128f6683fc78/pydantic_core-2.46.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4b068543bdb707f5d935dab765d99227aa2545ef2820935f2e5dd801795c7dbd", size = 2363286, upload-time = "2026-04-20T14:42:29.385Z" }, + { url = "https://files.pythonhosted.org/packages/ad/2e/ab044f4431798a565242d5e8e48d080faa931f45e3d30df62e4f501d9bb0/pydantic_core-2.46.3-cp39-cp39-win32.whl", hash = "sha256:dcda6583921c05a40533f982321532f2d8db29326c7b95c4026941fa5074bd79", size = 1981660, upload-time = "2026-04-20T14:43:54.525Z" }, + { url = "https://files.pythonhosted.org/packages/d0/2c/13855786276f51fe86915c0533f4fc14e1d5421726ba8ad57caa09eb18ec/pydantic_core-2.46.3-cp39-cp39-win_amd64.whl", hash = "sha256:a35cc284c8dd7edae8a31533713b4d2467dfe7c4f1b5587dd4031f28f90d1d13", size = 2078793, upload-time = "2026-04-20T14:42:17.87Z" }, + { url = "https://files.pythonhosted.org/packages/66/7f/03dbad45cd3aa9083fbc93c210ae8b005af67e4136a14186950a747c6874/pydantic_core-2.46.3-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:9715525891ed524a0a1eb6d053c74d4d4ad5017677fb00af0b7c2644a31bae46", size = 2105683, upload-time = "2026-04-20T14:42:19.779Z" }, + { url = "https://files.pythonhosted.org/packages/26/22/4dc186ac8ea6b257e9855031f51b62a9637beac4d68ac06bee02f046f836/pydantic_core-2.46.3-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:9d2f400712a99a013aff420ef1eb9be077f8189a36c1e3ef87660b4e1088a874", size = 1940052, upload-time = "2026-04-20T14:43:59.274Z" }, + { url = "https://files.pythonhosted.org/packages/0d/ca/d376391a5aff1f2e8188960d7873543608130a870961c2b6b5236627c116/pydantic_core-2.46.3-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd2aab0e2e9dc2daf36bd2686c982535d5e7b1d930a1344a7bb6e82baab42a76", size = 1988172, upload-time = "2026-04-20T14:41:17.469Z" }, + { url = "https://files.pythonhosted.org/packages/0e/6b/523b9f85c23788755d6ab949329de692a2e3a584bc6beb67fef5e035aa9d/pydantic_core-2.46.3-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e9d76736da5f362fabfeea6a69b13b7f2be405c6d6966f06b2f6bfff7e64531", size = 2128596, upload-time = "2026-04-20T14:40:41.707Z" }, + { url = "https://files.pythonhosted.org/packages/34/42/f426db557e8ab2791bc7562052299944a118655496fbff99914e564c0a94/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:b12dd51f1187c2eb489af8e20f880362db98e954b54ab792fa5d92e8bcc6b803", size = 2091877, upload-time = "2026-04-20T14:43:27.091Z" }, + { url = "https://files.pythonhosted.org/packages/5c/4f/86a832a9d14df58e663bfdf4627dc00d3317c2bd583c4fb23390b0f04b8e/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:f00a0961b125f1a47af7bcc17f00782e12f4cd056f83416006b30111d941dfa3", size = 1932428, upload-time = "2026-04-20T14:40:45.781Z" }, + { url = "https://files.pythonhosted.org/packages/11/1a/fe857968954d93fb78e0d4b6df5c988c74c4aaa67181c60be7cfe327c0ca/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57697d7c056aca4bbb680200f96563e841a6386ac1129370a0102592f4dddff5", size = 1997550, upload-time = "2026-04-20T14:44:02.425Z" }, + { url = "https://files.pythonhosted.org/packages/17/eb/9d89ad2d9b0ba8cd65393d434471621b98912abb10fbe1df08e480ba57b5/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd35aa21299def8db7ef4fe5c4ff862941a9a158ca7b63d61e66fe67d30416b4", size = 2137657, upload-time = "2026-04-20T14:42:45.149Z" }, + { url = "https://files.pythonhosted.org/packages/1f/da/99d40830684f81dec901cac521b5b91c095394cc1084b9433393cde1c2df/pydantic_core-2.46.3-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:13afdd885f3d71280cf286b13b310ee0f7ccfefd1dbbb661514a474b726e2f25", size = 2107973, upload-time = "2026-04-20T14:42:06.175Z" }, + { url = "https://files.pythonhosted.org/packages/99/a5/87024121818d75bbb2a98ddbaf638e40e7a18b5e0f5492c9ca4b1b316107/pydantic_core-2.46.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:f91c0aff3e3ee0928edd1232c57f643a7a003e6edf1860bc3afcdc749cb513f3", size = 1947191, upload-time = "2026-04-20T14:43:14.319Z" }, + { url = "https://files.pythonhosted.org/packages/60/62/0c1acfe10945b83a6a59d19fbaa92f48825381509e5701b855c08f13db76/pydantic_core-2.46.3-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6529d1d128321a58d30afcc97b49e98836542f68dd41b33c2e972bb9e5290536", size = 2123791, upload-time = "2026-04-20T14:43:22.766Z" }, + { url = "https://files.pythonhosted.org/packages/75/3e/3b2393b4c8f44285561dc30b00cf307a56a2eff7c483a824db3b8221ca51/pydantic_core-2.46.3-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:975c267cff4f7e7272eacbe50f6cc03ca9a3da4c4fbd66fffd89c94c1e311aa1", size = 2153197, upload-time = "2026-04-20T14:44:27.932Z" }, + { url = "https://files.pythonhosted.org/packages/ba/75/5af02fb35505051eee727c061f2881c555ab4f8ddb2d42da715a42c9731b/pydantic_core-2.46.3-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:2b8e4f2bbdf71415c544b4b1138b8060db7b6611bc927e8064c769f64bed651c", size = 2181073, upload-time = "2026-04-20T14:43:20.729Z" }, + { url = "https://files.pythonhosted.org/packages/10/92/7e0e1bd9ca3c68305db037560ca2876f89b2647deb2f8b6319005de37505/pydantic_core-2.46.3-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:e61ea8e9fff9606d09178f577ff8ccdd7206ff73d6552bcec18e1033c4254b85", size = 2315886, upload-time = "2026-04-20T14:44:04.826Z" }, + { url = "https://files.pythonhosted.org/packages/b8/d8/101655f27eaf3e44558ead736b2795d12500598beed4683f279396fa186e/pydantic_core-2.46.3-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b504bda01bafc69b6d3c7a0c7f039dcf60f47fab70e06fe23f57b5c75bdc82b8", size = 2360528, upload-time = "2026-04-20T14:40:47.431Z" }, + { url = "https://files.pythonhosted.org/packages/07/0f/1c34a74c8d07136f0d729ffe5e1fdab04fbdaa7684f61a92f92511a84a15/pydantic_core-2.46.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:b00b76f7142fc60c762ce579bd29c8fa44aaa56592dd3c54fab3928d0d4ca6ff", size = 2184144, upload-time = "2026-04-20T14:42:57Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "pyright" +version = "1.1.399" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nodeenv" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/9d/d91d5f6d26b2db95476fefc772e2b9a16d54c6bd0ea6bb5c1b6d635ab8b4/pyright-1.1.399.tar.gz", hash = "sha256:439035d707a36c3d1b443aec980bc37053fbda88158eded24b8eedcf1c7b7a1b", size = 3856954, upload-time = "2025-04-10T04:40:25.703Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2f/b5/380380c9e7a534cb1783c70c3e8ac6d1193c599650a55838d0557586796e/pyright-1.1.399-py3-none-any.whl", hash = "sha256:55f9a875ddf23c9698f24208c764465ffdfd38be6265f7faf9a176e1dc549f3b", size = 5592584, upload-time = "2025-04-10T04:40:23.502Z" }, +] + +[[package]] +name = "pytest" +version = "8.4.2" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.10'", +] +dependencies = [ + { name = "colorama", marker = "(python_full_version < '3.10' and sys_platform == 'win32') or (python_full_version >= '3.10' and extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2') or (sys_platform != 'win32' and extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "exceptiongroup", marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "iniconfig", version = "2.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "packaging", marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "pluggy", marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "pygments", marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "tomli", marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618, upload-time = "2025-09-04T14:34:22.711Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750, upload-time = "2025-09-04T14:34:20.226Z" }, +] + +[[package]] +name = "pytest" +version = "9.0.3" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14' and extra != 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and python_full_version < '3.14' and extra != 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and extra == 'group-10-cloudflare-pydantic-v1' and extra != 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and extra != 'group-10-cloudflare-pydantic-v1' and extra != 'group-10-cloudflare-pydantic-v2'", +] +dependencies = [ + { name = "colorama", marker = "(python_full_version >= '3.10' and sys_platform == 'win32') or (python_full_version < '3.10' and extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2') or (sys_platform != 'win32' and extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "exceptiongroup", marker = "python_full_version == '3.10.*' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "iniconfig", version = "2.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "packaging", marker = "python_full_version >= '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "pluggy", marker = "python_full_version >= '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "pygments", marker = "python_full_version >= '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "tomli", marker = "python_full_version == '3.10.*' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7d/0d/549bd94f1a0a402dc8cf64563a117c0f3765662e2e668477624baeec44d5/pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c", size = 1572165, upload-time = "2026-04-07T17:16:18.027Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", size = 375249, upload-time = "2026-04-07T17:16:16.13Z" }, +] + +[[package]] +name = "pytest-asyncio" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.10'", +] +dependencies = [ + { name = "backports-asyncio-runner", marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "pytest", version = "8.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "typing-extensions", marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/86/9e3c5f48f7b7b638b216e4b9e645f54d199d7abbbab7a64a13b4e12ba10f/pytest_asyncio-1.2.0.tar.gz", hash = "sha256:c609a64a2a8768462d0c99811ddb8bd2583c33fd33cf7f21af1c142e824ffb57", size = 50119, upload-time = "2025-09-12T07:33:53.816Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/93/2fa34714b7a4ae72f2f8dad66ba17dd9a2c793220719e736dda28b7aec27/pytest_asyncio-1.2.0-py3-none-any.whl", hash = "sha256:8e17ae5e46d8e7efe51ab6494dd2010f4ca8dae51652aa3c8d55acf50bfb2e99", size = 15095, upload-time = "2025-09-12T07:33:52.639Z" }, +] + +[[package]] +name = "pytest-asyncio" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14' and extra != 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and python_full_version < '3.14' and extra != 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and extra == 'group-10-cloudflare-pydantic-v1' and extra != 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and extra != 'group-10-cloudflare-pydantic-v1' and extra != 'group-10-cloudflare-pydantic-v2'", +] +dependencies = [ + { name = "backports-asyncio-runner", marker = "python_full_version == '3.10.*' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "pytest", version = "9.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "typing-extensions", marker = "(python_full_version >= '3.10' and python_full_version < '3.13') or (python_full_version < '3.10' and extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2') or (python_full_version >= '3.13' and extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/90/2c/8af215c0f776415f3590cac4f9086ccefd6fd463befeae41cd4d3f193e5a/pytest_asyncio-1.3.0.tar.gz", hash = "sha256:d7f52f36d231b80ee124cd216ffb19369aa168fc10095013c6b014a34d3ee9e5", size = 50087, upload-time = "2025-11-10T16:07:47.256Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/35/f8b19922b6a25bc0880171a2f1a003eaeb93657475193ab516fd87cac9da/pytest_asyncio-1.3.0-py3-none-any.whl", hash = "sha256:611e26147c7f77640e6d0a92a38ed17c3e9848063698d5c93d5aa7aa11cebff5", size = 15075, upload-time = "2025-11-10T16:07:45.537Z" }, +] + +[[package]] +name = "pytest-xdist" +version = "3.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "execnet" }, + { name = "pytest", version = "8.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "pytest", version = "9.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/78/b4/439b179d1ff526791eb921115fca8e44e596a13efeda518b9d845a619450/pytest_xdist-3.8.0.tar.gz", hash = "sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1", size = 88069, upload-time = "2025-07-01T13:30:59.346Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl", hash = "sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88", size = 46396, upload-time = "2025-07-01T13:30:56.632Z" }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six", marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, +] + +[[package]] +name = "respx" +version = "0.23.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "httpx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/43/98/4e55c9c486404ec12373708d015ebce157966965a5ebe7f28ff2c784d41b/respx-0.23.1.tar.gz", hash = "sha256:242dcc6ce6b5b9bf621f5870c82a63997e8e82bc7c947f9ffe272b8f3dd5a780", size = 29243, upload-time = "2026-04-08T14:37:16.008Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1d/4a/221da6ca167db45693d8d26c7dc79ccfc978a440251bf6721c9aaf251ac0/respx-0.23.1-py2.py3-none-any.whl", hash = "sha256:b18004b029935384bccfa6d7d9d74b4ec9af73a081cc28600fffc0447f4b8c1a", size = 25557, upload-time = "2026-04-08T14:37:14.613Z" }, +] + +[[package]] +name = "rich" +version = "15.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "markdown-it-py", version = "4.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" }, +] + +[[package]] +name = "ruff" +version = "0.15.12" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/99/43/3291f1cc9106f4c63bdce7a8d0df5047fe8422a75b091c16b5e9355e0b11/ruff-0.15.12.tar.gz", hash = "sha256:ecea26adb26b4232c0c2ca19ccbc0083a68344180bba2a600605538ce51a40a6", size = 4643852, upload-time = "2026-04-24T18:17:14.305Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c3/6e/e78ffb61d4686f3d96ba3df2c801161843746dcbcbb17a1e927d4829312b/ruff-0.15.12-py3-none-linux_armv6l.whl", hash = "sha256:f86f176e188e94d6bdbc09f09bfd9dc729059ad93d0e7390b5a73efe19f8861c", size = 10640713, upload-time = "2026-04-24T18:17:22.841Z" }, + { url = "https://files.pythonhosted.org/packages/ae/08/a317bc231fb9e7b93e4ef3089501e51922ff88d6936ce5cf870c4fe55419/ruff-0.15.12-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:e3bcd123364c3770b8e1b7baaf343cc99a35f197c5c6e8af79015c666c423a6c", size = 11069267, upload-time = "2026-04-24T18:17:30.105Z" }, + { url = "https://files.pythonhosted.org/packages/aa/a4/f828e9718d3dce1f5f11c39c4f65afd32783c8b2aebb2e3d259e492c47bd/ruff-0.15.12-py3-none-macosx_11_0_arm64.whl", hash = "sha256:fe87510d000220aa1ed530d4448a7c696a0cae1213e5ec30e5874287b66557b5", size = 10397182, upload-time = "2026-04-24T18:17:07.177Z" }, + { url = "https://files.pythonhosted.org/packages/71/e0/3310fc6d1b5e1fdea22bf3b1b807c7e187b581021b0d7d4514cccdb5fb71/ruff-0.15.12-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84a1630093121375a3e2a95b4a6dc7b59e2b4ee76216e32d81aae550a832d002", size = 10758012, upload-time = "2026-04-24T18:16:55.759Z" }, + { url = "https://files.pythonhosted.org/packages/11/c1/a606911aee04c324ddaa883ae418f3569792fd3c4a10c50e0dd0a2311e1e/ruff-0.15.12-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fb129f40f114f089ebe0ca56c0d251cf2061b17651d464bb6478dc01e69f11f5", size = 10447479, upload-time = "2026-04-24T18:16:51.677Z" }, + { url = "https://files.pythonhosted.org/packages/9d/68/4201e8444f0894f21ab4aeeaee68aa4f10b51613514a20d80bd628d57e88/ruff-0.15.12-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0c862b172d695db7598426b8af465e7e9ac00a3ea2a3630ee67eb82e366aaa6", size = 11234040, upload-time = "2026-04-24T18:17:16.529Z" }, + { url = "https://files.pythonhosted.org/packages/34/ff/8a6d6cf4ccc23fd67060874e832c18919d1557a0611ebef03fdb01fff11e/ruff-0.15.12-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2849ea9f3484c3aca43a82f484210370319e7170df4dfe4843395ddf6c57bc33", size = 12087377, upload-time = "2026-04-24T18:17:04.944Z" }, + { url = "https://files.pythonhosted.org/packages/85/f6/c669cf73f5152f623d34e69866a46d5e6185816b19fcd5b6dd8a2d299922/ruff-0.15.12-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9e77c7e51c07fe396826d5969a5b846d9cd4c402535835fb6e21ce8b28fef847", size = 11367784, upload-time = "2026-04-24T18:17:25.409Z" }, + { url = "https://files.pythonhosted.org/packages/e8/39/c61d193b8a1daaa8977f7dea9e8d8ba866e02ea7b65d32f6861693aa4c12/ruff-0.15.12-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83b2f4f2f3b1026b5fb449b467d9264bf22067b600f7b6f41fc5958909f449d0", size = 11344088, upload-time = "2026-04-24T18:17:12.258Z" }, + { url = "https://files.pythonhosted.org/packages/c2/8d/49afab3645e31e12c590acb6d3b5b69d7aab5b81926dbaf7461f9441f37a/ruff-0.15.12-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:9ba3b8f1afd7e2e43d8943e55f249e13f9682fde09711644a6e7290eb4f3e339", size = 11271770, upload-time = "2026-04-24T18:17:02.457Z" }, + { url = "https://files.pythonhosted.org/packages/46/06/33f41fe94403e2b755481cdfb9b7ef3e4e0ed031c4581124658d935d52b4/ruff-0.15.12-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e852ba9fdc890655e1d78f2df1499efbe0e54126bd405362154a75e2bde159c5", size = 10719355, upload-time = "2026-04-24T18:17:27.648Z" }, + { url = "https://files.pythonhosted.org/packages/0d/59/18aa4e014debbf559670e4048e39260a85c7fcee84acfd761ac01e7b8d35/ruff-0.15.12-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:dd8aed930da53780d22fc70bdf84452c843cf64f8cb4eb38984319c24c5cd5fd", size = 10462758, upload-time = "2026-04-24T18:17:32.347Z" }, + { url = "https://files.pythonhosted.org/packages/25/e7/cc9f16fd0f3b5fddcbd7ec3d6ae30c8f3fde1047f32a4093a98d633c6570/ruff-0.15.12-py3-none-musllinux_1_2_i686.whl", hash = "sha256:01da3988d225628b709493d7dc67c3b9b12c0210016b08690ef9bd27970b262b", size = 10953498, upload-time = "2026-04-24T18:17:20.674Z" }, + { url = "https://files.pythonhosted.org/packages/72/7a/a9ba7f98c7a575978698f4230c5e8cc54bbc761af34f560818f933dafa0c/ruff-0.15.12-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:9cae0f92bd5700d1213188b31cd3bdd2b315361296d10b96b8e2337d3d11f53e", size = 11447765, upload-time = "2026-04-24T18:17:09.755Z" }, + { url = "https://files.pythonhosted.org/packages/ea/f9/0ae446942c846b8266059ad8a30702a35afae55f5cdc54c5adf8d7afdc27/ruff-0.15.12-py3-none-win32.whl", hash = "sha256:d0185894e038d7043ba8fd6aee7499ece6462dc0ea9f1e260c7451807c714c20", size = 10657277, upload-time = "2026-04-24T18:17:18.591Z" }, + { url = "https://files.pythonhosted.org/packages/33/f1/9614e03e1cdcbf9437570b5400ced8a720b5db22b28d8e0f1bda429f660d/ruff-0.15.12-py3-none-win_amd64.whl", hash = "sha256:c87a162d61ab3adca47c03f7f717c68672edec7d1b5499e652331780fe74950d", size = 11837758, upload-time = "2026-04-24T18:17:00.113Z" }, + { url = "https://files.pythonhosted.org/packages/c0/98/6beb4b351e472e5f4c4613f7c35a5290b8be2497e183825310c4c3a3984b/ruff-0.15.12-py3-none-win_arm64.whl", hash = "sha256:a538f7a82d061cee7be55542aca1d86d1393d55d81d4fcc314370f4340930d4f", size = 11120821, upload-time = "2026-04-24T18:16:57.979Z" }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, +] + +[[package]] +name = "time-machine" +version = "2.19.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.10'", +] +dependencies = [ + { name = "python-dateutil", marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f8/a4/1b5fdd165f61b67f445fac2a7feb0c655118edef429cd09ff5a8067f7f1d/time_machine-2.19.0.tar.gz", hash = "sha256:7c5065a8b3f2bbb449422c66ef71d114d3f909c276a6469642ecfffb6a0fcd29", size = 14576, upload-time = "2025-08-19T17:22:08.402Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/8f/19125611ebbcb3a14da14cd982b9eb4573e2733db60c9f1fbf6a39534f40/time_machine-2.19.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b5169018ef47206997b46086ce01881cd3a4666fd2998c9d76a87858ca3e49e9", size = 19659, upload-time = "2025-08-19T17:20:30.062Z" }, + { url = "https://files.pythonhosted.org/packages/74/da/9b0a928321e7822a3ff96dbd1eae089883848e30e9e1b149b85fb96ba56b/time_machine-2.19.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:85bb7ed440fccf6f6d0c8f7d68d849e7c3d1f771d5e0b2cdf871fa6561da569f", size = 15157, upload-time = "2025-08-19T17:20:31.931Z" }, + { url = "https://files.pythonhosted.org/packages/36/ff/d7e943422038f5f2161fe2c2d791e64a45be691ef946020b20f3a6efc4d4/time_machine-2.19.0-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a3b12028af1cdc09ccd595be2168b7b26f206c1e190090b048598fbe278beb8e", size = 32860, upload-time = "2025-08-19T17:20:33.241Z" }, + { url = "https://files.pythonhosted.org/packages/fc/80/2b0f1070ed9808ee7da7a6da62a4a0b776957cb4d861578348f86446e778/time_machine-2.19.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c261f073086cf081d1443cbf7684148c662659d3d139d06b772bfe3fe7cc71a6", size = 34510, upload-time = "2025-08-19T17:20:34.221Z" }, + { url = "https://files.pythonhosted.org/packages/ef/b4/48038691c8d89924b36c83335a73adeeb68c884f5a1da08a5b17b8a956f3/time_machine-2.19.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:011954d951230a9f1079f22b39ed1a3a9abb50ee297dfb8c557c46351659d94d", size = 36204, upload-time = "2025-08-19T17:20:35.163Z" }, + { url = "https://files.pythonhosted.org/packages/37/2e/60e8adb541df195e83cb74b720b2cfb1f22ed99c5a7f8abf2a9ab3442cb5/time_machine-2.19.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b0f83308b29c7872006803f2e77318874eb84d0654f2afe0e48e3822e7a2e39b", size = 34936, upload-time = "2025-08-19T17:20:36.61Z" }, + { url = "https://files.pythonhosted.org/packages/5e/72/e8cee59c6cd99dd3b25b8001a0253e779a286aa8f44d5b40777cbd66210b/time_machine-2.19.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:39733ef844e2984620ec9382a42d00cccc4757d75a5dd572be8c2572e86e50b9", size = 32932, upload-time = "2025-08-19T17:20:37.901Z" }, + { url = "https://files.pythonhosted.org/packages/2c/eb/83f300d93c1504965d944e03679f1c943a923bce2d0fdfadef0e2e22cc13/time_machine-2.19.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f8db99f6334432e9ffbf00c215caf2ae9773f17cec08304d77e9e90febc3507b", size = 34010, upload-time = "2025-08-19T17:20:39.202Z" }, + { url = "https://files.pythonhosted.org/packages/e1/77/f35f2500e04daac5033a22fbfd17e68467822b8406ee77966bf222ccaa26/time_machine-2.19.0-cp310-cp310-win32.whl", hash = "sha256:72bf66cd19e27ffd26516b9cbe676d50c2e0b026153289765dfe0cf406708128", size = 17121, upload-time = "2025-08-19T17:20:40.108Z" }, + { url = "https://files.pythonhosted.org/packages/db/df/32d3e0404be1760a64a44caab2af34b07e952bfe00a23134fea9ddba3e8a/time_machine-2.19.0-cp310-cp310-win_amd64.whl", hash = "sha256:46f1c945934ce3d6b4f388b8e581fce7f87ec891ea90d7128e19520e434f96f0", size = 17957, upload-time = "2025-08-19T17:20:41.079Z" }, + { url = "https://files.pythonhosted.org/packages/66/df/598a71a1afb4b509a4587273b76590b16d9110a3e9106f01eedc68d02bb2/time_machine-2.19.0-cp310-cp310-win_arm64.whl", hash = "sha256:fb4897c7a5120a4fd03f0670f332d83b7e55645886cd8864a71944c4c2e5b35b", size = 16821, upload-time = "2025-08-19T17:20:41.967Z" }, + { url = "https://files.pythonhosted.org/packages/1d/ed/4815ebcc9b6c14273f692b9be38a9b09eae52a7e532407cc61a51912b121/time_machine-2.19.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5ee91664880434d98e41585c3446dac7180ec408c786347451ddfca110d19296", size = 19342, upload-time = "2025-08-19T17:20:43.207Z" }, + { url = "https://files.pythonhosted.org/packages/ee/08/154cce8b11b60d8238b0b751b8901d369999f4e8f7c3a5f917caa5d95b0b/time_machine-2.19.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ed3732b83a893d1c7b8cabde762968b4dc5680ee0d305b3ecca9bb516f4e3862", size = 14978, upload-time = "2025-08-19T17:20:44.134Z" }, + { url = "https://files.pythonhosted.org/packages/c7/b7/b689d8c8eeca7af375cfcd64973e49e83aa817cc00f80f98548d42c0eb50/time_machine-2.19.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:6ba0303e9cc9f7f947e344f501e26bedfb68fab521e3c2729d370f4f332d2d55", size = 30964, upload-time = "2025-08-19T17:20:45.366Z" }, + { url = "https://files.pythonhosted.org/packages/80/91/38bf9c79674e95ce32e23c267055f281dff651eec77ed32a677db3dc011a/time_machine-2.19.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2851825b524a988ee459c37c1c26bdfaa7eff78194efb2b562ea497a6f375b0a", size = 32606, upload-time = "2025-08-19T17:20:46.693Z" }, + { url = "https://files.pythonhosted.org/packages/19/4a/e9222d85d4de68975a5e799f539a9d32f3a134a9101fca0a61fa6aa33d68/time_machine-2.19.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:68d32b09ecfd7fef59255c091e8e7c24dd117f882c4880b5c7ab8c5c32a98f89", size = 34405, upload-time = "2025-08-19T17:20:48.032Z" }, + { url = "https://files.pythonhosted.org/packages/14/e2/09480d608d42d6876f9ff74593cfc9197a7eb2c31381a74fb2b145575b65/time_machine-2.19.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:60c46ab527bf2fa144b530f639cc9e12803524c9e1f111dc8c8f493bb6586eeb", size = 33181, upload-time = "2025-08-19T17:20:48.937Z" }, + { url = "https://files.pythonhosted.org/packages/84/64/f9359e000fad32d9066305c48abc527241d608bcdf77c19d67d66e268455/time_machine-2.19.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:56f26ab9f0201c453d18fe76bb7d1cf05fe58c1b9d9cb0c7d243d05132e01292", size = 31036, upload-time = "2025-08-19T17:20:50.276Z" }, + { url = "https://files.pythonhosted.org/packages/71/0d/fab2aacec71e3e482bd7fce0589381f9414a4a97f8766bddad04ad047b7b/time_machine-2.19.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6c806cf3c1185baa1d807b7f51bed0db7a6506832c961d5d1b4c94c775749bc0", size = 32145, upload-time = "2025-08-19T17:20:51.449Z" }, + { url = "https://files.pythonhosted.org/packages/44/fb/faeba2405fb27553f7b28db441a500e2064ffdb2dcba001ee315fdd2c121/time_machine-2.19.0-cp311-cp311-win32.whl", hash = "sha256:b30039dfd89855c12138095bee39c540b4633cbc3684580d684ef67a99a91587", size = 17004, upload-time = "2025-08-19T17:20:52.38Z" }, + { url = "https://files.pythonhosted.org/packages/2f/84/87e483d660ca669426192969280366635c845c3154a9fe750be546ed3afc/time_machine-2.19.0-cp311-cp311-win_amd64.whl", hash = "sha256:13ed8b34430f1de79905877f5600adffa626793ab4546a70a99fb72c6a3350d8", size = 17822, upload-time = "2025-08-19T17:20:53.348Z" }, + { url = "https://files.pythonhosted.org/packages/41/f4/ebf7bbf5047854a528adaf54a5e8780bc5f7f0104c298ab44566a3053bf8/time_machine-2.19.0-cp311-cp311-win_arm64.whl", hash = "sha256:cc29a50a0257d8750b08056b66d7225daab47606832dea1a69e8b017323bf511", size = 16680, upload-time = "2025-08-19T17:20:54.26Z" }, + { url = "https://files.pythonhosted.org/packages/9b/aa/7e00614d339e4d687f6e96e312a1566022528427d237ec639df66c4547bc/time_machine-2.19.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:c85cf437dc3c07429456d8d6670ac90ecbd8241dcd0fbf03e8db2800576f91ff", size = 19308, upload-time = "2025-08-19T17:20:55.25Z" }, + { url = "https://files.pythonhosted.org/packages/ab/3c/bde3c757394f5bca2fbc1528d4117960a26c38f9b160bf471b38d2378d8f/time_machine-2.19.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d9238897e8ef54acdf59f5dff16f59ca0720e7c02d820c56b4397c11db5d3eb9", size = 15019, upload-time = "2025-08-19T17:20:56.204Z" }, + { url = "https://files.pythonhosted.org/packages/c8/e0/8ca916dd918018352d377f1f5226ee071cfbeb7dbbde2b03d14a411ac2b1/time_machine-2.19.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e312c7d5d6bfffb96c6a7b39ff29e3046de100d7efaa3c01552654cfbd08f14c", size = 33079, upload-time = "2025-08-19T17:20:57.166Z" }, + { url = "https://files.pythonhosted.org/packages/48/69/184a0209f02dd0cb5e01e8d13cd4c97a5f389c4e3d09b95160dd676ad1e7/time_machine-2.19.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:714c40b2c90d1c57cc403382d5a9cf16e504cb525bfe9650095317da3c3d62b5", size = 34925, upload-time = "2025-08-19T17:20:58.117Z" }, + { url = "https://files.pythonhosted.org/packages/43/42/4bbf4309e8e57cea1086eb99052d97ff6ddecc1ab6a3b07aa4512f8bf963/time_machine-2.19.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2eaa1c675d500dc3ccae19e9fb1feff84458a68c132bbea47a80cc3dd2df7072", size = 36384, upload-time = "2025-08-19T17:20:59.108Z" }, + { url = "https://files.pythonhosted.org/packages/b1/af/9f510dc1719157348c1a2e87423aed406589070b54b503cb237d9bf3a4fe/time_machine-2.19.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e77a414e9597988af53b2b2e67242c9d2f409769df0d264b6d06fda8ca3360d4", size = 34881, upload-time = "2025-08-19T17:21:00.116Z" }, + { url = "https://files.pythonhosted.org/packages/ca/28/61764a635c70cc76c76ba582dfdc1a84834cddaeb96789023af5214426b2/time_machine-2.19.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:cd93996970e11c382b04d4937c3cd0b0167adeef14725ece35aae88d8a01733c", size = 32931, upload-time = "2025-08-19T17:21:01.095Z" }, + { url = "https://files.pythonhosted.org/packages/b6/e0/f028d93b266e6ade8aca5851f76ebbc605b2905cdc29981a2943b43e1a6c/time_machine-2.19.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8e20a6d8d6e23174bd7e931e134d9610b136db460b249d07e84ecdad029ec352", size = 34241, upload-time = "2025-08-19T17:21:02.052Z" }, + { url = "https://files.pythonhosted.org/packages/7d/a6/36d1950ed1d3f613158024cf1dcc73db1d9ef0b9117cf51ef2e37dc06499/time_machine-2.19.0-cp312-cp312-win32.whl", hash = "sha256:95afc9bc65228b27be80c2756799c20b8eb97c4ef382a9b762b6d7888bc84099", size = 17021, upload-time = "2025-08-19T17:21:03.374Z" }, + { url = "https://files.pythonhosted.org/packages/b1/0d/e2dce93355abda3cac69e77fe96566757e98b8fe7fdcbddce89c9ced3f5f/time_machine-2.19.0-cp312-cp312-win_amd64.whl", hash = "sha256:e84909af950e2448f4e2562ea5759c946248c99ab380d2b47d79b62bd76fa236", size = 17857, upload-time = "2025-08-19T17:21:04.331Z" }, + { url = "https://files.pythonhosted.org/packages/eb/28/50ae6fb83b7feeeca7a461c0dc156cf7ef5e6ef594a600d06634fde6a2cb/time_machine-2.19.0-cp312-cp312-win_arm64.whl", hash = "sha256:0390a1ea9fa7e9d772a39b7c61b34fdcca80eb9ffac339cc0441c6c714c81470", size = 16677, upload-time = "2025-08-19T17:21:05.39Z" }, + { url = "https://files.pythonhosted.org/packages/a9/b8/24ebce67aa531bae2cbe164bb3f4abc6467dc31f3aead35e77f5a075ea3e/time_machine-2.19.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:5e172866753e6041d3b29f3037dc47c20525176a494a71bbd0998dfdc4f11f2f", size = 19373, upload-time = "2025-08-19T17:21:06.701Z" }, + { url = "https://files.pythonhosted.org/packages/53/a5/c9a5240fd2f845d3ff9fa26f8c8eaa29f7239af9d65007e61d212250f15b/time_machine-2.19.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f70f68379bd6f542ae6775cce9a4fa3dcc20bf7959c42eaef871c14469e18097", size = 15056, upload-time = "2025-08-19T17:21:07.667Z" }, + { url = "https://files.pythonhosted.org/packages/b9/92/66cce5d2fb2a5e68459aca85fd18a7e2d216f725988940cd83f96630f2f1/time_machine-2.19.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e69e0b0f694728a00e72891ef8dd00c7542952cb1c87237db594b6b27d504a96", size = 33172, upload-time = "2025-08-19T17:21:08.619Z" }, + { url = "https://files.pythonhosted.org/packages/ae/20/b499e9ab4364cd466016c33dcdf4f56629ca4c20b865bd4196d229f31d92/time_machine-2.19.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:3ae0a8b869574301ec5637e32c270c7384cca5cd6e230f07af9d29271a7fa293", size = 35042, upload-time = "2025-08-19T17:21:09.622Z" }, + { url = "https://files.pythonhosted.org/packages/41/32/b252d3d32791eb16c07d553c820dbc33d9c7fa771de3d1c602190bded2b7/time_machine-2.19.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:554e4317de90e2f7605ff80d153c8bb56b38c0d0c0279feb17e799521e987b8c", size = 36535, upload-time = "2025-08-19T17:21:10.571Z" }, + { url = "https://files.pythonhosted.org/packages/98/cf/4d0470062b9742e1b040ab81bad04d1a5d1de09806507bb6188989cfa1a7/time_machine-2.19.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6567a5ec5538ed550539ac29be11b3cb36af1f9894e2a72940cba0292cc7c3c9", size = 34945, upload-time = "2025-08-19T17:21:11.538Z" }, + { url = "https://files.pythonhosted.org/packages/24/71/2f741b29d98b1c18f6777a32236497c3d3264b6077e431cea4695684c8a1/time_machine-2.19.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:82e9ffe8dfff07b0d810a2ad015a82cd78c6a237f6c7cf185fa7f747a3256f8a", size = 33014, upload-time = "2025-08-19T17:21:12.858Z" }, + { url = "https://files.pythonhosted.org/packages/e8/83/ca8dba6106562843fd99f672e5aaf95badbc10f4f13f7cfe8d8640a7019d/time_machine-2.19.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7e1c4e578cdd69b3531d8dd3fbcb92a0cd879dadb912ee37af99c3a9e3c0d285", size = 34350, upload-time = "2025-08-19T17:21:13.923Z" }, + { url = "https://files.pythonhosted.org/packages/21/7f/34fe540450e18d0a993240100e4b86e8d03d831b92af8bb6ddb2662dc6fc/time_machine-2.19.0-cp313-cp313-win32.whl", hash = "sha256:72dbd4cbc3d96dec9dd281ddfbb513982102776b63e4e039f83afb244802a9e5", size = 17047, upload-time = "2025-08-19T17:21:14.874Z" }, + { url = "https://files.pythonhosted.org/packages/bf/5d/c8be73df82c7ebe7cd133279670e89b8b110af3ce1412c551caa9d08e625/time_machine-2.19.0-cp313-cp313-win_amd64.whl", hash = "sha256:e17e3e089ac95f9a145ce07ff615e3c85674f7de36f2d92aaf588493a23ffb4b", size = 17868, upload-time = "2025-08-19T17:21:15.819Z" }, + { url = "https://files.pythonhosted.org/packages/92/13/2dfd3b8fb285308f61cd7aa9bfa96f46ddf916e3549a0f0afd094c556599/time_machine-2.19.0-cp313-cp313-win_arm64.whl", hash = "sha256:149072aff8e3690e14f4916103d898ea0d5d9c95531b6aa0995251c299533f7b", size = 16710, upload-time = "2025-08-19T17:21:16.748Z" }, + { url = "https://files.pythonhosted.org/packages/05/c1/deebb361727d2c5790f9d4d874be1b19afd41f4375581df465e6718b46a2/time_machine-2.19.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:f3589fee1ed0ab6ee424a55b0ea1ec694c4ba64cc26895bcd7d99f3d1bc6a28a", size = 20053, upload-time = "2025-08-19T17:21:17.704Z" }, + { url = "https://files.pythonhosted.org/packages/45/e8/fe3376951e6118d8ec1d1f94066a169b791424fe4a26c7dfc069b153ee08/time_machine-2.19.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7887e85275c4975fe54df03dcdd5f38bd36be973adc68a8c77e17441c3b443d6", size = 15423, upload-time = "2025-08-19T17:21:18.668Z" }, + { url = "https://files.pythonhosted.org/packages/9c/c7/f88d95cd1a87c650cf3749b4d64afdaf580297aa18ad7f4b44ec9d252dfc/time_machine-2.19.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:ce0be294c209928563fcce1c587963e60ec803436cf1e181acd5bc1e425d554b", size = 39630, upload-time = "2025-08-19T17:21:19.645Z" }, + { url = "https://files.pythonhosted.org/packages/cc/5d/65a5c48a65357e56ec6f032972e4abd1c02d4fca4b0717a3aaefd19014d4/time_machine-2.19.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a62fd1ab380012c86f4c042010418ed45eb31604f4bf4453e17c9fa60bc56a29", size = 41242, upload-time = "2025-08-19T17:21:20.979Z" }, + { url = "https://files.pythonhosted.org/packages/f6/f9/fe5209e1615fde0a8cad6c4e857157b150333ed1fe31a7632b08cfe0ebdd/time_machine-2.19.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b25ec853a4530a5800731257f93206b12cbdee85ede964ebf8011b66086a7914", size = 44278, upload-time = "2025-08-19T17:21:21.984Z" }, + { url = "https://files.pythonhosted.org/packages/4a/3a/a5e5fe9c5d614cde0a9387ff35e8dfd12c5ef6384e4c1a21b04e6e0b905d/time_machine-2.19.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a430e4d0e0556f021a9c78e9b9f68e5e8910bdace4aa34ed4d1a73e239ed9384", size = 42321, upload-time = "2025-08-19T17:21:23.755Z" }, + { url = "https://files.pythonhosted.org/packages/a1/c5/56eca774e9162bc1ce59111d2bd69140dc8908c9478c92ec7bd15d547600/time_machine-2.19.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:2415b7495ec4364c8067071e964fbadfe746dd4cdb43983f2f0bd6ebed13315c", size = 39270, upload-time = "2025-08-19T17:21:26.009Z" }, + { url = "https://files.pythonhosted.org/packages/9b/69/5dd0c420667578169a12acc8c8fd7452e8cfb181e41c9b4ac7e88fa36686/time_machine-2.19.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dbfc6b90c10f288594e1bf89a728a98cc0030791fd73541bbdc6b090aff83143", size = 40193, upload-time = "2025-08-19T17:21:27.054Z" }, + { url = "https://files.pythonhosted.org/packages/75/a7/de974d421bd55c9355583427c2a38fb0237bb5fd6614af492ba89dacb2f9/time_machine-2.19.0-cp313-cp313t-win32.whl", hash = "sha256:16f5d81f650c0a4d117ab08036dc30b5f8b262e11a4a0becc458e7f1c011b228", size = 17542, upload-time = "2025-08-19T17:21:28.674Z" }, + { url = "https://files.pythonhosted.org/packages/76/0a/aa0d05becd5d06ae8d3f16d657dc8cc9400c8d79aef80299de196467ff12/time_machine-2.19.0-cp313-cp313t-win_amd64.whl", hash = "sha256:645699616ec14e147094f601e6ab9553ff6cea37fad9c42720a6d7ed04bcd5dc", size = 18703, upload-time = "2025-08-19T17:21:29.663Z" }, + { url = "https://files.pythonhosted.org/packages/1f/c0/f785a4c7c73aa176510f7c48b84b49c26be84af0d534deb222e0327f750e/time_machine-2.19.0-cp313-cp313t-win_arm64.whl", hash = "sha256:b32daa965d13237536ea3afaa5ad61ade2b2d9314bc3a20196a0d2e1d7b57c6a", size = 17020, upload-time = "2025-08-19T17:21:30.653Z" }, + { url = "https://files.pythonhosted.org/packages/ed/97/c5fb51def06c0b2b6735332ad118ab35b4d9b85368792e5b638e99b1b686/time_machine-2.19.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:31cb43c8fd2d961f31bed0ff4e0026964d2b35e5de9e0fabbfecf756906d3612", size = 19360, upload-time = "2025-08-19T17:21:31.94Z" }, + { url = "https://files.pythonhosted.org/packages/2d/4e/2d795f7d6b7f5205ffe737a05bb1cf19d8038233b797062b2ef412b8512b/time_machine-2.19.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:bdf481a75afc6bff3e520db594501975b652f7def21cd1de6aa971d35ba644e6", size = 15033, upload-time = "2025-08-19T17:21:32.934Z" }, + { url = "https://files.pythonhosted.org/packages/dd/32/9bad501e360b4e758c58fae616ca5f8c7ad974b343f2463a15b2bf77a366/time_machine-2.19.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:00bee4bb950ac6a08d62af78e4da0cf2b4fc2abf0de2320d0431bf610db06e7c", size = 33379, upload-time = "2025-08-19T17:21:33.925Z" }, + { url = "https://files.pythonhosted.org/packages/a3/45/eda0ca4d793dfd162478d6163759b1c6ce7f6e61daa7fd7d62b31f21f87f/time_machine-2.19.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9f02199490906582302ce09edd32394fb393271674c75d7aa76c7a3245f16003", size = 35123, upload-time = "2025-08-19T17:21:34.945Z" }, + { url = "https://files.pythonhosted.org/packages/f0/5a/97e16325442ae5731fcaac794f0a1ef9980eff8a5491e58201d7eb814a34/time_machine-2.19.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e35726c7ba625f844c13b1fc0d4f81f394eefaee1d3a094a9093251521f2ef15", size = 36588, upload-time = "2025-08-19T17:21:35.975Z" }, + { url = "https://files.pythonhosted.org/packages/e8/9d/bf0b2ccc930cc4a316f26f1c78d3f313cd0fa13bb7480369b730a8f129db/time_machine-2.19.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:304315023999cd401ff02698870932b893369e1cfeb2248d09f6490507a92e97", size = 35013, upload-time = "2025-08-19T17:21:37.017Z" }, + { url = "https://files.pythonhosted.org/packages/f0/5a/39ac6a3078174f9715d88364871348b249631f12e76de1b862433b3f8862/time_machine-2.19.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:9765d4f003f263ea8bfd90d2d15447ca4b3dfa181922cf6cf808923b02ac180a", size = 33303, upload-time = "2025-08-19T17:21:38.352Z" }, + { url = "https://files.pythonhosted.org/packages/b3/ac/d8646baf9f95f2e792a6d7a7b35e92fca253c4a992afff801beafae0e5c2/time_machine-2.19.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7837ef3fd5911eb9b480909bb93d922737b6bdecea99dfcedb0a03807de9b2d3", size = 34440, upload-time = "2025-08-19T17:21:39.382Z" }, + { url = "https://files.pythonhosted.org/packages/ce/8b/8b6568c5ae966d80ead03ab537be3c6acf2af06fb501c2d466a3162c6295/time_machine-2.19.0-cp314-cp314-win32.whl", hash = "sha256:4bb5bd43b1bdfac3007b920b51d8e761f024ed465cfeec63ac4296922a4ec428", size = 17162, upload-time = "2025-08-19T17:21:40.381Z" }, + { url = "https://files.pythonhosted.org/packages/46/a5/211c1ab4566eba5308b2dc001b6349e3a032e3f6afa67ca2f27ea6b27af5/time_machine-2.19.0-cp314-cp314-win_amd64.whl", hash = "sha256:f583bbd0aa8ab4a7c45a684bf636d9e042d466e30bcbae1d13e7541e2cbe7207", size = 18040, upload-time = "2025-08-19T17:21:41.363Z" }, + { url = "https://files.pythonhosted.org/packages/b8/fc/4c2fb705f6371cb83824da45a8b967514a922fc092a0ef53979334d97a70/time_machine-2.19.0-cp314-cp314-win_arm64.whl", hash = "sha256:f379c6f8a6575a8284592179cf528ce89373f060301323edcc44f1fa1d37be12", size = 16752, upload-time = "2025-08-19T17:21:42.336Z" }, + { url = "https://files.pythonhosted.org/packages/79/ab/6437d18f31c666b5116c97572a282ac2590a82a0a9867746a6647eaf4613/time_machine-2.19.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:a3b8981f9c663b0906b05ab4d0ca211fae4b63b47c6ec26de5374fe56c836162", size = 20057, upload-time = "2025-08-19T17:21:43.35Z" }, + { url = "https://files.pythonhosted.org/packages/6c/a2/e03639ec2ba7200328bbcad8a2b2b1d5fccca9cceb9481b164a1cabdcb33/time_machine-2.19.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8e9c6363893e7f52c226afbebb23e825259222d100e67dfd24c8a6d35f1a1907", size = 15430, upload-time = "2025-08-19T17:21:44.725Z" }, + { url = "https://files.pythonhosted.org/packages/5d/ff/39e63a48e840f3e36ce24846ee51dd99c6dba635659b1750a2993771e88e/time_machine-2.19.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:206fcd6c9a6f00cac83db446ad1effc530a8cec244d2780af62db3a2d0a9871b", size = 39622, upload-time = "2025-08-19T17:21:45.821Z" }, + { url = "https://files.pythonhosted.org/packages/9a/2e/ee5ac79c4954768705801e54817c7d58e07e25a0bb227e775f501f3e2122/time_machine-2.19.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bf33016a1403c123373ffaeff25e26e69d63bf2c63b6163932efed94160db7ef", size = 41235, upload-time = "2025-08-19T17:21:46.783Z" }, + { url = "https://files.pythonhosted.org/packages/3a/3e/9af5f39525e779185c77285b8bbae15340eeeaa0afb33d458bc8b47d459b/time_machine-2.19.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9247c4bb9bbd3ff584ef4efbdec8efd9f37aa08bcfc4728bde1e489c2cb445bd", size = 44276, upload-time = "2025-08-19T17:21:47.759Z" }, + { url = "https://files.pythonhosted.org/packages/59/fe/572c7443cc27140bbeae3947279bbd4a120f9e8622253a20637f260b7813/time_machine-2.19.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:77f9bb0b86758d1f2d9352642c874946ad5815df53ef4ca22eb9d532179fe50d", size = 42330, upload-time = "2025-08-19T17:21:48.881Z" }, + { url = "https://files.pythonhosted.org/packages/cf/24/1a81c2e08ee7dae13ec8ceed27a29afa980c3d63852e42f1e023bf0faa03/time_machine-2.19.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:0b529e262df3b9c449f427385f4d98250828c879168c2e00eec844439f40b370", size = 39281, upload-time = "2025-08-19T17:21:49.907Z" }, + { url = "https://files.pythonhosted.org/packages/d2/60/6f0d6e5108978ca1a2a4ffb4d1c7e176d9199bb109fd44efe2680c60b52a/time_machine-2.19.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9199246e31cdc810e5d89cb71d09144c4d745960fdb0824da4994d152aca3303", size = 40201, upload-time = "2025-08-19T17:21:50.953Z" }, + { url = "https://files.pythonhosted.org/packages/73/b9/3ea4951e8293b0643feb98c0b9a176fa822154f1810835db3f282968ab10/time_machine-2.19.0-cp314-cp314t-win32.whl", hash = "sha256:0fe81bae55b7aefc2c2a34eb552aa82e6c61a86b3353a3c70df79b9698cb02ca", size = 17743, upload-time = "2025-08-19T17:21:51.948Z" }, + { url = "https://files.pythonhosted.org/packages/e4/8b/cd802884ca8a98e2b6cdc2397d57dd12ff8a7d1481e06fc3fad3d4e7e5ff/time_machine-2.19.0-cp314-cp314t-win_amd64.whl", hash = "sha256:7253791b8d7e7399fbeed7a8193cb01bc004242864306288797056badbdaf80b", size = 18956, upload-time = "2025-08-19T17:21:52.997Z" }, + { url = "https://files.pythonhosted.org/packages/c6/49/cabb1593896082fd55e34768029b8b0ca23c9be8b2dc127e0fc14796d33e/time_machine-2.19.0-cp314-cp314t-win_arm64.whl", hash = "sha256:536bd1ac31ab06a1522e7bf287602188f502dc19d122b1502c4f60b1e8efac79", size = 17068, upload-time = "2025-08-19T17:21:54.064Z" }, + { url = "https://files.pythonhosted.org/packages/d6/05/0608376c3167afe6cf7cdfd2b05c142ea4c42616eee9ba06d1799965806a/time_machine-2.19.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d8bb00b30ec9fe56d01e9812df1ffe39f331437cef9bfaebcc81c83f7f8f8ee2", size = 19659, upload-time = "2025-08-19T17:21:55.426Z" }, + { url = "https://files.pythonhosted.org/packages/11/c4/72eb8c7b36830cf36c51d7bc2f1ac313d68881c3a58040fb6b42c4523d20/time_machine-2.19.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d821c60efc08a97cc11e5482798e6fd5eba5c0f22a02db246b50895dbdc0de41", size = 15153, upload-time = "2025-08-19T17:21:56.505Z" }, + { url = "https://files.pythonhosted.org/packages/89/1a/0782e1f5c8ab8809ebd992709e1bb69d67600191baa023af7a5d32023a3c/time_machine-2.19.0-cp39-cp39-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:fb051aec7b3b6e96a200d911c225901e6133ff3da11e470e24111a53bbc13637", size = 32555, upload-time = "2025-08-19T17:21:57.74Z" }, + { url = "https://files.pythonhosted.org/packages/94/b0/8ef58e2f6321851d5900ca3d18044938832c2ed42a2ac7570ca6aa29768a/time_machine-2.19.0-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fe59909d95a2ef5e01ce3354fdea3908404c2932c2069f00f66dff6f27e9363e", size = 34185, upload-time = "2025-08-19T17:21:59.361Z" }, + { url = "https://files.pythonhosted.org/packages/82/74/ce0c9867f788c1fb22c417ec1aae47a24117e53d51f6ff97d7c6ca5392f6/time_machine-2.19.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:29e84b8682645b16eb6f9e8ec11c35324ad091841a11cf4fc3fc7f6119094c89", size = 35917, upload-time = "2025-08-19T17:22:00.421Z" }, + { url = "https://files.pythonhosted.org/packages/d2/70/6f97a8f552dbaa66feb10170b5726dab74bc531673d1ed9d6f271547e54c/time_machine-2.19.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4a11f1c0e0d06023dc01614c964e256138913551d3ae6dca5148f79081156336", size = 34584, upload-time = "2025-08-19T17:22:01.447Z" }, + { url = "https://files.pythonhosted.org/packages/48/c8/cf139088ce537c15d7f03cf56ec317d3a5cfb520e30aa711ea0248d0ae8a/time_machine-2.19.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:57a235a6307c54df50e69f1906e2f199e47da91bde4b886ee05aff57fe4b6bf6", size = 32608, upload-time = "2025-08-19T17:22:02.548Z" }, + { url = "https://files.pythonhosted.org/packages/b1/17/0ec41ef7a30c6753fb226a28b74162b264b35724905ced4098f2f5076ded/time_machine-2.19.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:426aba552f7af9604adad9ef570c859af7c1081d878db78089fac159cd911b0a", size = 33686, upload-time = "2025-08-19T17:22:03.606Z" }, + { url = "https://files.pythonhosted.org/packages/b0/19/586f15159083ec84f178d494c60758c46603b00c9641b04deb63f1950128/time_machine-2.19.0-cp39-cp39-win32.whl", hash = "sha256:67772c7197a3a712d1b970ed545c6e98db73524bd90e245fd3c8fa7ad7630768", size = 17133, upload-time = "2025-08-19T17:22:04.989Z" }, + { url = "https://files.pythonhosted.org/packages/6a/c2/bfe4b906a9fe0bf2d011534314212ed752d6b8f392c9c82f6ac63dccc5ab/time_machine-2.19.0-cp39-cp39-win_amd64.whl", hash = "sha256:011d7859089263204dc5fdf83dce7388f986fe833c9381d6106b4edfda2ebd3e", size = 17972, upload-time = "2025-08-19T17:22:06.026Z" }, + { url = "https://files.pythonhosted.org/packages/5d/73/182343eba05aa5787732aaa68f3b3feb5e40ddf86b928ae941be45646393/time_machine-2.19.0-cp39-cp39-win_arm64.whl", hash = "sha256:e1af66550fa4685434f00002808a525f176f1f92746646c0019bb86fbff48b27", size = 16820, upload-time = "2025-08-19T17:22:07.227Z" }, +] + +[[package]] +name = "time-machine" +version = "3.2.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14' and extra != 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and python_full_version < '3.14' and extra != 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and extra == 'group-10-cloudflare-pydantic-v1' and extra != 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and extra != 'group-10-cloudflare-pydantic-v1' and extra != 'group-10-cloudflare-pydantic-v2'", +] +sdist = { url = "https://files.pythonhosted.org/packages/02/fc/37b02f6094dbb1f851145330460532176ed2f1dc70511a35828166c41e52/time_machine-3.2.0.tar.gz", hash = "sha256:a4ddd1cea17b8950e462d1805a42b20c81eb9aafc8f66b392dd5ce997e037d79", size = 14804, upload-time = "2025-12-17T23:33:02.599Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9c/31/6bf41cb4a326230518d9b76c910dfc11d4fc23444d1cbfdf2d7652bd99f4/time_machine-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:68142c070e78b62215d8029ec7394905083a4f9aacb0a2a11514ce70b5951b13", size = 19447, upload-time = "2025-12-17T23:31:30.181Z" }, + { url = "https://files.pythonhosted.org/packages/fa/14/d71ce771712e1cbfa15d8c24452225109262b16cb6caaf967e9f60662b67/time_machine-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:161bbd0648802ffdfcb4bb297ecb26b3009684a47d3a4dedb90bc549df4fa2ad", size = 15432, upload-time = "2025-12-17T23:31:31.381Z" }, + { url = "https://files.pythonhosted.org/packages/8b/d6/dcb43a11f8029561996fad58ff9d3dc5e6d7f32b74f0745a2965d7e4b4f3/time_machine-3.2.0-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:1359ba8c258be695ba69253bc84db882fd616fe69b426cc6056536da2c7bf68e", size = 32956, upload-time = "2025-12-17T23:31:32.469Z" }, + { url = "https://files.pythonhosted.org/packages/77/da/d802cd3c335c414f9b11b479f7459aa72df5de6485c799966cfdf8856d53/time_machine-3.2.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c85b169998ca2c24a78fb214586ec11c4cad56d9c38f55ad8326235cb481c884", size = 34556, upload-time = "2025-12-17T23:31:33.946Z" }, + { url = "https://files.pythonhosted.org/packages/85/ee/51ad553514ab0b940c7c82c6e1519dd10fd06ac07b32039a1d153ef09c88/time_machine-3.2.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:65b9367cb8a10505bc8f67da0da514ba20fa816fc47e11f434f7c60350322b4c", size = 36101, upload-time = "2025-12-17T23:31:35.462Z" }, + { url = "https://files.pythonhosted.org/packages/11/39/938b111b5bb85a2b07502d0f9d8a704fc75bd760d62e76bce23c89ed16c9/time_machine-3.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9faca6a0f1973d7df3233c951fc2a11ff0c54df74087d8aaf41ae3deb19d0893", size = 34905, upload-time = "2025-12-17T23:31:36.543Z" }, + { url = "https://files.pythonhosted.org/packages/dd/50/0951f73b23e76455de0b4a3a58ac5a24bd8d10489624b1c5e03f10c6fc0b/time_machine-3.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:213b1ada7f385d467e598999b642eda4a8e89ae10ad5dc4f5d8f672cbf604261", size = 33012, upload-time = "2025-12-17T23:31:37.967Z" }, + { url = "https://files.pythonhosted.org/packages/4f/95/5304912d3dcecc4e14ed222dbe0396352efdf8497534abc3c9edd67a7528/time_machine-3.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:160b6afd94c39855af04d39c58e4cf602406abd6d79427ab80e830ea71789cfb", size = 34104, upload-time = "2025-12-17T23:31:39.449Z" }, + { url = "https://files.pythonhosted.org/packages/d4/1c/af56518652ec7adac4ced193b7a42c4ff354fef28a412b3b5ffa5763aead/time_machine-3.2.0-cp310-cp310-win32.whl", hash = "sha256:c15d9ac257c78c124d112e4fc91fa9f3dcb004bdda913c19f0e7368d713cf080", size = 17468, upload-time = "2025-12-17T23:31:40.432Z" }, + { url = "https://files.pythonhosted.org/packages/48/15/0213f00ca3cf6fe1c9fdbd7fd467e801052fc85534f30c0e4684bd474190/time_machine-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:3bf0f428487f93b8fe9d27aa01eccc817885da3290b467341b4a4a795e1d1891", size = 18313, upload-time = "2025-12-17T23:31:41.617Z" }, + { url = "https://files.pythonhosted.org/packages/77/e4/811f96aa7a634b2b264d9a476f3400e710744dda503b4ad87a5c76db32c9/time_machine-3.2.0-cp310-cp310-win_arm64.whl", hash = "sha256:347f6be2129fcd35b1c94b9387fcb2cbe7949b1e649228c5f22949a811b78976", size = 17037, upload-time = "2025-12-17T23:31:42.924Z" }, + { url = "https://files.pythonhosted.org/packages/f5/e1/03aae5fbaa53859f665094af696338fc7cae733d926a024af69982712350/time_machine-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c188a9dda9fcf975022f1b325b466651b96a4dfc223c523ed7ed8d979f9bf3e8", size = 19143, upload-time = "2025-12-17T23:31:44.258Z" }, + { url = "https://files.pythonhosted.org/packages/75/8f/98cb17bebb52b22ff4ec26984dd44280f9c71353c3bae0640a470e6683e5/time_machine-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:17245f1cc2dd13f9d63a174be59bb2684a9e5e0a112ab707e37be92068cd655f", size = 15273, upload-time = "2025-12-17T23:31:45.246Z" }, + { url = "https://files.pythonhosted.org/packages/dd/2f/ca11e4a7897234bb9331fcc5f4ed4714481ba4012370cc79a0ae8c42ea0a/time_machine-3.2.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d9bd1de1996e76efd36ae15970206c5089fb3728356794455bd5cd8d392b5537", size = 31049, upload-time = "2025-12-17T23:31:46.613Z" }, + { url = "https://files.pythonhosted.org/packages/cf/ad/d17d83a59943094e6b6c6a3743caaf6811b12203c3e07a30cc7bcc2ab7ee/time_machine-3.2.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:98493cd50e8b7f941eab69b9e18e697ad69db1a0ec1959f78f3d7b0387107e5c", size = 32632, upload-time = "2025-12-17T23:31:47.72Z" }, + { url = "https://files.pythonhosted.org/packages/71/50/d60576d047a0dfb5638cdfb335e9c3deb6e8528544fa0b3966a8480f72b7/time_machine-3.2.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:31f2a33d595d9f91eb9bc7f157f0dc5721f5789f4c4a9e8b852cdedb2a7d9b16", size = 34289, upload-time = "2025-12-17T23:31:48.913Z" }, + { url = "https://files.pythonhosted.org/packages/fa/fe/4afa602dbdebddde6d0ea4a7fe849e49b9bb85dc3fb415725a87ccb4b471/time_machine-3.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9f78ac4213c10fbc44283edd1a29cfb7d3382484f4361783ddc057292aaa1889", size = 33175, upload-time = "2025-12-17T23:31:50.611Z" }, + { url = "https://files.pythonhosted.org/packages/0d/87/c152e23977c1d7d7c94eb3ed3ea45cc55971796205125c6fdff40db2c60f/time_machine-3.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c1326b09e947b360926d529a96d1d9e126ce120359b63b506ecdc6ee20755c23", size = 31170, upload-time = "2025-12-17T23:31:51.645Z" }, + { url = "https://files.pythonhosted.org/packages/80/af/54acf51d0f3ade3b51eab73df6192937c9a938753ef5456dff65eb8630be/time_machine-3.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9f2949f03d15264cc15c38918a2cda8966001f0f4ebe190cbfd9c56d91aed8ac", size = 32292, upload-time = "2025-12-17T23:31:52.803Z" }, + { url = "https://files.pythonhosted.org/packages/cc/bc/3745963f36e75661a807196428639327a366f4332f35f1f775c074d4062f/time_machine-3.2.0-cp311-cp311-win32.whl", hash = "sha256:6dfe48e0499e6e16751476b9799e67be7514e6ef04cdf39571ef95a279645831", size = 17349, upload-time = "2025-12-17T23:31:54.19Z" }, + { url = "https://files.pythonhosted.org/packages/82/a2/057469232a99d1f5a0160ae7c5bae7b095c9168b333dd598fcbcfbc1c87b/time_machine-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:809bdf267a29189c304154873620fe0bcc0c9513295fa46b19e21658231c4915", size = 18191, upload-time = "2025-12-17T23:31:55.472Z" }, + { url = "https://files.pythonhosted.org/packages/79/d8/bf9c8de57262ee7130d92a6ed49ed6a6e40a36317e46979428d373630c12/time_machine-3.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:a3f4c17fa90f54902a3f8692c75caf67be87edc3429eeb71cb4595da58198f8e", size = 16905, upload-time = "2025-12-17T23:31:56.658Z" }, + { url = "https://files.pythonhosted.org/packages/71/8b/080c8eedcd67921a52ba5bd0e075362062509ab63c86fc1a0442fad241a6/time_machine-3.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:cc4bee5b0214d7dc4ebc91f4a4c600f1a598e9b5606ac751f42cb6f6740b1dbb", size = 19255, upload-time = "2025-12-17T23:31:58.057Z" }, + { url = "https://files.pythonhosted.org/packages/66/17/0e5291e9eb705bf8a5a1305f826e979af307bbeb79def4ddbf4b3f9a81e0/time_machine-3.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3ca036304b4460ae2fdc1b52dd8b1fa7cf1464daa427fc49567413c09aa839c1", size = 15360, upload-time = "2025-12-17T23:31:59.048Z" }, + { url = "https://files.pythonhosted.org/packages/8b/e8/9ab87b71d2e2b62463b9b058b7ae7ac09fb57f8fcd88729dec169d304340/time_machine-3.2.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5442735b41d7a2abc2f04579b4ca6047ed4698a8338a4fec92c7c9423e7938cb", size = 33029, upload-time = "2025-12-17T23:32:00.413Z" }, + { url = "https://files.pythonhosted.org/packages/4b/26/b5ca19da6f25ea905b3e10a0ea95d697c1aeba0404803a43c68f1af253e6/time_machine-3.2.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:97da3e971e505cb637079fb07ab0bcd36e33279f8ecac888ff131f45ef1e4d8d", size = 34579, upload-time = "2025-12-17T23:32:01.431Z" }, + { url = "https://files.pythonhosted.org/packages/79/ca/6ac7ad5f10ea18cc1d9de49716ba38c32132c7b64532430d92ef240c116b/time_machine-3.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3cdda6dee4966e38aeb487309bb414c6cb23a81fc500291c77a8fcd3098832e7", size = 35961, upload-time = "2025-12-17T23:32:02.521Z" }, + { url = "https://files.pythonhosted.org/packages/33/67/390dd958bed395ab32d79a9fe61fe111825c0dd4ded54dbba7e867f171e6/time_machine-3.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:33d9efd302a6998bcc8baa4d84f259f8a4081105bd3d7f7af7f1d0abd3b1c8aa", size = 34668, upload-time = "2025-12-17T23:32:03.585Z" }, + { url = "https://files.pythonhosted.org/packages/da/57/c88fff034a4e9538b3ae7c68c9cfb283670b14d17522c5a8bc17d29f9a4b/time_machine-3.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3a0b0a33971f14145853c9bd95a6ab0353cf7e0019fa2a7aa1ae9fddfe8eab50", size = 32891, upload-time = "2025-12-17T23:32:04.656Z" }, + { url = "https://files.pythonhosted.org/packages/2d/70/ebbb76022dba0fec8f9156540fc647e4beae1680c787c01b1b6200e56d70/time_machine-3.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2d0be9e5f22c38082d247a2cdcd8a936504e9db60b7b3606855fb39f299e9548", size = 34080, upload-time = "2025-12-17T23:32:06.146Z" }, + { url = "https://files.pythonhosted.org/packages/db/9a/2ca9e7af3df540dc1c79e3de588adeddb7dcc2107829248e6969c4f14167/time_machine-3.2.0-cp312-cp312-win32.whl", hash = "sha256:3f74623648b936fdce5f911caf386c0a0b579456410975de8c0dfeaaffece1d8", size = 17371, upload-time = "2025-12-17T23:32:07.164Z" }, + { url = "https://files.pythonhosted.org/packages/d8/ce/21d23efc9c2151939af1b7ee4e60d86d661b74ef32b8eaa148f6fe8c899c/time_machine-3.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:34e26a41d994b5e4b205136a90e9578470386749cc9a2ecf51ca18f83ce25e23", size = 18132, upload-time = "2025-12-17T23:32:08.447Z" }, + { url = "https://files.pythonhosted.org/packages/2f/34/c2b70be483accf6db9e5d6c3139bce3c38fe51f898ccf64e8d3fe14fbf4d/time_machine-3.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:0615d3d82c418d6293f271c348945c5091a71f37e37173653d5c26d0e74b13a8", size = 16930, upload-time = "2025-12-17T23:32:09.477Z" }, + { url = "https://files.pythonhosted.org/packages/ee/cd/43ad5efc88298af3c59b66769cea7f055567a85071579ed40536188530c1/time_machine-3.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c421a8eb85a4418a7675a41bf8660224318c46cc62e4751c8f1ceca752059090", size = 19318, upload-time = "2025-12-17T23:32:10.518Z" }, + { url = "https://files.pythonhosted.org/packages/b0/f6/084010ef7f4a3f38b5a4900923d7c85b29e797655c4f6ee4ce54d903cca8/time_machine-3.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8f4e758f7727d0058c4950c66b58200c187072122d6f7a98b610530a4233ea7b", size = 15390, upload-time = "2025-12-17T23:32:11.625Z" }, + { url = "https://files.pythonhosted.org/packages/25/aa/1cabb74134f492270dc6860cb7865859bf40ecf828be65972827646e91ad/time_machine-3.2.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:154bd3f75c81f70218b2585cc12b60762fb2665c507eec5ec5037d8756d9b4e0", size = 33115, upload-time = "2025-12-17T23:32:13.219Z" }, + { url = "https://files.pythonhosted.org/packages/5e/03/78c5d7dfa366924eb4dbfcc3fc917c39a4280ca234b12819cc1f16c03d88/time_machine-3.2.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d50cfe5ebea422c896ad8d278af9648412b7533b8ea6adeeee698a3fd9b1d3b7", size = 34705, upload-time = "2025-12-17T23:32:14.29Z" }, + { url = "https://files.pythonhosted.org/packages/86/93/d5e877c24541f674c6869ff6e9c56833369796010190252e92c9d7ae5f0f/time_machine-3.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:636576501724bd6a9124e69d86e5aef263479e89ef739c5db361469f0463a0a1", size = 36104, upload-time = "2025-12-17T23:32:15.354Z" }, + { url = "https://files.pythonhosted.org/packages/22/1c/d4bae72f388f67efc9609f89b012e434bb19d9549c7a7b47d6c7d9e5c55d/time_machine-3.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:40e6f40c57197fcf7ec32d2c563f4df0a82c42cdcc3cab27f688e98f6060df10", size = 34765, upload-time = "2025-12-17T23:32:16.434Z" }, + { url = "https://files.pythonhosted.org/packages/1d/c3/ac378cf301d527d8dfad2f0db6bad0dfb1ab73212eaa56d6b96ee5d9d20b/time_machine-3.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a1bcf0b846bbfc19a79bc19e3fa04d8c7b1e8101c1b70340ffdb689cd801ea53", size = 33010, upload-time = "2025-12-17T23:32:17.532Z" }, + { url = "https://files.pythonhosted.org/packages/06/35/7ce897319accda7a6970b288a9a8c52d25227342a7508505a2b3d235b649/time_machine-3.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ae55a56c179f4fe7a62575ad5148b6ed82f6c7e5cf2f9a9ec65f2f5b067db5f5", size = 34185, upload-time = "2025-12-17T23:32:18.566Z" }, + { url = "https://files.pythonhosted.org/packages/bf/28/f922022269749cb02eee2b62919671153c4088994fa955a6b0e50327ff81/time_machine-3.2.0-cp313-cp313-win32.whl", hash = "sha256:a66fe55a107e46916007a391d4030479df8864ec6ad6f6a6528221befc5c886e", size = 17397, upload-time = "2025-12-17T23:32:19.605Z" }, + { url = "https://files.pythonhosted.org/packages/ee/dc/fd87cde397f4a7bea493152f0aca8fd569ec709cad9e0f2ca7011eb8c7f7/time_machine-3.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:30c9ce57165df913e4f74e285a8ab829ff9b7aa3e5ec0973f88f642b9a7b3d15", size = 18139, upload-time = "2025-12-17T23:32:20.991Z" }, + { url = "https://files.pythonhosted.org/packages/75/81/b8ce58233addc5d7d54d2fabc49dcbc02d79e3f079d150aa1bec3d5275ef/time_machine-3.2.0-cp313-cp313-win_arm64.whl", hash = "sha256:89cad7e179e9bdcc84dcf09efe52af232c4cc7a01b3de868356bbd59d95bd9b8", size = 16964, upload-time = "2025-12-17T23:32:22.075Z" }, + { url = "https://files.pythonhosted.org/packages/67/e7/487f0ba5fe6c58186a5e1af2a118dfa2c160fedb37ef53a7e972d410408e/time_machine-3.2.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:59d71545e62525a4b85b6de9ab5c02ee3c61110fd7f636139914a2335dcbfc9c", size = 20000, upload-time = "2025-12-17T23:32:23.058Z" }, + { url = "https://files.pythonhosted.org/packages/e1/17/eb2c0054c8d44dd42df84ccd434539249a9c7d0b8eb53f799be2102500ab/time_machine-3.2.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:999672c621c35362bc28e03ca0c7df21500195540773c25993421fd8d6cc5003", size = 15657, upload-time = "2025-12-17T23:32:24.125Z" }, + { url = "https://files.pythonhosted.org/packages/43/21/93443b5d1dd850f8bb9442e90d817a9033dcce6bfbdd3aabbb9786251c80/time_machine-3.2.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5faf7397f0580c7b9d67288522c8d7863e85f0cffadc0f1fccdb2c3dfce5783e", size = 39216, upload-time = "2025-12-17T23:32:25.542Z" }, + { url = "https://files.pythonhosted.org/packages/9f/9e/18544cf8acc72bb1dc03762231c82ecc259733f4bb6770a7bbe5cd138603/time_machine-3.2.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d3dd886ec49f1fa5a00e844f5947e5c0f98ce574750c24b7424c6f77fc1c3e87", size = 40764, upload-time = "2025-12-17T23:32:26.643Z" }, + { url = "https://files.pythonhosted.org/packages/27/f7/9fe9ce2795636a3a7467307af6bdf38bb613ddb701a8a5cd50ec713beb5e/time_machine-3.2.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:da0ecd96bc7bbe450acaaabe569d84e81688f1be8ad58d1470e42371d145fb53", size = 43526, upload-time = "2025-12-17T23:32:27.693Z" }, + { url = "https://files.pythonhosted.org/packages/03/c1/a93e975ba9dec22e87ec92d18c28e67d36bd536f9119ffa439b2892b0c9c/time_machine-3.2.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:158220e946c1c4fb8265773a0282c88c35a7e3bb5d78e3561214e3b3231166f3", size = 41727, upload-time = "2025-12-17T23:32:28.985Z" }, + { url = "https://files.pythonhosted.org/packages/5f/fb/e3633e5a6bbed1c76bb2e9810dabc2f8467532ffcd29b9aed404b473061a/time_machine-3.2.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:8c1aee29bc54356f248d5d7dfdd131e12ca825e850a08c0ebdb022266d073013", size = 38952, upload-time = "2025-12-17T23:32:30.031Z" }, + { url = "https://files.pythonhosted.org/packages/82/3d/02e9fb2526b3d6b1b45bc8e4d912d95d1cd699d1a3f6df985817d37a0600/time_machine-3.2.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c8ed2224f09d25b1c2fc98683613aca12f90f682a427eabb68fc824d27014e4a", size = 39829, upload-time = "2025-12-17T23:32:31.075Z" }, + { url = "https://files.pythonhosted.org/packages/85/c8/c14265212436da8e0814c45463987b3f57de3eca4de023cc2eabb0c62ef3/time_machine-3.2.0-cp313-cp313t-win32.whl", hash = "sha256:3498719f8dab51da76d29a20c1b5e52ee7db083dddf3056af7fa69c1b94e1fe6", size = 17852, upload-time = "2025-12-17T23:32:32.079Z" }, + { url = "https://files.pythonhosted.org/packages/1d/bc/8acb13cf6149f47508097b158a9a8bec9ec4530a70cb406124e8023581f5/time_machine-3.2.0-cp313-cp313t-win_amd64.whl", hash = "sha256:e0d90bee170b219e1d15e6a58164aa808f5170090e4f090bd0670303e34181b1", size = 18918, upload-time = "2025-12-17T23:32:33.106Z" }, + { url = "https://files.pythonhosted.org/packages/24/87/c443ee508c2708fd2514ccce9052f5e48888783ce690506919629ebc8eb0/time_machine-3.2.0-cp313-cp313t-win_arm64.whl", hash = "sha256:051de220fdb6e20d648111bbad423d9506fdbb2e44d4429cef3dc0382abf1fc2", size = 17261, upload-time = "2025-12-17T23:32:34.446Z" }, + { url = "https://files.pythonhosted.org/packages/61/70/b4b980d126ed155c78d1879c50d60c8dcbd47bd11cb14ee7be50e0dfc07f/time_machine-3.2.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:1398980c017fe5744d66f419e0115ee48a53b00b146d738e1416c225eb610b82", size = 19303, upload-time = "2025-12-17T23:32:35.796Z" }, + { url = "https://files.pythonhosted.org/packages/73/73/eaa33603c69a68fe2b6f54f9dd75481693d62f1d29676531002be06e2d1c/time_machine-3.2.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:4f8f4e35f4191ef70c2ab8ff490761ee9051b891afce2bf86dde3918eb7b537b", size = 15431, upload-time = "2025-12-17T23:32:37.244Z" }, + { url = "https://files.pythonhosted.org/packages/76/10/b81e138e86cc7bab40cdb59d294b341e172201f4a6c84bb0ec080407977a/time_machine-3.2.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:6db498686ecf6163c5aa8cf0bcd57bbe0f4081184f247edf3ee49a2612b584f9", size = 33206, upload-time = "2025-12-17T23:32:38.713Z" }, + { url = "https://files.pythonhosted.org/packages/d3/72/4deab446b579e8bd5dca91de98595c5d6bd6a17ce162abf5c5f2ce40d3d8/time_machine-3.2.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:027c1807efb74d0cd58ad16524dec94212fbe900115d70b0123399883657ac0f", size = 34792, upload-time = "2025-12-17T23:32:40.223Z" }, + { url = "https://files.pythonhosted.org/packages/2c/39/439c6b587ddee76d533fe972289d0646e0a5520e14dc83d0a30aeb5565f7/time_machine-3.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92432610c05676edd5e6946a073c6f0c926923123ce7caee1018dc10782c713d", size = 36187, upload-time = "2025-12-17T23:32:41.705Z" }, + { url = "https://files.pythonhosted.org/packages/4b/db/2da4368db15180989bab83746a857bde05ad16e78f326801c142bb747a06/time_machine-3.2.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c25586b62480eb77ef3d953fba273209478e1ef49654592cd6a52a68dfe56a67", size = 34855, upload-time = "2025-12-17T23:32:42.817Z" }, + { url = "https://files.pythonhosted.org/packages/88/84/120a431fee50bc4c241425bee4d3a4910df4923b7ab5f7dff1bf0c772f08/time_machine-3.2.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:6bf3a2fa738d15e0b95d14469a0b8ea42635467408d8b490e263d5d45c9a177f", size = 33222, upload-time = "2025-12-17T23:32:43.94Z" }, + { url = "https://files.pythonhosted.org/packages/f9/ea/89cfda82bb8c57ff91bb9a26751aa234d6d90e9b4d5ab0ad9dce0f9f0329/time_machine-3.2.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ce76b82276d7ad2a66cdc85dad4df19d1422b69183170a34e8fbc4c3f35502f7", size = 34270, upload-time = "2025-12-17T23:32:45.037Z" }, + { url = "https://files.pythonhosted.org/packages/8a/aa/235357da4f69a51a8d35fcbfcfa77cdc7dc24f62ae54025006570bda7e2d/time_machine-3.2.0-cp314-cp314-win32.whl", hash = "sha256:14d6778273c543441863dff712cd1d7803dee946b18de35921eb8df10714539d", size = 17544, upload-time = "2025-12-17T23:32:46.099Z" }, + { url = "https://files.pythonhosted.org/packages/7b/51/6c8405a7276be79693b792cff22ce41067ec05db26a7d02f2d5b06324434/time_machine-3.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:cbf821da96dbc80d349fa9e7c36e670b41d68a878d28c8850057992fed430eef", size = 18423, upload-time = "2025-12-17T23:32:47.468Z" }, + { url = "https://files.pythonhosted.org/packages/d9/03/a3cf419e20c35fc203c6e4fed48b5b667c1a2b4da456d9971e605f73ecef/time_machine-3.2.0-cp314-cp314-win_arm64.whl", hash = "sha256:71c75d71f8e68abc8b669bca26ed2ddd558430a6c171e32b8620288565f18c0e", size = 17050, upload-time = "2025-12-17T23:32:48.91Z" }, + { url = "https://files.pythonhosted.org/packages/86/a1/142de946dc4393f910bf4564b5c3ba819906e1f49b06c9cb557519c849e4/time_machine-3.2.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:4e374779021446fc2b5c29d80457ec9a3b1a5df043dc2aae07d7c1415d52323c", size = 19991, upload-time = "2025-12-17T23:32:49.933Z" }, + { url = "https://files.pythonhosted.org/packages/ee/62/7f17def6289901f94726921811a16b9adce46e666362c75d45730c60274f/time_machine-3.2.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:122310a6af9c36e9a636da32830e591e7923e8a07bdd0a43276c3a36c6821c90", size = 15707, upload-time = "2025-12-17T23:32:50.969Z" }, + { url = "https://files.pythonhosted.org/packages/5d/d3/3502fb9bd3acb159c18844b26c43220201a0d4a622c0c853785d07699a92/time_machine-3.2.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:ba3eeb0f018cc362dd8128befa3426696a2e16dd223c3fb695fde184892d4d8c", size = 39207, upload-time = "2025-12-17T23:32:52.033Z" }, + { url = "https://files.pythonhosted.org/packages/5a/be/8b27f4aa296fda14a5a2ad7f588ddd450603c33415ab3f8e85b2f1a44678/time_machine-3.2.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:77d38ba664b381a7793f8786efc13b5004f0d5f672dae814430445b8202a67a6", size = 40764, upload-time = "2025-12-17T23:32:53.167Z" }, + { url = "https://files.pythonhosted.org/packages/42/cd/fe4c4e5c8ab6d48fab3624c32be9116fb120173a35fe67e482e5cf68b3d2/time_machine-3.2.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f09abeb8f03f044d72712207e0489a62098ad3ad16dac38927fcf80baca4d6a7", size = 43508, upload-time = "2025-12-17T23:32:54.597Z" }, + { url = "https://files.pythonhosted.org/packages/b4/28/5a3ba2fce85b97655a425d6bb20a441550acd2b304c96b2c19d3839f721a/time_machine-3.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:6b28367ce4f73987a55e230e1d30a57a3af85da8eb1a140074eb6e8c7e6ef19f", size = 41712, upload-time = "2025-12-17T23:32:55.781Z" }, + { url = "https://files.pythonhosted.org/packages/81/58/e38084be7fdabb4835db68a3a47e58c34182d79fc35df1ecbe0db2c5359f/time_machine-3.2.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:903c7751c904581da9f7861c3015bed7cdc40047321291d3694a3cdc783bbca3", size = 38939, upload-time = "2025-12-17T23:32:56.867Z" }, + { url = "https://files.pythonhosted.org/packages/40/d0/ad3feb0a392ef4e0c08bc32024950373ddc0669002cbdcbb9f3bf0c2d114/time_machine-3.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:528217cad85ede5f85c8bc78b0341868d3c3cfefc6ecb5b622e1cacb6c73247b", size = 39837, upload-time = "2025-12-17T23:32:58.283Z" }, + { url = "https://files.pythonhosted.org/packages/5b/9e/5f4b2ea63b267bd78f3245e76f5528836611b5f2d30b5e7300a722fe4428/time_machine-3.2.0-cp314-cp314t-win32.whl", hash = "sha256:75724762ffd517e7e80aaec1fad1ff5a7414bd84e2b3ee7a0bacfeb67c14926e", size = 18091, upload-time = "2025-12-17T23:32:59.403Z" }, + { url = "https://files.pythonhosted.org/packages/39/6f/456b1f4d2700ae02b19eba830f870596a4b89b74bac3b6c80666f1b108c5/time_machine-3.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2526abbd053c5bca898d1b3e7898eec34626b12206718d8c7ce88fd12c1c9c5c", size = 19208, upload-time = "2025-12-17T23:33:00.488Z" }, + { url = "https://files.pythonhosted.org/packages/2f/22/8063101427ecd3d2652aada4d21d0876b07a3dc789125bca2ee858fec3ed/time_machine-3.2.0-cp314-cp314t-win_arm64.whl", hash = "sha256:7f2fb6784b414edbe2c0b558bfaab0c251955ba27edd62946cce4a01675a992c", size = 17359, upload-time = "2025-12-17T23:33:01.54Z" }, +] + +[[package]] +name = "tomli" +version = "2.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/11/db3d5885d8528263d8adc260bb2d28ebf1270b96e98f0e0268d32b8d9900/tomli-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30", size = 154704, upload-time = "2026-03-25T20:21:10.473Z" }, + { url = "https://files.pythonhosted.org/packages/6d/f7/675db52c7e46064a9aa928885a9b20f4124ecb9bc2e1ce74c9106648d202/tomli-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a", size = 149454, upload-time = "2026-03-25T20:21:12.036Z" }, + { url = "https://files.pythonhosted.org/packages/61/71/81c50943cf953efa35bce7646caab3cf457a7d8c030b27cfb40d7235f9ee/tomli-2.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076", size = 237561, upload-time = "2026-03-25T20:21:13.098Z" }, + { url = "https://files.pythonhosted.org/packages/48/c1/f41d9cb618acccca7df82aaf682f9b49013c9397212cb9f53219e3abac37/tomli-2.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9", size = 243824, upload-time = "2026-03-25T20:21:14.569Z" }, + { url = "https://files.pythonhosted.org/packages/22/e4/5a816ecdd1f8ca51fb756ef684b90f2780afc52fc67f987e3c61d800a46d/tomli-2.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c", size = 242227, upload-time = "2026-03-25T20:21:15.712Z" }, + { url = "https://files.pythonhosted.org/packages/6b/49/2b2a0ef529aa6eec245d25f0c703e020a73955ad7edf73e7f54ddc608aa5/tomli-2.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc", size = 247859, upload-time = "2026-03-25T20:21:17.001Z" }, + { url = "https://files.pythonhosted.org/packages/83/bd/6c1a630eaca337e1e78c5903104f831bda934c426f9231429396ce3c3467/tomli-2.4.1-cp311-cp311-win32.whl", hash = "sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049", size = 97204, upload-time = "2026-03-25T20:21:18.079Z" }, + { url = "https://files.pythonhosted.org/packages/42/59/71461df1a885647e10b6bb7802d0b8e66480c61f3f43079e0dcd315b3954/tomli-2.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e", size = 108084, upload-time = "2026-03-25T20:21:18.978Z" }, + { url = "https://files.pythonhosted.org/packages/b8/83/dceca96142499c069475b790e7913b1044c1a4337e700751f48ed723f883/tomli-2.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece", size = 95285, upload-time = "2026-03-25T20:21:20.309Z" }, + { url = "https://files.pythonhosted.org/packages/c1/ba/42f134a3fe2b370f555f44b1d72feebb94debcab01676bf918d0cb70e9aa/tomli-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a", size = 155924, upload-time = "2026-03-25T20:21:21.626Z" }, + { url = "https://files.pythonhosted.org/packages/dc/c7/62d7a17c26487ade21c5422b646110f2162f1fcc95980ef7f63e73c68f14/tomli-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085", size = 150018, upload-time = "2026-03-25T20:21:23.002Z" }, + { url = "https://files.pythonhosted.org/packages/5c/05/79d13d7c15f13bdef410bdd49a6485b1c37d28968314eabee452c22a7fda/tomli-2.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9", size = 244948, upload-time = "2026-03-25T20:21:24.04Z" }, + { url = "https://files.pythonhosted.org/packages/10/90/d62ce007a1c80d0b2c93e02cab211224756240884751b94ca72df8a875ca/tomli-2.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5", size = 253341, upload-time = "2026-03-25T20:21:25.177Z" }, + { url = "https://files.pythonhosted.org/packages/1a/7e/caf6496d60152ad4ed09282c1885cca4eea150bfd007da84aea07bcc0a3e/tomli-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585", size = 248159, upload-time = "2026-03-25T20:21:26.364Z" }, + { url = "https://files.pythonhosted.org/packages/99/e7/c6f69c3120de34bbd882c6fba7975f3d7a746e9218e56ab46a1bc4b42552/tomli-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1", size = 253290, upload-time = "2026-03-25T20:21:27.46Z" }, + { url = "https://files.pythonhosted.org/packages/d6/2f/4a3c322f22c5c66c4b836ec58211641a4067364f5dcdd7b974b4c5da300c/tomli-2.4.1-cp312-cp312-win32.whl", hash = "sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917", size = 98141, upload-time = "2026-03-25T20:21:28.492Z" }, + { url = "https://files.pythonhosted.org/packages/24/22/4daacd05391b92c55759d55eaee21e1dfaea86ce5c571f10083360adf534/tomli-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9", size = 108847, upload-time = "2026-03-25T20:21:29.386Z" }, + { url = "https://files.pythonhosted.org/packages/68/fd/70e768887666ddd9e9f5d85129e84910f2db2796f9096aa02b721a53098d/tomli-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257", size = 95088, upload-time = "2026-03-25T20:21:30.677Z" }, + { url = "https://files.pythonhosted.org/packages/07/06/b823a7e818c756d9a7123ba2cda7d07bc2dd32835648d1a7b7b7a05d848d/tomli-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54", size = 155866, upload-time = "2026-03-25T20:21:31.65Z" }, + { url = "https://files.pythonhosted.org/packages/14/6f/12645cf7f08e1a20c7eb8c297c6f11d31c1b50f316a7e7e1e1de6e2e7b7e/tomli-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a", size = 149887, upload-time = "2026-03-25T20:21:33.028Z" }, + { url = "https://files.pythonhosted.org/packages/5c/e0/90637574e5e7212c09099c67ad349b04ec4d6020324539297b634a0192b0/tomli-2.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897", size = 243704, upload-time = "2026-03-25T20:21:34.51Z" }, + { url = "https://files.pythonhosted.org/packages/10/8f/d3ddb16c5a4befdf31a23307f72828686ab2096f068eaf56631e136c1fdd/tomli-2.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f", size = 251628, upload-time = "2026-03-25T20:21:36.012Z" }, + { url = "https://files.pythonhosted.org/packages/e3/f1/dbeeb9116715abee2485bf0a12d07a8f31af94d71608c171c45f64c0469d/tomli-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d", size = 247180, upload-time = "2026-03-25T20:21:37.136Z" }, + { url = "https://files.pythonhosted.org/packages/d3/74/16336ffd19ed4da28a70959f92f506233bd7cfc2332b20bdb01591e8b1d1/tomli-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5", size = 251674, upload-time = "2026-03-25T20:21:38.298Z" }, + { url = "https://files.pythonhosted.org/packages/16/f9/229fa3434c590ddf6c0aa9af64d3af4b752540686cace29e6281e3458469/tomli-2.4.1-cp313-cp313-win32.whl", hash = "sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd", size = 97976, upload-time = "2026-03-25T20:21:39.316Z" }, + { url = "https://files.pythonhosted.org/packages/6a/1e/71dfd96bcc1c775420cb8befe7a9d35f2e5b1309798f009dca17b7708c1e/tomli-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36", size = 108755, upload-time = "2026-03-25T20:21:40.248Z" }, + { url = "https://files.pythonhosted.org/packages/83/7a/d34f422a021d62420b78f5c538e5b102f62bea616d1d75a13f0a88acb04a/tomli-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd", size = 95265, upload-time = "2026-03-25T20:21:41.219Z" }, + { url = "https://files.pythonhosted.org/packages/3c/fb/9a5c8d27dbab540869f7c1f8eb0abb3244189ce780ba9cd73f3770662072/tomli-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf", size = 155726, upload-time = "2026-03-25T20:21:42.23Z" }, + { url = "https://files.pythonhosted.org/packages/62/05/d2f816630cc771ad836af54f5001f47a6f611d2d39535364f148b6a92d6b/tomli-2.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac", size = 149859, upload-time = "2026-03-25T20:21:43.386Z" }, + { url = "https://files.pythonhosted.org/packages/ce/48/66341bdb858ad9bd0ceab5a86f90eddab127cf8b046418009f2125630ecb/tomli-2.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662", size = 244713, upload-time = "2026-03-25T20:21:44.474Z" }, + { url = "https://files.pythonhosted.org/packages/df/6d/c5fad00d82b3c7a3ab6189bd4b10e60466f22cfe8a08a9394185c8a8111c/tomli-2.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853", size = 252084, upload-time = "2026-03-25T20:21:45.62Z" }, + { url = "https://files.pythonhosted.org/packages/00/71/3a69e86f3eafe8c7a59d008d245888051005bd657760e96d5fbfb0b740c2/tomli-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15", size = 247973, upload-time = "2026-03-25T20:21:46.937Z" }, + { url = "https://files.pythonhosted.org/packages/67/50/361e986652847fec4bd5e4a0208752fbe64689c603c7ae5ea7cb16b1c0ca/tomli-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba", size = 256223, upload-time = "2026-03-25T20:21:48.467Z" }, + { url = "https://files.pythonhosted.org/packages/8c/9a/b4173689a9203472e5467217e0154b00e260621caa227b6fa01feab16998/tomli-2.4.1-cp314-cp314-win32.whl", hash = "sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6", size = 98973, upload-time = "2026-03-25T20:21:49.526Z" }, + { url = "https://files.pythonhosted.org/packages/14/58/640ac93bf230cd27d002462c9af0d837779f8773bc03dee06b5835208214/tomli-2.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7", size = 109082, upload-time = "2026-03-25T20:21:50.506Z" }, + { url = "https://files.pythonhosted.org/packages/d5/2f/702d5e05b227401c1068f0d386d79a589bb12bf64c3d2c72ce0631e3bc49/tomli-2.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232", size = 96490, upload-time = "2026-03-25T20:21:51.474Z" }, + { url = "https://files.pythonhosted.org/packages/45/4b/b877b05c8ba62927d9865dd980e34a755de541eb65fffba52b4cc495d4d2/tomli-2.4.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4", size = 164263, upload-time = "2026-03-25T20:21:52.543Z" }, + { url = "https://files.pythonhosted.org/packages/24/79/6ab420d37a270b89f7195dec5448f79400d9e9c1826df982f3f8e97b24fd/tomli-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c", size = 160736, upload-time = "2026-03-25T20:21:53.674Z" }, + { url = "https://files.pythonhosted.org/packages/02/e0/3630057d8eb170310785723ed5adcdfb7d50cb7e6455f85ba8a3deed642b/tomli-2.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d", size = 270717, upload-time = "2026-03-25T20:21:55.129Z" }, + { url = "https://files.pythonhosted.org/packages/7a/b4/1613716072e544d1a7891f548d8f9ec6ce2faf42ca65acae01d76ea06bb0/tomli-2.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41", size = 278461, upload-time = "2026-03-25T20:21:56.228Z" }, + { url = "https://files.pythonhosted.org/packages/05/38/30f541baf6a3f6df77b3df16b01ba319221389e2da59427e221ef417ac0c/tomli-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c", size = 274855, upload-time = "2026-03-25T20:21:57.653Z" }, + { url = "https://files.pythonhosted.org/packages/77/a3/ec9dd4fd2c38e98de34223b995a3b34813e6bdadf86c75314c928350ed14/tomli-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f", size = 283144, upload-time = "2026-03-25T20:21:59.089Z" }, + { url = "https://files.pythonhosted.org/packages/ef/be/605a6261cac79fba2ec0c9827e986e00323a1945700969b8ee0b30d85453/tomli-2.4.1-cp314-cp314t-win32.whl", hash = "sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8", size = 108683, upload-time = "2026-03-25T20:22:00.214Z" }, + { url = "https://files.pythonhosted.org/packages/12/64/da524626d3b9cc40c168a13da8335fe1c51be12c0a63685cc6db7308daae/tomli-2.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26", size = 121196, upload-time = "2026-03-25T20:22:01.169Z" }, + { url = "https://files.pythonhosted.org/packages/5a/cd/e80b62269fc78fc36c9af5a6b89c835baa8af28ff5ad28c7028d60860320/tomli-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396", size = 100393, upload-time = "2026-03-25T20:22:02.137Z" }, + { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "extra == 'group-10-cloudflare-pydantic-v2' or extra != 'group-10-cloudflare-pydantic-v1'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, +] + +[[package]] +name = "yarl" +version = "1.22.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.10'", +] +dependencies = [ + { name = "idna", marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "multidict", marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "propcache", marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/57/63/0c6ebca57330cd313f6102b16dd57ffaf3ec4c83403dcb45dbd15c6f3ea1/yarl-1.22.0.tar.gz", hash = "sha256:bebf8557577d4401ba8bd9ff33906f1376c877aa78d1fe216ad01b4d6745af71", size = 187169, upload-time = "2025-10-06T14:12:55.963Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/43/a2204825342f37c337f5edb6637040fa14e365b2fcc2346960201d457579/yarl-1.22.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c7bd6683587567e5a49ee6e336e0612bec8329be1b7d4c8af5687dcdeb67ee1e", size = 140517, upload-time = "2025-10-06T14:08:42.494Z" }, + { url = "https://files.pythonhosted.org/packages/44/6f/674f3e6f02266428c56f704cd2501c22f78e8b2eeb23f153117cc86fb28a/yarl-1.22.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5cdac20da754f3a723cceea5b3448e1a2074866406adeb4ef35b469d089adb8f", size = 93495, upload-time = "2025-10-06T14:08:46.2Z" }, + { url = "https://files.pythonhosted.org/packages/b8/12/5b274d8a0f30c07b91b2f02cba69152600b47830fcfb465c108880fcee9c/yarl-1.22.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:07a524d84df0c10f41e3ee918846e1974aba4ec017f990dc735aad487a0bdfdf", size = 94400, upload-time = "2025-10-06T14:08:47.855Z" }, + { url = "https://files.pythonhosted.org/packages/e2/7f/df1b6949b1fa1aa9ff6de6e2631876ad4b73c4437822026e85d8acb56bb1/yarl-1.22.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e1b329cb8146d7b736677a2440e422eadd775d1806a81db2d4cded80a48efc1a", size = 347545, upload-time = "2025-10-06T14:08:49.683Z" }, + { url = "https://files.pythonhosted.org/packages/84/09/f92ed93bd6cd77872ab6c3462df45ca45cd058d8f1d0c9b4f54c1704429f/yarl-1.22.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:75976c6945d85dbb9ee6308cd7ff7b1fb9409380c82d6119bd778d8fcfe2931c", size = 319598, upload-time = "2025-10-06T14:08:51.215Z" }, + { url = "https://files.pythonhosted.org/packages/c3/97/ac3f3feae7d522cf7ccec3d340bb0b2b61c56cb9767923df62a135092c6b/yarl-1.22.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:80ddf7a5f8c86cb3eb4bc9028b07bbbf1f08a96c5c0bc1244be5e8fefcb94147", size = 363893, upload-time = "2025-10-06T14:08:53.144Z" }, + { url = "https://files.pythonhosted.org/packages/06/49/f3219097403b9c84a4d079b1d7bda62dd9b86d0d6e4428c02d46ab2c77fc/yarl-1.22.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d332fc2e3c94dad927f2112395772a4e4fedbcf8f80efc21ed7cdfae4d574fdb", size = 371240, upload-time = "2025-10-06T14:08:55.036Z" }, + { url = "https://files.pythonhosted.org/packages/35/9f/06b765d45c0e44e8ecf0fe15c9eacbbde342bb5b7561c46944f107bfb6c3/yarl-1.22.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0cf71bf877efeac18b38d3930594c0948c82b64547c1cf420ba48722fe5509f6", size = 346965, upload-time = "2025-10-06T14:08:56.722Z" }, + { url = "https://files.pythonhosted.org/packages/c5/69/599e7cea8d0fcb1694323b0db0dda317fa3162f7b90166faddecf532166f/yarl-1.22.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:663e1cadaddae26be034a6ab6072449a8426ddb03d500f43daf952b74553bba0", size = 342026, upload-time = "2025-10-06T14:08:58.563Z" }, + { url = "https://files.pythonhosted.org/packages/95/6f/9dfd12c8bc90fea9eab39832ee32ea48f8e53d1256252a77b710c065c89f/yarl-1.22.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:6dcbb0829c671f305be48a7227918cfcd11276c2d637a8033a99a02b67bf9eda", size = 335637, upload-time = "2025-10-06T14:09:00.506Z" }, + { url = "https://files.pythonhosted.org/packages/57/2e/34c5b4eb9b07e16e873db5b182c71e5f06f9b5af388cdaa97736d79dd9a6/yarl-1.22.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:f0d97c18dfd9a9af4490631905a3f131a8e4c9e80a39353919e2cfed8f00aedc", size = 359082, upload-time = "2025-10-06T14:09:01.936Z" }, + { url = "https://files.pythonhosted.org/packages/31/71/fa7e10fb772d273aa1f096ecb8ab8594117822f683bab7d2c5a89914c92a/yarl-1.22.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:437840083abe022c978470b942ff832c3940b2ad3734d424b7eaffcd07f76737", size = 357811, upload-time = "2025-10-06T14:09:03.445Z" }, + { url = "https://files.pythonhosted.org/packages/26/da/11374c04e8e1184a6a03cf9c8f5688d3e5cec83ed6f31ad3481b3207f709/yarl-1.22.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a899cbd98dce6f5d8de1aad31cb712ec0a530abc0a86bd6edaa47c1090138467", size = 351223, upload-time = "2025-10-06T14:09:05.401Z" }, + { url = "https://files.pythonhosted.org/packages/82/8f/e2d01f161b0c034a30410e375e191a5d27608c1f8693bab1a08b089ca096/yarl-1.22.0-cp310-cp310-win32.whl", hash = "sha256:595697f68bd1f0c1c159fcb97b661fc9c3f5db46498043555d04805430e79bea", size = 82118, upload-time = "2025-10-06T14:09:11.148Z" }, + { url = "https://files.pythonhosted.org/packages/62/46/94c76196642dbeae634c7a61ba3da88cd77bed875bf6e4a8bed037505aa6/yarl-1.22.0-cp310-cp310-win_amd64.whl", hash = "sha256:cb95a9b1adaa48e41815a55ae740cfda005758104049a640a398120bf02515ca", size = 86852, upload-time = "2025-10-06T14:09:12.958Z" }, + { url = "https://files.pythonhosted.org/packages/af/af/7df4f179d3b1a6dcb9a4bd2ffbc67642746fcafdb62580e66876ce83fff4/yarl-1.22.0-cp310-cp310-win_arm64.whl", hash = "sha256:b85b982afde6df99ecc996990d4ad7ccbdbb70e2a4ba4de0aecde5922ba98a0b", size = 82012, upload-time = "2025-10-06T14:09:14.664Z" }, + { url = "https://files.pythonhosted.org/packages/4d/27/5ab13fc84c76a0250afd3d26d5936349a35be56ce5785447d6c423b26d92/yarl-1.22.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1ab72135b1f2db3fed3997d7e7dc1b80573c67138023852b6efb336a5eae6511", size = 141607, upload-time = "2025-10-06T14:09:16.298Z" }, + { url = "https://files.pythonhosted.org/packages/6a/a1/d065d51d02dc02ce81501d476b9ed2229d9a990818332242a882d5d60340/yarl-1.22.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:669930400e375570189492dc8d8341301578e8493aec04aebc20d4717f899dd6", size = 94027, upload-time = "2025-10-06T14:09:17.786Z" }, + { url = "https://files.pythonhosted.org/packages/c1/da/8da9f6a53f67b5106ffe902c6fa0164e10398d4e150d85838b82f424072a/yarl-1.22.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:792a2af6d58177ef7c19cbf0097aba92ca1b9cb3ffdd9c7470e156c8f9b5e028", size = 94963, upload-time = "2025-10-06T14:09:19.662Z" }, + { url = "https://files.pythonhosted.org/packages/68/fe/2c1f674960c376e29cb0bec1249b117d11738db92a6ccc4a530b972648db/yarl-1.22.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3ea66b1c11c9150f1372f69afb6b8116f2dd7286f38e14ea71a44eee9ec51b9d", size = 368406, upload-time = "2025-10-06T14:09:21.402Z" }, + { url = "https://files.pythonhosted.org/packages/95/26/812a540e1c3c6418fec60e9bbd38e871eaba9545e94fa5eff8f4a8e28e1e/yarl-1.22.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3e2daa88dc91870215961e96a039ec73e4937da13cf77ce17f9cad0c18df3503", size = 336581, upload-time = "2025-10-06T14:09:22.98Z" }, + { url = "https://files.pythonhosted.org/packages/0b/f5/5777b19e26fdf98563985e481f8be3d8a39f8734147a6ebf459d0dab5a6b/yarl-1.22.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ba440ae430c00eee41509353628600212112cd5018d5def7e9b05ea7ac34eb65", size = 388924, upload-time = "2025-10-06T14:09:24.655Z" }, + { url = "https://files.pythonhosted.org/packages/86/08/24bd2477bd59c0bbd994fe1d93b126e0472e4e3df5a96a277b0a55309e89/yarl-1.22.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e6438cc8f23a9c1478633d216b16104a586b9761db62bfacb6425bac0a36679e", size = 392890, upload-time = "2025-10-06T14:09:26.617Z" }, + { url = "https://files.pythonhosted.org/packages/46/00/71b90ed48e895667ecfb1eaab27c1523ee2fa217433ed77a73b13205ca4b/yarl-1.22.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c52a6e78aef5cf47a98ef8e934755abf53953379b7d53e68b15ff4420e6683d", size = 365819, upload-time = "2025-10-06T14:09:28.544Z" }, + { url = "https://files.pythonhosted.org/packages/30/2d/f715501cae832651d3282387c6a9236cd26bd00d0ff1e404b3dc52447884/yarl-1.22.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3b06bcadaac49c70f4c88af4ffcfbe3dc155aab3163e75777818092478bcbbe7", size = 363601, upload-time = "2025-10-06T14:09:30.568Z" }, + { url = "https://files.pythonhosted.org/packages/f8/f9/a678c992d78e394e7126ee0b0e4e71bd2775e4334d00a9278c06a6cce96a/yarl-1.22.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:6944b2dc72c4d7f7052683487e3677456050ff77fcf5e6204e98caf785ad1967", size = 358072, upload-time = "2025-10-06T14:09:32.528Z" }, + { url = "https://files.pythonhosted.org/packages/2c/d1/b49454411a60edb6fefdcad4f8e6dbba7d8019e3a508a1c5836cba6d0781/yarl-1.22.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d5372ca1df0f91a86b047d1277c2aaf1edb32d78bbcefffc81b40ffd18f027ed", size = 385311, upload-time = "2025-10-06T14:09:34.634Z" }, + { url = "https://files.pythonhosted.org/packages/87/e5/40d7a94debb8448c7771a916d1861d6609dddf7958dc381117e7ba36d9e8/yarl-1.22.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:51af598701f5299012b8416486b40fceef8c26fc87dc6d7d1f6fc30609ea0aa6", size = 381094, upload-time = "2025-10-06T14:09:36.268Z" }, + { url = "https://files.pythonhosted.org/packages/35/d8/611cc282502381ad855448643e1ad0538957fc82ae83dfe7762c14069e14/yarl-1.22.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b266bd01fedeffeeac01a79ae181719ff848a5a13ce10075adbefc8f1daee70e", size = 370944, upload-time = "2025-10-06T14:09:37.872Z" }, + { url = "https://files.pythonhosted.org/packages/2d/df/fadd00fb1c90e1a5a8bd731fa3d3de2e165e5a3666a095b04e31b04d9cb6/yarl-1.22.0-cp311-cp311-win32.whl", hash = "sha256:a9b1ba5610a4e20f655258d5a1fdc7ebe3d837bb0e45b581398b99eb98b1f5ca", size = 81804, upload-time = "2025-10-06T14:09:39.359Z" }, + { url = "https://files.pythonhosted.org/packages/b5/f7/149bb6f45f267cb5c074ac40c01c6b3ea6d8a620d34b337f6321928a1b4d/yarl-1.22.0-cp311-cp311-win_amd64.whl", hash = "sha256:078278b9b0b11568937d9509b589ee83ef98ed6d561dfe2020e24a9fd08eaa2b", size = 86858, upload-time = "2025-10-06T14:09:41.068Z" }, + { url = "https://files.pythonhosted.org/packages/2b/13/88b78b93ad3f2f0b78e13bfaaa24d11cbc746e93fe76d8c06bf139615646/yarl-1.22.0-cp311-cp311-win_arm64.whl", hash = "sha256:b6a6f620cfe13ccec221fa312139135166e47ae169f8253f72a0abc0dae94376", size = 81637, upload-time = "2025-10-06T14:09:42.712Z" }, + { url = "https://files.pythonhosted.org/packages/75/ff/46736024fee3429b80a165a732e38e5d5a238721e634ab41b040d49f8738/yarl-1.22.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e340382d1afa5d32b892b3ff062436d592ec3d692aeea3bef3a5cfe11bbf8c6f", size = 142000, upload-time = "2025-10-06T14:09:44.631Z" }, + { url = "https://files.pythonhosted.org/packages/5a/9a/b312ed670df903145598914770eb12de1bac44599549b3360acc96878df8/yarl-1.22.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f1e09112a2c31ffe8d80be1b0988fa6a18c5d5cad92a9ffbb1c04c91bfe52ad2", size = 94338, upload-time = "2025-10-06T14:09:46.372Z" }, + { url = "https://files.pythonhosted.org/packages/ba/f5/0601483296f09c3c65e303d60c070a5c19fcdbc72daa061e96170785bc7d/yarl-1.22.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:939fe60db294c786f6b7c2d2e121576628468f65453d86b0fe36cb52f987bd74", size = 94909, upload-time = "2025-10-06T14:09:48.648Z" }, + { url = "https://files.pythonhosted.org/packages/60/41/9a1fe0b73dbcefce72e46cf149b0e0a67612d60bfc90fb59c2b2efdfbd86/yarl-1.22.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e1651bf8e0398574646744c1885a41198eba53dc8a9312b954073f845c90a8df", size = 372940, upload-time = "2025-10-06T14:09:50.089Z" }, + { url = "https://files.pythonhosted.org/packages/17/7a/795cb6dfee561961c30b800f0ed616b923a2ec6258b5def2a00bf8231334/yarl-1.22.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b8a0588521a26bf92a57a1705b77b8b59044cdceccac7151bd8d229e66b8dedb", size = 345825, upload-time = "2025-10-06T14:09:52.142Z" }, + { url = "https://files.pythonhosted.org/packages/d7/93/a58f4d596d2be2ae7bab1a5846c4d270b894958845753b2c606d666744d3/yarl-1.22.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:42188e6a615c1a75bcaa6e150c3fe8f3e8680471a6b10150c5f7e83f47cc34d2", size = 386705, upload-time = "2025-10-06T14:09:54.128Z" }, + { url = "https://files.pythonhosted.org/packages/61/92/682279d0e099d0e14d7fd2e176bd04f48de1484f56546a3e1313cd6c8e7c/yarl-1.22.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f6d2cb59377d99718913ad9a151030d6f83ef420a2b8f521d94609ecc106ee82", size = 396518, upload-time = "2025-10-06T14:09:55.762Z" }, + { url = "https://files.pythonhosted.org/packages/db/0f/0d52c98b8a885aeda831224b78f3be7ec2e1aa4a62091f9f9188c3c65b56/yarl-1.22.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50678a3b71c751d58d7908edc96d332af328839eea883bb554a43f539101277a", size = 377267, upload-time = "2025-10-06T14:09:57.958Z" }, + { url = "https://files.pythonhosted.org/packages/22/42/d2685e35908cbeaa6532c1fc73e89e7f2efb5d8a7df3959ea8e37177c5a3/yarl-1.22.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1e8fbaa7cec507aa24ea27a01456e8dd4b6fab829059b69844bd348f2d467124", size = 365797, upload-time = "2025-10-06T14:09:59.527Z" }, + { url = "https://files.pythonhosted.org/packages/a2/83/cf8c7bcc6355631762f7d8bdab920ad09b82efa6b722999dfb05afa6cfac/yarl-1.22.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:433885ab5431bc3d3d4f2f9bd15bfa1614c522b0f1405d62c4f926ccd69d04fa", size = 365535, upload-time = "2025-10-06T14:10:01.139Z" }, + { url = "https://files.pythonhosted.org/packages/25/e1/5302ff9b28f0c59cac913b91fe3f16c59a033887e57ce9ca5d41a3a94737/yarl-1.22.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:b790b39c7e9a4192dc2e201a282109ed2985a1ddbd5ac08dc56d0e121400a8f7", size = 382324, upload-time = "2025-10-06T14:10:02.756Z" }, + { url = "https://files.pythonhosted.org/packages/bf/cd/4617eb60f032f19ae3a688dc990d8f0d89ee0ea378b61cac81ede3e52fae/yarl-1.22.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:31f0b53913220599446872d757257be5898019c85e7971599065bc55065dc99d", size = 383803, upload-time = "2025-10-06T14:10:04.552Z" }, + { url = "https://files.pythonhosted.org/packages/59/65/afc6e62bb506a319ea67b694551dab4a7e6fb7bf604e9bd9f3e11d575fec/yarl-1.22.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a49370e8f711daec68d09b821a34e1167792ee2d24d405cbc2387be4f158b520", size = 374220, upload-time = "2025-10-06T14:10:06.489Z" }, + { url = "https://files.pythonhosted.org/packages/e7/3d/68bf18d50dc674b942daec86a9ba922d3113d8399b0e52b9897530442da2/yarl-1.22.0-cp312-cp312-win32.whl", hash = "sha256:70dfd4f241c04bd9239d53b17f11e6ab672b9f1420364af63e8531198e3f5fe8", size = 81589, upload-time = "2025-10-06T14:10:09.254Z" }, + { url = "https://files.pythonhosted.org/packages/c8/9a/6ad1a9b37c2f72874f93e691b2e7ecb6137fb2b899983125db4204e47575/yarl-1.22.0-cp312-cp312-win_amd64.whl", hash = "sha256:8884d8b332a5e9b88e23f60bb166890009429391864c685e17bd73a9eda9105c", size = 87213, upload-time = "2025-10-06T14:10:11.369Z" }, + { url = "https://files.pythonhosted.org/packages/44/c5/c21b562d1680a77634d748e30c653c3ca918beb35555cff24986fff54598/yarl-1.22.0-cp312-cp312-win_arm64.whl", hash = "sha256:ea70f61a47f3cc93bdf8b2f368ed359ef02a01ca6393916bc8ff877427181e74", size = 81330, upload-time = "2025-10-06T14:10:13.112Z" }, + { url = "https://files.pythonhosted.org/packages/ea/f3/d67de7260456ee105dc1d162d43a019ecad6b91e2f51809d6cddaa56690e/yarl-1.22.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8dee9c25c74997f6a750cd317b8ca63545169c098faee42c84aa5e506c819b53", size = 139980, upload-time = "2025-10-06T14:10:14.601Z" }, + { url = "https://files.pythonhosted.org/packages/01/88/04d98af0b47e0ef42597b9b28863b9060bb515524da0a65d5f4db160b2d5/yarl-1.22.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:01e73b85a5434f89fc4fe27dcda2aff08ddf35e4d47bbbea3bdcd25321af538a", size = 93424, upload-time = "2025-10-06T14:10:16.115Z" }, + { url = "https://files.pythonhosted.org/packages/18/91/3274b215fd8442a03975ce6bee5fe6aa57a8326b29b9d3d56234a1dca244/yarl-1.22.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:22965c2af250d20c873cdbee8ff958fb809940aeb2e74ba5f20aaf6b7ac8c70c", size = 93821, upload-time = "2025-10-06T14:10:17.993Z" }, + { url = "https://files.pythonhosted.org/packages/61/3a/caf4e25036db0f2da4ca22a353dfeb3c9d3c95d2761ebe9b14df8fc16eb0/yarl-1.22.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4f15793aa49793ec8d1c708ab7f9eded1aa72edc5174cae703651555ed1b601", size = 373243, upload-time = "2025-10-06T14:10:19.44Z" }, + { url = "https://files.pythonhosted.org/packages/6e/9e/51a77ac7516e8e7803b06e01f74e78649c24ee1021eca3d6a739cb6ea49c/yarl-1.22.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5542339dcf2747135c5c85f68680353d5cb9ffd741c0f2e8d832d054d41f35a", size = 342361, upload-time = "2025-10-06T14:10:21.124Z" }, + { url = "https://files.pythonhosted.org/packages/d4/f8/33b92454789dde8407f156c00303e9a891f1f51a0330b0fad7c909f87692/yarl-1.22.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5c401e05ad47a75869c3ab3e35137f8468b846770587e70d71e11de797d113df", size = 387036, upload-time = "2025-10-06T14:10:22.902Z" }, + { url = "https://files.pythonhosted.org/packages/d9/9a/c5db84ea024f76838220280f732970aa4ee154015d7f5c1bfb60a267af6f/yarl-1.22.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:243dda95d901c733f5b59214d28b0120893d91777cb8aa043e6ef059d3cddfe2", size = 397671, upload-time = "2025-10-06T14:10:24.523Z" }, + { url = "https://files.pythonhosted.org/packages/11/c9/cd8538dc2e7727095e0c1d867bad1e40c98f37763e6d995c1939f5fdc7b1/yarl-1.22.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bec03d0d388060058f5d291a813f21c011041938a441c593374da6077fe21b1b", size = 377059, upload-time = "2025-10-06T14:10:26.406Z" }, + { url = "https://files.pythonhosted.org/packages/a1/b9/ab437b261702ced75122ed78a876a6dec0a1b0f5e17a4ac7a9a2482d8abe/yarl-1.22.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b0748275abb8c1e1e09301ee3cf90c8a99678a4e92e4373705f2a2570d581273", size = 365356, upload-time = "2025-10-06T14:10:28.461Z" }, + { url = "https://files.pythonhosted.org/packages/b2/9d/8e1ae6d1d008a9567877b08f0ce4077a29974c04c062dabdb923ed98e6fe/yarl-1.22.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:47fdb18187e2a4e18fda2c25c05d8251a9e4a521edaed757fef033e7d8498d9a", size = 361331, upload-time = "2025-10-06T14:10:30.541Z" }, + { url = "https://files.pythonhosted.org/packages/ca/5a/09b7be3905962f145b73beb468cdd53db8aa171cf18c80400a54c5b82846/yarl-1.22.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c7044802eec4524fde550afc28edda0dd5784c4c45f0be151a2d3ba017daca7d", size = 382590, upload-time = "2025-10-06T14:10:33.352Z" }, + { url = "https://files.pythonhosted.org/packages/aa/7f/59ec509abf90eda5048b0bc3e2d7b5099dffdb3e6b127019895ab9d5ef44/yarl-1.22.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:139718f35149ff544caba20fce6e8a2f71f1e39b92c700d8438a0b1d2a631a02", size = 385316, upload-time = "2025-10-06T14:10:35.034Z" }, + { url = "https://files.pythonhosted.org/packages/e5/84/891158426bc8036bfdfd862fabd0e0fa25df4176ec793e447f4b85cf1be4/yarl-1.22.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e1b51bebd221006d3d2f95fbe124b22b247136647ae5dcc8c7acafba66e5ee67", size = 374431, upload-time = "2025-10-06T14:10:37.76Z" }, + { url = "https://files.pythonhosted.org/packages/bb/49/03da1580665baa8bef5e8ed34c6df2c2aca0a2f28bf397ed238cc1bbc6f2/yarl-1.22.0-cp313-cp313-win32.whl", hash = "sha256:d3e32536234a95f513bd374e93d717cf6b2231a791758de6c509e3653f234c95", size = 81555, upload-time = "2025-10-06T14:10:39.649Z" }, + { url = "https://files.pythonhosted.org/packages/9a/ee/450914ae11b419eadd067c6183ae08381cfdfcb9798b90b2b713bbebddda/yarl-1.22.0-cp313-cp313-win_amd64.whl", hash = "sha256:47743b82b76d89a1d20b83e60d5c20314cbd5ba2befc9cda8f28300c4a08ed4d", size = 86965, upload-time = "2025-10-06T14:10:41.313Z" }, + { url = "https://files.pythonhosted.org/packages/98/4d/264a01eae03b6cf629ad69bae94e3b0e5344741e929073678e84bf7a3e3b/yarl-1.22.0-cp313-cp313-win_arm64.whl", hash = "sha256:5d0fcda9608875f7d052eff120c7a5da474a6796fe4d83e152e0e4d42f6d1a9b", size = 81205, upload-time = "2025-10-06T14:10:43.167Z" }, + { url = "https://files.pythonhosted.org/packages/88/fc/6908f062a2f77b5f9f6d69cecb1747260831ff206adcbc5b510aff88df91/yarl-1.22.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:719ae08b6972befcba4310e49edb1161a88cdd331e3a694b84466bd938a6ab10", size = 146209, upload-time = "2025-10-06T14:10:44.643Z" }, + { url = "https://files.pythonhosted.org/packages/65/47/76594ae8eab26210b4867be6f49129861ad33da1f1ebdf7051e98492bf62/yarl-1.22.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:47d8a5c446df1c4db9d21b49619ffdba90e77c89ec6e283f453856c74b50b9e3", size = 95966, upload-time = "2025-10-06T14:10:46.554Z" }, + { url = "https://files.pythonhosted.org/packages/ab/ce/05e9828a49271ba6b5b038b15b3934e996980dd78abdfeb52a04cfb9467e/yarl-1.22.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cfebc0ac8333520d2d0423cbbe43ae43c8838862ddb898f5ca68565e395516e9", size = 97312, upload-time = "2025-10-06T14:10:48.007Z" }, + { url = "https://files.pythonhosted.org/packages/d1/c5/7dffad5e4f2265b29c9d7ec869c369e4223166e4f9206fc2243ee9eea727/yarl-1.22.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4398557cbf484207df000309235979c79c4356518fd5c99158c7d38203c4da4f", size = 361967, upload-time = "2025-10-06T14:10:49.997Z" }, + { url = "https://files.pythonhosted.org/packages/50/b2/375b933c93a54bff7fc041e1a6ad2c0f6f733ffb0c6e642ce56ee3b39970/yarl-1.22.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2ca6fd72a8cd803be290d42f2dec5cdcd5299eeb93c2d929bf060ad9efaf5de0", size = 323949, upload-time = "2025-10-06T14:10:52.004Z" }, + { url = "https://files.pythonhosted.org/packages/66/50/bfc2a29a1d78644c5a7220ce2f304f38248dc94124a326794e677634b6cf/yarl-1.22.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca1f59c4e1ab6e72f0a23c13fca5430f889634166be85dbf1013683e49e3278e", size = 361818, upload-time = "2025-10-06T14:10:54.078Z" }, + { url = "https://files.pythonhosted.org/packages/46/96/f3941a46af7d5d0f0498f86d71275696800ddcdd20426298e572b19b91ff/yarl-1.22.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c5010a52015e7c70f86eb967db0f37f3c8bd503a695a49f8d45700144667708", size = 372626, upload-time = "2025-10-06T14:10:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/c1/42/8b27c83bb875cd89448e42cd627e0fb971fa1675c9ec546393d18826cb50/yarl-1.22.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d7672ecf7557476642c88497c2f8d8542f8e36596e928e9bcba0e42e1e7d71f", size = 341129, upload-time = "2025-10-06T14:10:57.985Z" }, + { url = "https://files.pythonhosted.org/packages/49/36/99ca3122201b382a3cf7cc937b95235b0ac944f7e9f2d5331d50821ed352/yarl-1.22.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3b7c88eeef021579d600e50363e0b6ee4f7f6f728cd3486b9d0f3ee7b946398d", size = 346776, upload-time = "2025-10-06T14:10:59.633Z" }, + { url = "https://files.pythonhosted.org/packages/85/b4/47328bf996acd01a4c16ef9dcd2f59c969f495073616586f78cd5f2efb99/yarl-1.22.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:f4afb5c34f2c6fecdcc182dfcfc6af6cccf1aa923eed4d6a12e9d96904e1a0d8", size = 334879, upload-time = "2025-10-06T14:11:01.454Z" }, + { url = "https://files.pythonhosted.org/packages/c2/ad/b77d7b3f14a4283bffb8e92c6026496f6de49751c2f97d4352242bba3990/yarl-1.22.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:59c189e3e99a59cf8d83cbb31d4db02d66cda5a1a4374e8a012b51255341abf5", size = 350996, upload-time = "2025-10-06T14:11:03.452Z" }, + { url = "https://files.pythonhosted.org/packages/81/c8/06e1d69295792ba54d556f06686cbd6a7ce39c22307100e3fb4a2c0b0a1d/yarl-1.22.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:5a3bf7f62a289fa90f1990422dc8dff5a458469ea71d1624585ec3a4c8d6960f", size = 356047, upload-time = "2025-10-06T14:11:05.115Z" }, + { url = "https://files.pythonhosted.org/packages/4b/b8/4c0e9e9f597074b208d18cef227d83aac36184bfbc6eab204ea55783dbc5/yarl-1.22.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:de6b9a04c606978fdfe72666fa216ffcf2d1a9f6a381058d4378f8d7b1e5de62", size = 342947, upload-time = "2025-10-06T14:11:08.137Z" }, + { url = "https://files.pythonhosted.org/packages/e0/e5/11f140a58bf4c6ad7aca69a892bff0ee638c31bea4206748fc0df4ebcb3a/yarl-1.22.0-cp313-cp313t-win32.whl", hash = "sha256:1834bb90991cc2999f10f97f5f01317f99b143284766d197e43cd5b45eb18d03", size = 86943, upload-time = "2025-10-06T14:11:10.284Z" }, + { url = "https://files.pythonhosted.org/packages/31/74/8b74bae38ed7fe6793d0c15a0c8207bbb819cf287788459e5ed230996cdd/yarl-1.22.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ff86011bd159a9d2dfc89c34cfd8aff12875980e3bd6a39ff097887520e60249", size = 93715, upload-time = "2025-10-06T14:11:11.739Z" }, + { url = "https://files.pythonhosted.org/packages/69/66/991858aa4b5892d57aef7ee1ba6b4d01ec3b7eb3060795d34090a3ca3278/yarl-1.22.0-cp313-cp313t-win_arm64.whl", hash = "sha256:7861058d0582b847bc4e3a4a4c46828a410bca738673f35a29ba3ca5db0b473b", size = 83857, upload-time = "2025-10-06T14:11:13.586Z" }, + { url = "https://files.pythonhosted.org/packages/46/b3/e20ef504049f1a1c54a814b4b9bed96d1ac0e0610c3b4da178f87209db05/yarl-1.22.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:34b36c2c57124530884d89d50ed2c1478697ad7473efd59cfd479945c95650e4", size = 140520, upload-time = "2025-10-06T14:11:15.465Z" }, + { url = "https://files.pythonhosted.org/packages/e4/04/3532d990fdbab02e5ede063676b5c4260e7f3abea2151099c2aa745acc4c/yarl-1.22.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:0dd9a702591ca2e543631c2a017e4a547e38a5c0f29eece37d9097e04a7ac683", size = 93504, upload-time = "2025-10-06T14:11:17.106Z" }, + { url = "https://files.pythonhosted.org/packages/11/63/ff458113c5c2dac9a9719ac68ee7c947cb621432bcf28c9972b1c0e83938/yarl-1.22.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:594fcab1032e2d2cc3321bb2e51271e7cd2b516c7d9aee780ece81b07ff8244b", size = 94282, upload-time = "2025-10-06T14:11:19.064Z" }, + { url = "https://files.pythonhosted.org/packages/a7/bc/315a56aca762d44a6aaaf7ad253f04d996cb6b27bad34410f82d76ea8038/yarl-1.22.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3d7a87a78d46a2e3d5b72587ac14b4c16952dd0887dbb051451eceac774411e", size = 372080, upload-time = "2025-10-06T14:11:20.996Z" }, + { url = "https://files.pythonhosted.org/packages/3f/3f/08e9b826ec2e099ea6e7c69a61272f4f6da62cb5b1b63590bb80ca2e4a40/yarl-1.22.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:852863707010316c973162e703bddabec35e8757e67fcb8ad58829de1ebc8590", size = 338696, upload-time = "2025-10-06T14:11:22.847Z" }, + { url = "https://files.pythonhosted.org/packages/e3/9f/90360108e3b32bd76789088e99538febfea24a102380ae73827f62073543/yarl-1.22.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:131a085a53bfe839a477c0845acf21efc77457ba2bcf5899618136d64f3303a2", size = 387121, upload-time = "2025-10-06T14:11:24.889Z" }, + { url = "https://files.pythonhosted.org/packages/98/92/ab8d4657bd5b46a38094cfaea498f18bb70ce6b63508fd7e909bd1f93066/yarl-1.22.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:078a8aefd263f4d4f923a9677b942b445a2be970ca24548a8102689a3a8ab8da", size = 394080, upload-time = "2025-10-06T14:11:27.307Z" }, + { url = "https://files.pythonhosted.org/packages/f5/e7/d8c5a7752fef68205296201f8ec2bf718f5c805a7a7e9880576c67600658/yarl-1.22.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bca03b91c323036913993ff5c738d0842fc9c60c4648e5c8d98331526df89784", size = 372661, upload-time = "2025-10-06T14:11:29.387Z" }, + { url = "https://files.pythonhosted.org/packages/b6/2e/f4d26183c8db0bb82d491b072f3127fb8c381a6206a3a56332714b79b751/yarl-1.22.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:68986a61557d37bb90d3051a45b91fa3d5c516d177dfc6dd6f2f436a07ff2b6b", size = 364645, upload-time = "2025-10-06T14:11:31.423Z" }, + { url = "https://files.pythonhosted.org/packages/80/7c/428e5812e6b87cd00ee8e898328a62c95825bf37c7fa87f0b6bb2ad31304/yarl-1.22.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:4792b262d585ff0dff6bcb787f8492e40698443ec982a3568c2096433660c694", size = 355361, upload-time = "2025-10-06T14:11:33.055Z" }, + { url = "https://files.pythonhosted.org/packages/ec/2a/249405fd26776f8b13c067378ef4d7dd49c9098d1b6457cdd152a99e96a9/yarl-1.22.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ebd4549b108d732dba1d4ace67614b9545b21ece30937a63a65dd34efa19732d", size = 381451, upload-time = "2025-10-06T14:11:35.136Z" }, + { url = "https://files.pythonhosted.org/packages/67/a8/fb6b1adbe98cf1e2dd9fad71003d3a63a1bc22459c6e15f5714eb9323b93/yarl-1.22.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f87ac53513d22240c7d59203f25cc3beac1e574c6cd681bbfd321987b69f95fd", size = 383814, upload-time = "2025-10-06T14:11:37.094Z" }, + { url = "https://files.pythonhosted.org/packages/d9/f9/3aa2c0e480fb73e872ae2814c43bc1e734740bb0d54e8cb2a95925f98131/yarl-1.22.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:22b029f2881599e2f1b06f8f1db2ee63bd309e2293ba2d566e008ba12778b8da", size = 370799, upload-time = "2025-10-06T14:11:38.83Z" }, + { url = "https://files.pythonhosted.org/packages/50/3c/af9dba3b8b5eeb302f36f16f92791f3ea62e3f47763406abf6d5a4a3333b/yarl-1.22.0-cp314-cp314-win32.whl", hash = "sha256:6a635ea45ba4ea8238463b4f7d0e721bad669f80878b7bfd1f89266e2ae63da2", size = 82990, upload-time = "2025-10-06T14:11:40.624Z" }, + { url = "https://files.pythonhosted.org/packages/ac/30/ac3a0c5bdc1d6efd1b41fa24d4897a4329b3b1e98de9449679dd327af4f0/yarl-1.22.0-cp314-cp314-win_amd64.whl", hash = "sha256:0d6e6885777af0f110b0e5d7e5dda8b704efed3894da26220b7f3d887b839a79", size = 88292, upload-time = "2025-10-06T14:11:42.578Z" }, + { url = "https://files.pythonhosted.org/packages/df/0a/227ab4ff5b998a1b7410abc7b46c9b7a26b0ca9e86c34ba4b8d8bc7c63d5/yarl-1.22.0-cp314-cp314-win_arm64.whl", hash = "sha256:8218f4e98d3c10d683584cb40f0424f4b9fd6e95610232dd75e13743b070ee33", size = 82888, upload-time = "2025-10-06T14:11:44.863Z" }, + { url = "https://files.pythonhosted.org/packages/06/5e/a15eb13db90abd87dfbefb9760c0f3f257ac42a5cac7e75dbc23bed97a9f/yarl-1.22.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:45c2842ff0e0d1b35a6bf1cd6c690939dacb617a70827f715232b2e0494d55d1", size = 146223, upload-time = "2025-10-06T14:11:46.796Z" }, + { url = "https://files.pythonhosted.org/packages/18/82/9665c61910d4d84f41a5bf6837597c89e665fa88aa4941080704645932a9/yarl-1.22.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:d947071e6ebcf2e2bee8fce76e10faca8f7a14808ca36a910263acaacef08eca", size = 95981, upload-time = "2025-10-06T14:11:48.845Z" }, + { url = "https://files.pythonhosted.org/packages/5d/9a/2f65743589809af4d0a6d3aa749343c4b5f4c380cc24a8e94a3c6625a808/yarl-1.22.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:334b8721303e61b00019474cc103bdac3d7b1f65e91f0bfedeec2d56dfe74b53", size = 97303, upload-time = "2025-10-06T14:11:50.897Z" }, + { url = "https://files.pythonhosted.org/packages/b0/ab/5b13d3e157505c43c3b43b5a776cbf7b24a02bc4cccc40314771197e3508/yarl-1.22.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e7ce67c34138a058fd092f67d07a72b8e31ff0c9236e751957465a24b28910c", size = 361820, upload-time = "2025-10-06T14:11:52.549Z" }, + { url = "https://files.pythonhosted.org/packages/fb/76/242a5ef4677615cf95330cfc1b4610e78184400699bdda0acb897ef5e49a/yarl-1.22.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d77e1b2c6d04711478cb1c4ab90db07f1609ccf06a287d5607fcd90dc9863acf", size = 323203, upload-time = "2025-10-06T14:11:54.225Z" }, + { url = "https://files.pythonhosted.org/packages/8c/96/475509110d3f0153b43d06164cf4195c64d16999e0c7e2d8a099adcd6907/yarl-1.22.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4647674b6150d2cae088fc07de2738a84b8bcedebef29802cf0b0a82ab6face", size = 363173, upload-time = "2025-10-06T14:11:56.069Z" }, + { url = "https://files.pythonhosted.org/packages/c9/66/59db471aecfbd559a1fd48aedd954435558cd98c7d0da8b03cc6c140a32c/yarl-1.22.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:efb07073be061c8f79d03d04139a80ba33cbd390ca8f0297aae9cce6411e4c6b", size = 373562, upload-time = "2025-10-06T14:11:58.783Z" }, + { url = "https://files.pythonhosted.org/packages/03/1f/c5d94abc91557384719da10ff166b916107c1b45e4d0423a88457071dd88/yarl-1.22.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e51ac5435758ba97ad69617e13233da53908beccc6cfcd6c34bbed8dcbede486", size = 339828, upload-time = "2025-10-06T14:12:00.686Z" }, + { url = "https://files.pythonhosted.org/packages/5f/97/aa6a143d3afba17b6465733681c70cf175af89f76ec8d9286e08437a7454/yarl-1.22.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:33e32a0dd0c8205efa8e83d04fc9f19313772b78522d1bdc7d9aed706bfd6138", size = 347551, upload-time = "2025-10-06T14:12:02.628Z" }, + { url = "https://files.pythonhosted.org/packages/43/3c/45a2b6d80195959239a7b2a8810506d4eea5487dce61c2a3393e7fc3c52e/yarl-1.22.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:bf4a21e58b9cde0e401e683ebd00f6ed30a06d14e93f7c8fd059f8b6e8f87b6a", size = 334512, upload-time = "2025-10-06T14:12:04.871Z" }, + { url = "https://files.pythonhosted.org/packages/86/a0/c2ab48d74599c7c84cb104ebd799c5813de252bea0f360ffc29d270c2caa/yarl-1.22.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:e4b582bab49ac33c8deb97e058cd67c2c50dac0dd134874106d9c774fd272529", size = 352400, upload-time = "2025-10-06T14:12:06.624Z" }, + { url = "https://files.pythonhosted.org/packages/32/75/f8919b2eafc929567d3d8411f72bdb1a2109c01caaab4ebfa5f8ffadc15b/yarl-1.22.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0b5bcc1a9c4839e7e30b7b30dd47fe5e7e44fb7054ec29b5bb8d526aa1041093", size = 357140, upload-time = "2025-10-06T14:12:08.362Z" }, + { url = "https://files.pythonhosted.org/packages/cf/72/6a85bba382f22cf78add705d8c3731748397d986e197e53ecc7835e76de7/yarl-1.22.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c0232bce2170103ec23c454e54a57008a9a72b5d1c3105dc2496750da8cfa47c", size = 341473, upload-time = "2025-10-06T14:12:10.994Z" }, + { url = "https://files.pythonhosted.org/packages/35/18/55e6011f7c044dc80b98893060773cefcfdbf60dfefb8cb2f58b9bacbd83/yarl-1.22.0-cp314-cp314t-win32.whl", hash = "sha256:8009b3173bcd637be650922ac455946197d858b3630b6d8787aa9e5c4564533e", size = 89056, upload-time = "2025-10-06T14:12:13.317Z" }, + { url = "https://files.pythonhosted.org/packages/f9/86/0f0dccb6e59a9e7f122c5afd43568b1d31b8ab7dda5f1b01fb5c7025c9a9/yarl-1.22.0-cp314-cp314t-win_amd64.whl", hash = "sha256:9fb17ea16e972c63d25d4a97f016d235c78dd2344820eb35bc034bc32012ee27", size = 96292, upload-time = "2025-10-06T14:12:15.398Z" }, + { url = "https://files.pythonhosted.org/packages/48/b7/503c98092fb3b344a179579f55814b613c1fbb1c23b3ec14a7b008a66a6e/yarl-1.22.0-cp314-cp314t-win_arm64.whl", hash = "sha256:9f6d73c1436b934e3f01df1e1b21ff765cd1d28c77dfb9ace207f746d4610ee1", size = 85171, upload-time = "2025-10-06T14:12:16.935Z" }, + { url = "https://files.pythonhosted.org/packages/94/fd/6480106702a79bcceda5fd9c63cb19a04a6506bd5ce7fd8d9b63742f0021/yarl-1.22.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3aa27acb6de7a23785d81557577491f6c38a5209a254d1191519d07d8fe51748", size = 141301, upload-time = "2025-10-06T14:12:19.01Z" }, + { url = "https://files.pythonhosted.org/packages/42/e1/6d95d21b17a93e793e4ec420a925fe1f6a9342338ca7a563ed21129c0990/yarl-1.22.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:af74f05666a5e531289cb1cc9c883d1de2088b8e5b4de48004e5ca8a830ac859", size = 93864, upload-time = "2025-10-06T14:12:21.05Z" }, + { url = "https://files.pythonhosted.org/packages/32/58/b8055273c203968e89808413ea4c984988b6649baabf10f4522e67c22d2f/yarl-1.22.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:62441e55958977b8167b2709c164c91a6363e25da322d87ae6dd9c6019ceecf9", size = 94706, upload-time = "2025-10-06T14:12:23.287Z" }, + { url = "https://files.pythonhosted.org/packages/18/91/d7bfbc28a88c2895ecd0da6a874def0c147de78afc52c773c28e1aa233a3/yarl-1.22.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b580e71cac3f8113d3135888770903eaf2f507e9421e5697d6ee6d8cd1c7f054", size = 347100, upload-time = "2025-10-06T14:12:28.527Z" }, + { url = "https://files.pythonhosted.org/packages/bd/e8/37a1e7b99721c0564b1fc7b0a4d1f595ef6fb8060d82ca61775b644185f7/yarl-1.22.0-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e81fda2fb4a07eda1a2252b216aa0df23ebcd4d584894e9612e80999a78fd95b", size = 318902, upload-time = "2025-10-06T14:12:30.528Z" }, + { url = "https://files.pythonhosted.org/packages/1c/ef/34724449d7ef2db4f22df644f2dac0b8a275d20f585e526937b3ae47b02d/yarl-1.22.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:99b6fc1d55782461b78221e95fc357b47ad98b041e8e20f47c1411d0aacddc60", size = 363302, upload-time = "2025-10-06T14:12:32.295Z" }, + { url = "https://files.pythonhosted.org/packages/8a/04/88a39a5dad39889f192cce8d66cc4c58dbeca983e83f9b6bf23822a7ed91/yarl-1.22.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:088e4e08f033db4be2ccd1f34cf29fe994772fb54cfe004bbf54db320af56890", size = 370816, upload-time = "2025-10-06T14:12:34.01Z" }, + { url = "https://files.pythonhosted.org/packages/6b/1f/5e895e547129413f56c76be2c3ce4b96c797d2d0ff3e16a817d9269b12e6/yarl-1.22.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e4e1f6f0b4da23e61188676e3ed027ef0baa833a2e633c29ff8530800edccba", size = 346465, upload-time = "2025-10-06T14:12:35.977Z" }, + { url = "https://files.pythonhosted.org/packages/11/13/a750e9fd6f9cc9ed3a52a70fe58ffe505322f0efe0d48e1fd9ffe53281f5/yarl-1.22.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:84fc3ec96fce86ce5aa305eb4aa9358279d1aa644b71fab7b8ed33fe3ba1a7ca", size = 341506, upload-time = "2025-10-06T14:12:37.788Z" }, + { url = "https://files.pythonhosted.org/packages/3c/67/bb6024de76e7186611ebe626aec5b71a2d2ecf9453e795f2dbd80614784c/yarl-1.22.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:5dbeefd6ca588b33576a01b0ad58aa934bc1b41ef89dee505bf2932b22ddffba", size = 335030, upload-time = "2025-10-06T14:12:39.775Z" }, + { url = "https://files.pythonhosted.org/packages/a2/be/50b38447fd94a7992996a62b8b463d0579323fcfc08c61bdba949eef8a5d/yarl-1.22.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:14291620375b1060613f4aab9ebf21850058b6b1b438f386cc814813d901c60b", size = 358560, upload-time = "2025-10-06T14:12:41.547Z" }, + { url = "https://files.pythonhosted.org/packages/e2/89/c020b6f547578c4e3dbb6335bf918f26e2f34ad0d1e515d72fd33ac0c635/yarl-1.22.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:a4fcfc8eb2c34148c118dfa02e6427ca278bfd0f3df7c5f99e33d2c0e81eae3e", size = 357290, upload-time = "2025-10-06T14:12:43.861Z" }, + { url = "https://files.pythonhosted.org/packages/8c/52/c49a619ee35a402fa3a7019a4fa8d26878fec0d1243f6968bbf516789578/yarl-1.22.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:029866bde8d7b0878b9c160e72305bbf0a7342bcd20b9999381704ae03308dc8", size = 350700, upload-time = "2025-10-06T14:12:46.868Z" }, + { url = "https://files.pythonhosted.org/packages/ab/c9/f5042d87777bf6968435f04a2bbb15466b2f142e6e47fa4f34d1a3f32f0c/yarl-1.22.0-cp39-cp39-win32.whl", hash = "sha256:4dcc74149ccc8bba31ce1944acee24813e93cfdee2acda3c172df844948ddf7b", size = 82323, upload-time = "2025-10-06T14:12:48.633Z" }, + { url = "https://files.pythonhosted.org/packages/fd/58/d00f7cad9eba20c4eefac2682f34661d1d1b3a942fc0092eb60e78cfb733/yarl-1.22.0-cp39-cp39-win_amd64.whl", hash = "sha256:10619d9fdee46d20edc49d3479e2f8269d0779f1b031e6f7c2aa1c76be04b7ed", size = 87145, upload-time = "2025-10-06T14:12:50.241Z" }, + { url = "https://files.pythonhosted.org/packages/c2/a3/70904f365080780d38b919edd42d224b8c4ce224a86950d2eaa2a24366ad/yarl-1.22.0-cp39-cp39-win_arm64.whl", hash = "sha256:dd7afd3f8b0bfb4e0d9fc3c31bfe8a4ec7debe124cfd90619305def3c8ca8cd2", size = 82173, upload-time = "2025-10-06T14:12:51.869Z" }, + { url = "https://files.pythonhosted.org/packages/73/ae/b48f95715333080afb75a4504487cbe142cae1268afc482d06692d605ae6/yarl-1.22.0-py3-none-any.whl", hash = "sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff", size = 46814, upload-time = "2025-10-06T14:12:53.872Z" }, +] + +[[package]] +name = "yarl" +version = "1.23.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14' and extra != 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and python_full_version < '3.14' and extra != 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and extra == 'group-10-cloudflare-pydantic-v1' and extra != 'group-10-cloudflare-pydantic-v2'", + "python_full_version >= '3.10' and extra != 'group-10-cloudflare-pydantic-v1' and extra != 'group-10-cloudflare-pydantic-v2'", +] +dependencies = [ + { name = "idna", marker = "python_full_version >= '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "multidict", marker = "python_full_version >= '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, + { name = "propcache", marker = "python_full_version >= '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/23/6e/beb1beec874a72f23815c1434518bfc4ed2175065173fb138c3705f658d4/yarl-1.23.0.tar.gz", hash = "sha256:53b1ea6ca88ebd4420379c330aea57e258408dd0df9af0992e5de2078dc9f5d5", size = 194676, upload-time = "2026-03-01T22:07:53.373Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8b/0d/9cc638702f6fc3c7a3685bcc8cf2a9ed7d6206e932a49f5242658047ef51/yarl-1.23.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cff6d44cb13d39db2663a22b22305d10855efa0fa8015ddeacc40bc59b9d8107", size = 123764, upload-time = "2026-03-01T22:04:09.7Z" }, + { url = "https://files.pythonhosted.org/packages/7a/35/5a553687c5793df5429cd1db45909d4f3af7eee90014888c208d086a44f0/yarl-1.23.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e4c53f8347cd4200f0d70a48ad059cabaf24f5adc6ba08622a23423bc7efa10d", size = 86282, upload-time = "2026-03-01T22:04:11.892Z" }, + { url = "https://files.pythonhosted.org/packages/68/2e/c5a2234238f8ce37a8312b52801ee74117f576b1539eec8404a480434acc/yarl-1.23.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a6940a074fb3c48356ed0158a3ca5699c955ee4185b4d7d619be3c327143e05", size = 86053, upload-time = "2026-03-01T22:04:13.292Z" }, + { url = "https://files.pythonhosted.org/packages/74/3f/bbd8ff36fb038622797ffbaf7db314918bb4d76f1cc8a4f9ca7a55fe5195/yarl-1.23.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ed5f69ce7be7902e5c70ea19eb72d20abf7d725ab5d49777d696e32d4fc1811d", size = 99395, upload-time = "2026-03-01T22:04:15.133Z" }, + { url = "https://files.pythonhosted.org/packages/77/04/9516bc4e269d2a3ec9c6779fcdeac51ce5b3a9b0156f06ac7152e5bba864/yarl-1.23.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:389871e65468400d6283c0308e791a640b5ab5c83bcee02a2f51295f95e09748", size = 92143, upload-time = "2026-03-01T22:04:16.829Z" }, + { url = "https://files.pythonhosted.org/packages/c7/63/88802d1f6b1cb1fc67d67a58cd0cf8a1790de4ce7946e434240f1d60ab4a/yarl-1.23.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:dda608c88cf709b1d406bdfcd84d8d63cff7c9e577a403c6108ce8ce9dcc8764", size = 107643, upload-time = "2026-03-01T22:04:18.519Z" }, + { url = "https://files.pythonhosted.org/packages/8e/db/4f9b838f4d8bdd6f0f385aed8bbf21c71ed11a0b9983305c302cbd557815/yarl-1.23.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8c4fe09e0780c6c3bf2b7d4af02ee2394439d11a523bbcf095cf4747c2932007", size = 108700, upload-time = "2026-03-01T22:04:20.373Z" }, + { url = "https://files.pythonhosted.org/packages/50/12/95a1d33f04a79c402664070d43b8b9f72dc18914e135b345b611b0b1f8cc/yarl-1.23.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:31c9921eb8bd12633b41ad27686bbb0b1a2a9b8452bfdf221e34f311e9942ed4", size = 102769, upload-time = "2026-03-01T22:04:23.055Z" }, + { url = "https://files.pythonhosted.org/packages/86/65/91a0285f51321369fd1a8308aa19207520c5f0587772cfc2e03fc2467e90/yarl-1.23.0-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5f10fd85e4b75967468af655228fbfd212bdf66db1c0d135065ce288982eda26", size = 101114, upload-time = "2026-03-01T22:04:25.031Z" }, + { url = "https://files.pythonhosted.org/packages/58/80/c7c8244fc3e5bc483dc71a09560f43b619fab29301a0f0a8f936e42865c7/yarl-1.23.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:dbf507e9ef5688bada447a24d68b4b58dd389ba93b7afc065a2ba892bea54769", size = 98883, upload-time = "2026-03-01T22:04:27.281Z" }, + { url = "https://files.pythonhosted.org/packages/86/e7/71ca9cc9ca79c0b7d491216177d1aed559d632947b8ffb0ee60f7d8b23e3/yarl-1.23.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:85e9beda1f591bc73e77ea1c51965c68e98dafd0fec72cdd745f77d727466716", size = 94172, upload-time = "2026-03-01T22:04:28.554Z" }, + { url = "https://files.pythonhosted.org/packages/6a/3f/6c6c8a0fe29c26fb2db2e8d32195bb84ec1bfb8f1d32e7f73b787fcf349b/yarl-1.23.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:0e1fdaa14ef51366d7757b45bde294e95f6c8c049194e793eedb8387c86d5993", size = 107010, upload-time = "2026-03-01T22:04:30.385Z" }, + { url = "https://files.pythonhosted.org/packages/56/38/12730c05e5ad40a76374d440ed8b0899729a96c250516d91c620a6e38fc2/yarl-1.23.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:75e3026ab649bf48f9a10c0134512638725b521340293f202a69b567518d94e0", size = 100285, upload-time = "2026-03-01T22:04:31.752Z" }, + { url = "https://files.pythonhosted.org/packages/34/92/6a7be9239f2347234e027284e7a5f74b1140cc86575e7b469d13fba1ebfe/yarl-1.23.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:80e6d33a3d42a7549b409f199857b4fb54e2103fc44fb87605b6663b7a7ff750", size = 108230, upload-time = "2026-03-01T22:04:33.844Z" }, + { url = "https://files.pythonhosted.org/packages/5e/81/4aebccfa9376bd98b9d8bfad20621a57d3e8cfc5b8631c1fa5f62cdd03f4/yarl-1.23.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5ec2f42d41ccbd5df0270d7df31618a8ee267bfa50997f5d720ddba86c4a83a6", size = 103008, upload-time = "2026-03-01T22:04:35.856Z" }, + { url = "https://files.pythonhosted.org/packages/38/0f/0b4e3edcec794a86b853b0c6396c0a888d72dfce19b2d88c02ac289fb6c1/yarl-1.23.0-cp310-cp310-win32.whl", hash = "sha256:debe9c4f41c32990771be5c22b56f810659f9ddf3d63f67abfdcaa2c6c9c5c1d", size = 83073, upload-time = "2026-03-01T22:04:38.268Z" }, + { url = "https://files.pythonhosted.org/packages/a0/71/ad95c33da18897e4c636528bbc24a1dd23fe16797de8bc4ec667b8db0ba4/yarl-1.23.0-cp310-cp310-win_amd64.whl", hash = "sha256:ab5f043cb8a2d71c981c09c510da013bc79fd661f5c60139f00dd3c3cc4f2ffb", size = 87328, upload-time = "2026-03-01T22:04:39.558Z" }, + { url = "https://files.pythonhosted.org/packages/e2/14/dfa369523c79bccf9c9c746b0a63eb31f65db9418ac01275f7950962e504/yarl-1.23.0-cp310-cp310-win_arm64.whl", hash = "sha256:263cd4f47159c09b8b685890af949195b51d1aa82ba451c5847ca9bc6413c220", size = 82463, upload-time = "2026-03-01T22:04:41.454Z" }, + { url = "https://files.pythonhosted.org/packages/a2/aa/60da938b8f0997ba3a911263c40d82b6f645a67902a490b46f3355e10fae/yarl-1.23.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b35d13d549077713e4414f927cdc388d62e543987c572baee613bf82f11a4b99", size = 123641, upload-time = "2026-03-01T22:04:42.841Z" }, + { url = "https://files.pythonhosted.org/packages/24/84/e237607faf4e099dbb8a4f511cfd5efcb5f75918baad200ff7380635631b/yarl-1.23.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cbb0fef01f0c6b38cb0f39b1f78fc90b807e0e3c86a7ff3ce74ad77ce5c7880c", size = 86248, upload-time = "2026-03-01T22:04:44.757Z" }, + { url = "https://files.pythonhosted.org/packages/b2/0d/71ceabc14c146ba8ee3804ca7b3d42b1664c8440439de5214d366fec7d3a/yarl-1.23.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dc52310451fc7c629e13c4e061cbe2dd01684d91f2f8ee2821b083c58bd72432", size = 85988, upload-time = "2026-03-01T22:04:46.365Z" }, + { url = "https://files.pythonhosted.org/packages/8c/6c/4a90d59c572e46b270ca132aca66954f1175abd691f74c1ef4c6711828e2/yarl-1.23.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b2c6b50c7b0464165472b56b42d4c76a7b864597007d9c085e8b63e185cf4a7a", size = 100566, upload-time = "2026-03-01T22:04:47.639Z" }, + { url = "https://files.pythonhosted.org/packages/49/fb/c438fb5108047e629f6282a371e6e91cf3f97ee087c4fb748a1f32ceef55/yarl-1.23.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:aafe5dcfda86c8af00386d7781d4c2181b5011b7be3f2add5e99899ea925df05", size = 92079, upload-time = "2026-03-01T22:04:48.925Z" }, + { url = "https://files.pythonhosted.org/packages/d9/13/d269aa1aed3e4f50a5a103f96327210cc5fa5dd2d50882778f13c7a14606/yarl-1.23.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9ee33b875f0b390564c1fb7bc528abf18c8ee6073b201c6ae8524aca778e2d83", size = 108741, upload-time = "2026-03-01T22:04:50.838Z" }, + { url = "https://files.pythonhosted.org/packages/85/fb/115b16f22c37ea4437d323e472945bea97301c8ec6089868fa560abab590/yarl-1.23.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4c41e021bc6d7affb3364dc1e1e5fa9582b470f283748784bd6ea0558f87f42c", size = 108099, upload-time = "2026-03-01T22:04:52.499Z" }, + { url = "https://files.pythonhosted.org/packages/9a/64/c53487d9f4968045b8afa51aed7ca44f58b2589e772f32745f3744476c82/yarl-1.23.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:99c8a9ed30f4164bc4c14b37a90208836cbf50d4ce2a57c71d0f52c7fb4f7598", size = 102678, upload-time = "2026-03-01T22:04:55.176Z" }, + { url = "https://files.pythonhosted.org/packages/85/59/cd98e556fbb2bf8fab29c1a722f67ad45c5f3447cac798ab85620d1e70af/yarl-1.23.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f2af5c81a1f124609d5f33507082fc3f739959d4719b56877ab1ee7e7b3d602b", size = 100803, upload-time = "2026-03-01T22:04:56.588Z" }, + { url = "https://files.pythonhosted.org/packages/9e/c0/b39770b56d4a9f0bb5f77e2f1763cd2d75cc2f6c0131e3b4c360348fcd65/yarl-1.23.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6b41389c19b07c760c7e427a3462e8ab83c4bb087d127f0e854c706ce1b9215c", size = 100163, upload-time = "2026-03-01T22:04:58.492Z" }, + { url = "https://files.pythonhosted.org/packages/e7/64/6980f99ab00e1f0ff67cb84766c93d595b067eed07439cfccfc8fb28c1a6/yarl-1.23.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:1dc702e42d0684f42d6519c8d581e49c96cefaaab16691f03566d30658ee8788", size = 93859, upload-time = "2026-03-01T22:05:00.268Z" }, + { url = "https://files.pythonhosted.org/packages/38/69/912e6c5e146793e5d4b5fe39ff5b00f4d22463dfd5a162bec565ac757673/yarl-1.23.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:0e40111274f340d32ebcc0a5668d54d2b552a6cca84c9475859d364b380e3222", size = 108202, upload-time = "2026-03-01T22:05:02.273Z" }, + { url = "https://files.pythonhosted.org/packages/59/97/35ca6767524687ad64e5f5c31ad54bc76d585585a9fcb40f649e7e82ffed/yarl-1.23.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:4764a6a7588561a9aef92f65bda2c4fb58fe7c675c0883862e6df97559de0bfb", size = 99866, upload-time = "2026-03-01T22:05:03.597Z" }, + { url = "https://files.pythonhosted.org/packages/d3/1c/1a3387ee6d73589f6f2a220ae06f2984f6c20b40c734989b0a44f5987308/yarl-1.23.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:03214408cfa590df47728b84c679ae4ef00be2428e11630277be0727eba2d7cc", size = 107852, upload-time = "2026-03-01T22:05:04.986Z" }, + { url = "https://files.pythonhosted.org/packages/a4/b8/35c0750fcd5a3f781058bfd954515dd4b1eab45e218cbb85cf11132215f1/yarl-1.23.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:170e26584b060879e29fac213e4228ef063f39128723807a312e5c7fec28eff2", size = 102919, upload-time = "2026-03-01T22:05:06.397Z" }, + { url = "https://files.pythonhosted.org/packages/e5/1c/9a1979aec4a81896d597bcb2177827f2dbee3f5b7cc48b2d0dadb644b41d/yarl-1.23.0-cp311-cp311-win32.whl", hash = "sha256:51430653db848d258336cfa0244427b17d12db63d42603a55f0d4546f50f25b5", size = 82602, upload-time = "2026-03-01T22:05:08.444Z" }, + { url = "https://files.pythonhosted.org/packages/93/22/b85eca6fa2ad9491af48c973e4c8cf6b103a73dbb271fe3346949449fca0/yarl-1.23.0-cp311-cp311-win_amd64.whl", hash = "sha256:bf49a3ae946a87083ef3a34c8f677ae4243f5b824bfc4c69672e72b3d6719d46", size = 87461, upload-time = "2026-03-01T22:05:10.145Z" }, + { url = "https://files.pythonhosted.org/packages/93/95/07e3553fe6f113e6864a20bdc53a78113cda3b9ced8784ee52a52c9f80d8/yarl-1.23.0-cp311-cp311-win_arm64.whl", hash = "sha256:b39cb32a6582750b6cc77bfb3c49c0f8760dc18dc96ec9fb55fbb0f04e08b928", size = 82336, upload-time = "2026-03-01T22:05:11.554Z" }, + { url = "https://files.pythonhosted.org/packages/88/8a/94615bc31022f711add374097ad4144d569e95ff3c38d39215d07ac153a0/yarl-1.23.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1932b6b8bba8d0160a9d1078aae5838a66039e8832d41d2992daa9a3a08f7860", size = 124737, upload-time = "2026-03-01T22:05:12.897Z" }, + { url = "https://files.pythonhosted.org/packages/e3/6f/c6554045d59d64052698add01226bc867b52fe4a12373415d7991fdca95d/yarl-1.23.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:411225bae281f114067578891bc75534cfb3d92a3b4dfef7a6ca78ba354e6069", size = 87029, upload-time = "2026-03-01T22:05:14.376Z" }, + { url = "https://files.pythonhosted.org/packages/19/2a/725ecc166d53438bc88f76822ed4b1e3b10756e790bafd7b523fe97c322d/yarl-1.23.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:13a563739ae600a631c36ce096615fe307f131344588b0bc0daec108cdb47b25", size = 86310, upload-time = "2026-03-01T22:05:15.71Z" }, + { url = "https://files.pythonhosted.org/packages/99/30/58260ed98e6ff7f90ba84442c1ddd758c9170d70327394a6227b310cd60f/yarl-1.23.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cbf44c5cb4a7633d078788e1b56387e3d3cf2b8139a3be38040b22d6c3221c8", size = 97587, upload-time = "2026-03-01T22:05:17.384Z" }, + { url = "https://files.pythonhosted.org/packages/76/0a/8b08aac08b50682e65759f7f8dde98ae8168f72487e7357a5d684c581ef9/yarl-1.23.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53ad387048f6f09a8969631e4de3f1bf70c50e93545d64af4f751b2498755072", size = 92528, upload-time = "2026-03-01T22:05:18.804Z" }, + { url = "https://files.pythonhosted.org/packages/52/07/0b7179101fe5f8385ec6c6bb5d0cb9f76bd9fb4a769591ab6fb5cdbfc69a/yarl-1.23.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4a59ba56f340334766f3a4442e0efd0af895fae9e2b204741ef885c446b3a1a8", size = 105339, upload-time = "2026-03-01T22:05:20.235Z" }, + { url = "https://files.pythonhosted.org/packages/d3/8a/36d82869ab5ec829ca8574dfcb92b51286fcfb1e9c7a73659616362dc880/yarl-1.23.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:803a3c3ce4acc62eaf01eaca1208dcf0783025ef27572c3336502b9c232005e7", size = 105061, upload-time = "2026-03-01T22:05:22.268Z" }, + { url = "https://files.pythonhosted.org/packages/66/3e/868e5c3364b6cee19ff3e1a122194fa4ce51def02c61023970442162859e/yarl-1.23.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3d2bff8f37f8d0f96c7ec554d16945050d54462d6e95414babaa18bfafc7f51", size = 100132, upload-time = "2026-03-01T22:05:23.638Z" }, + { url = "https://files.pythonhosted.org/packages/cf/26/9c89acf82f08a52cb52d6d39454f8d18af15f9d386a23795389d1d423823/yarl-1.23.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c75eb09e8d55bceb4367e83496ff8ef2bc7ea6960efb38e978e8073ea59ecb67", size = 99289, upload-time = "2026-03-01T22:05:25.749Z" }, + { url = "https://files.pythonhosted.org/packages/6f/54/5b0db00d2cb056922356104468019c0a132e89c8d3ab67d8ede9f4483d2a/yarl-1.23.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877b0738624280e34c55680d6054a307aa94f7d52fa0e3034a9cc6e790871da7", size = 96950, upload-time = "2026-03-01T22:05:27.318Z" }, + { url = "https://files.pythonhosted.org/packages/f6/40/10fa93811fd439341fad7e0718a86aca0de9548023bbb403668d6555acab/yarl-1.23.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:b5405bb8f0e783a988172993cfc627e4d9d00432d6bbac65a923041edacf997d", size = 93960, upload-time = "2026-03-01T22:05:28.738Z" }, + { url = "https://files.pythonhosted.org/packages/bc/d2/8ae2e6cd77d0805f4526e30ec43b6f9a3dfc542d401ac4990d178e4bf0cf/yarl-1.23.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1c3a3598a832590c5a3ce56ab5576361b5688c12cb1d39429cf5dba30b510760", size = 104703, upload-time = "2026-03-01T22:05:30.438Z" }, + { url = "https://files.pythonhosted.org/packages/2f/0c/b3ceacf82c3fe21183ce35fa2acf5320af003d52bc1fcf5915077681142e/yarl-1.23.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:8419ebd326430d1cbb7efb5292330a2cf39114e82df5cc3d83c9a0d5ebeaf2f2", size = 98325, upload-time = "2026-03-01T22:05:31.835Z" }, + { url = "https://files.pythonhosted.org/packages/9d/e0/12900edd28bdab91a69bd2554b85ad7b151f64e8b521fe16f9ad2f56477a/yarl-1.23.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:be61f6fff406ca40e3b1d84716fde398fc08bc63dd96d15f3a14230a0973ed86", size = 105067, upload-time = "2026-03-01T22:05:33.358Z" }, + { url = "https://files.pythonhosted.org/packages/15/61/74bb1182cf79c9bbe4eb6b1f14a57a22d7a0be5e9cedf8e2d5c2086474c3/yarl-1.23.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3ceb13c5c858d01321b5d9bb65e4cf37a92169ea470b70fec6f236b2c9dd7e34", size = 100285, upload-time = "2026-03-01T22:05:35.4Z" }, + { url = "https://files.pythonhosted.org/packages/69/7f/cd5ef733f2550de6241bd8bd8c3febc78158b9d75f197d9c7baa113436af/yarl-1.23.0-cp312-cp312-win32.whl", hash = "sha256:fffc45637bcd6538de8b85f51e3df3223e4ad89bccbfca0481c08c7fc8b7ed7d", size = 82359, upload-time = "2026-03-01T22:05:36.811Z" }, + { url = "https://files.pythonhosted.org/packages/f5/be/25216a49daeeb7af2bec0db22d5e7df08ed1d7c9f65d78b14f3b74fd72fc/yarl-1.23.0-cp312-cp312-win_amd64.whl", hash = "sha256:f69f57305656a4852f2a7203efc661d8c042e6cc67f7acd97d8667fb448a426e", size = 87674, upload-time = "2026-03-01T22:05:38.171Z" }, + { url = "https://files.pythonhosted.org/packages/d2/35/aeab955d6c425b227d5b7247eafb24f2653fedc32f95373a001af5dfeb9e/yarl-1.23.0-cp312-cp312-win_arm64.whl", hash = "sha256:6e87a6e8735b44816e7db0b2fbc9686932df473c826b0d9743148432e10bb9b9", size = 81879, upload-time = "2026-03-01T22:05:40.006Z" }, + { url = "https://files.pythonhosted.org/packages/9a/4b/a0a6e5d0ee8a2f3a373ddef8a4097d74ac901ac363eea1440464ccbe0898/yarl-1.23.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:16c6994ac35c3e74fb0ae93323bf8b9c2a9088d55946109489667c510a7d010e", size = 123796, upload-time = "2026-03-01T22:05:41.412Z" }, + { url = "https://files.pythonhosted.org/packages/67/b6/8925d68af039b835ae876db5838e82e76ec87b9782ecc97e192b809c4831/yarl-1.23.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4a42e651629dafb64fd5b0286a3580613702b5809ad3f24934ea87595804f2c5", size = 86547, upload-time = "2026-03-01T22:05:42.841Z" }, + { url = "https://files.pythonhosted.org/packages/ae/50/06d511cc4b8e0360d3c94af051a768e84b755c5eb031b12adaaab6dec6e5/yarl-1.23.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7c6b9461a2a8b47c65eef63bb1c76a4f1c119618ffa99ea79bc5bb1e46c5821b", size = 85854, upload-time = "2026-03-01T22:05:44.85Z" }, + { url = "https://files.pythonhosted.org/packages/c4/f4/4e30b250927ffdab4db70da08b9b8d2194d7c7b400167b8fbeca1e4701ca/yarl-1.23.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2569b67d616eab450d262ca7cb9f9e19d2f718c70a8b88712859359d0ab17035", size = 98351, upload-time = "2026-03-01T22:05:46.836Z" }, + { url = "https://files.pythonhosted.org/packages/86/fc/4118c5671ea948208bdb1492d8b76bdf1453d3e73df051f939f563e7dcc5/yarl-1.23.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e9d9a4d06d3481eab79803beb4d9bd6f6a8e781ec078ac70d7ef2dcc29d1bea5", size = 92711, upload-time = "2026-03-01T22:05:48.316Z" }, + { url = "https://files.pythonhosted.org/packages/56/11/1ed91d42bd9e73c13dc9e7eb0dd92298d75e7ac4dd7f046ad0c472e231cd/yarl-1.23.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f514f6474e04179d3d33175ed3f3e31434d3130d42ec153540d5b157deefd735", size = 106014, upload-time = "2026-03-01T22:05:50.028Z" }, + { url = "https://files.pythonhosted.org/packages/ce/c9/74e44e056a23fbc33aca71779ef450ca648a5bc472bdad7a82339918f818/yarl-1.23.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fda207c815b253e34f7e1909840fd14299567b1c0eb4908f8c2ce01a41265401", size = 105557, upload-time = "2026-03-01T22:05:51.416Z" }, + { url = "https://files.pythonhosted.org/packages/66/fe/b1e10b08d287f518994f1e2ff9b6d26f0adeecd8dd7d533b01bab29a3eda/yarl-1.23.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34b6cf500e61c90f305094911f9acc9c86da1a05a7a3f5be9f68817043f486e4", size = 101559, upload-time = "2026-03-01T22:05:52.872Z" }, + { url = "https://files.pythonhosted.org/packages/72/59/c5b8d94b14e3d3c2a9c20cb100119fd534ab5a14b93673ab4cc4a4141ea5/yarl-1.23.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d7504f2b476d21653e4d143f44a175f7f751cd41233525312696c76aa3dbb23f", size = 100502, upload-time = "2026-03-01T22:05:54.954Z" }, + { url = "https://files.pythonhosted.org/packages/77/4f/96976cb54cbfc5c9fd73ed4c51804f92f209481d1fb190981c0f8a07a1d7/yarl-1.23.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:578110dd426f0d209d1509244e6d4a3f1a3e9077655d98c5f22583d63252a08a", size = 98027, upload-time = "2026-03-01T22:05:56.409Z" }, + { url = "https://files.pythonhosted.org/packages/63/6e/904c4f476471afdbad6b7e5b70362fb5810e35cd7466529a97322b6f5556/yarl-1.23.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:609d3614d78d74ebe35f54953c5bbd2ac647a7ddb9c30a5d877580f5e86b22f2", size = 95369, upload-time = "2026-03-01T22:05:58.141Z" }, + { url = "https://files.pythonhosted.org/packages/9d/40/acfcdb3b5f9d68ef499e39e04d25e141fe90661f9d54114556cf83be8353/yarl-1.23.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4966242ec68afc74c122f8459abd597afd7d8a60dc93d695c1334c5fd25f762f", size = 105565, upload-time = "2026-03-01T22:06:00.286Z" }, + { url = "https://files.pythonhosted.org/packages/5e/c6/31e28f3a6ba2869c43d124f37ea5260cac9c9281df803c354b31f4dd1f3c/yarl-1.23.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e0fd068364a6759bc794459f0a735ab151d11304346332489c7972bacbe9e72b", size = 99813, upload-time = "2026-03-01T22:06:01.712Z" }, + { url = "https://files.pythonhosted.org/packages/08/1f/6f65f59e72d54aa467119b63fc0b0b1762eff0232db1f4720cd89e2f4a17/yarl-1.23.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:39004f0ad156da43e86aa71f44e033de68a44e5a31fc53507b36dd253970054a", size = 105632, upload-time = "2026-03-01T22:06:03.188Z" }, + { url = "https://files.pythonhosted.org/packages/a3/c4/18b178a69935f9e7a338127d5b77d868fdc0f0e49becd286d51b3a18c61d/yarl-1.23.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e5723c01a56c5028c807c701aa66722916d2747ad737a046853f6c46f4875543", size = 101895, upload-time = "2026-03-01T22:06:04.651Z" }, + { url = "https://files.pythonhosted.org/packages/8f/54/f5b870b5505663911dba950a8e4776a0dbd51c9c54c0ae88e823e4b874a0/yarl-1.23.0-cp313-cp313-win32.whl", hash = "sha256:1b6b572edd95b4fa8df75de10b04bc81acc87c1c7d16bcdd2035b09d30acc957", size = 82356, upload-time = "2026-03-01T22:06:06.04Z" }, + { url = "https://files.pythonhosted.org/packages/7a/84/266e8da36879c6edcd37b02b547e2d9ecdfea776be49598e75696e3316e1/yarl-1.23.0-cp313-cp313-win_amd64.whl", hash = "sha256:baaf55442359053c7d62f6f8413a62adba3205119bcb6f49594894d8be47e5e3", size = 87515, upload-time = "2026-03-01T22:06:08.107Z" }, + { url = "https://files.pythonhosted.org/packages/00/fd/7e1c66efad35e1649114fa13f17485f62881ad58edeeb7f49f8c5e748bf9/yarl-1.23.0-cp313-cp313-win_arm64.whl", hash = "sha256:fb4948814a2a98e3912505f09c9e7493b1506226afb1f881825368d6fb776ee3", size = 81785, upload-time = "2026-03-01T22:06:10.181Z" }, + { url = "https://files.pythonhosted.org/packages/9c/fc/119dd07004f17ea43bb91e3ece6587759edd7519d6b086d16bfbd3319982/yarl-1.23.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:aecfed0b41aa72b7881712c65cf764e39ce2ec352324f5e0837c7048d9e6daaa", size = 130719, upload-time = "2026-03-01T22:06:11.708Z" }, + { url = "https://files.pythonhosted.org/packages/e6/0d/9f2348502fbb3af409e8f47730282cd6bc80dec6630c1e06374d882d6eb2/yarl-1.23.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a41bcf68efd19073376eb8cf948b8d9be0af26256403e512bb18f3966f1f9120", size = 89690, upload-time = "2026-03-01T22:06:13.429Z" }, + { url = "https://files.pythonhosted.org/packages/50/93/e88f3c80971b42cfc83f50a51b9d165a1dbf154b97005f2994a79f212a07/yarl-1.23.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cde9a2ecd91668bcb7f077c4966d8ceddb60af01b52e6e3e2680e4cf00ad1a59", size = 89851, upload-time = "2026-03-01T22:06:15.53Z" }, + { url = "https://files.pythonhosted.org/packages/1c/07/61c9dd8ba8f86473263b4036f70fb594c09e99c0d9737a799dfd8bc85651/yarl-1.23.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5023346c4ee7992febc0068e7593de5fa2bf611848c08404b35ebbb76b1b0512", size = 95874, upload-time = "2026-03-01T22:06:17.553Z" }, + { url = "https://files.pythonhosted.org/packages/9e/e9/f9ff8ceefba599eac6abddcfb0b3bee9b9e636e96dbf54342a8577252379/yarl-1.23.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d1009abedb49ae95b136a8904a3f71b342f849ffeced2d3747bf29caeda218c4", size = 88710, upload-time = "2026-03-01T22:06:19.004Z" }, + { url = "https://files.pythonhosted.org/packages/eb/78/0231bfcc5d4c8eec220bc2f9ef82cb4566192ea867a7c5b4148f44f6cbcd/yarl-1.23.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a8d00f29b42f534cc8aa3931cfe773b13b23e561e10d2b26f27a8d309b0e82a1", size = 101033, upload-time = "2026-03-01T22:06:21.203Z" }, + { url = "https://files.pythonhosted.org/packages/cd/9b/30ea5239a61786f18fd25797151a17fbb3be176977187a48d541b5447dd4/yarl-1.23.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:95451e6ce06c3e104556d73b559f5da6c34a069b6b62946d3ad66afcd51642ea", size = 100817, upload-time = "2026-03-01T22:06:22.738Z" }, + { url = "https://files.pythonhosted.org/packages/62/e2/a4980481071791bc83bce2b7a1a1f7adcabfa366007518b4b845e92eeee3/yarl-1.23.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:531ef597132086b6cf96faa7c6c1dcd0361dd5f1694e5cc30375907b9b7d3ea9", size = 97482, upload-time = "2026-03-01T22:06:24.21Z" }, + { url = "https://files.pythonhosted.org/packages/e5/1e/304a00cf5f6100414c4b5a01fc7ff9ee724b62158a08df2f8170dfc72a2d/yarl-1.23.0-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:88f9fb0116fbfcefcab70f85cf4b74a2b6ce5d199c41345296f49d974ddb4123", size = 95949, upload-time = "2026-03-01T22:06:25.697Z" }, + { url = "https://files.pythonhosted.org/packages/68/03/093f4055ed4cae649ac53bca3d180bd37102e9e11d048588e9ab0c0108d0/yarl-1.23.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:e7b0460976dc75cb87ad9cc1f9899a4b97751e7d4e77ab840fc9b6d377b8fd24", size = 95839, upload-time = "2026-03-01T22:06:27.309Z" }, + { url = "https://files.pythonhosted.org/packages/b9/28/4c75ebb108f322aa8f917ae10a8ffa4f07cae10a8a627b64e578617df6a0/yarl-1.23.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:115136c4a426f9da976187d238e84139ff6b51a20839aa6e3720cd1026d768de", size = 90696, upload-time = "2026-03-01T22:06:29.048Z" }, + { url = "https://files.pythonhosted.org/packages/23/9c/42c2e2dd91c1a570402f51bdf066bfdb1241c2240ba001967bad778e77b7/yarl-1.23.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:ead11956716a940c1abc816b7df3fa2b84d06eaed8832ca32f5c5e058c65506b", size = 100865, upload-time = "2026-03-01T22:06:30.525Z" }, + { url = "https://files.pythonhosted.org/packages/74/05/1bcd60a8a0a914d462c305137246b6f9d167628d73568505fce3f1cb2e65/yarl-1.23.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:fe8f8f5e70e6dbdfca9882cd9deaac058729bcf323cf7a58660901e55c9c94f6", size = 96234, upload-time = "2026-03-01T22:06:32.692Z" }, + { url = "https://files.pythonhosted.org/packages/90/b2/f52381aac396d6778ce516b7bc149c79e65bfc068b5de2857ab69eeea3b7/yarl-1.23.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:a0e317df055958a0c1e79e5d2aa5a5eaa4a6d05a20d4b0c9c3f48918139c9fc6", size = 100295, upload-time = "2026-03-01T22:06:34.268Z" }, + { url = "https://files.pythonhosted.org/packages/e5/e8/638bae5bbf1113a659b2435d8895474598afe38b4a837103764f603aba56/yarl-1.23.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f0fd84de0c957b2d280143522c4f91a73aada1923caee763e24a2b3fda9f8a5", size = 97784, upload-time = "2026-03-01T22:06:35.864Z" }, + { url = "https://files.pythonhosted.org/packages/80/25/a3892b46182c586c202629fc2159aa13975d3741d52ebd7347fd501d48d5/yarl-1.23.0-cp313-cp313t-win32.whl", hash = "sha256:93a784271881035ab4406a172edb0faecb6e7d00f4b53dc2f55919d6c9688595", size = 88313, upload-time = "2026-03-01T22:06:37.39Z" }, + { url = "https://files.pythonhosted.org/packages/43/68/8c5b36aa5178900b37387937bc2c2fe0e9505537f713495472dcf6f6fccc/yarl-1.23.0-cp313-cp313t-win_amd64.whl", hash = "sha256:dd00607bffbf30250fe108065f07453ec124dbf223420f57f5e749b04295e090", size = 94932, upload-time = "2026-03-01T22:06:39.579Z" }, + { url = "https://files.pythonhosted.org/packages/c6/cc/d79ba8292f51f81f4dc533a8ccfb9fc6992cabf0998ed3245de7589dc07c/yarl-1.23.0-cp313-cp313t-win_arm64.whl", hash = "sha256:ac09d42f48f80c9ee1635b2fcaa819496a44502737660d3c0f2ade7526d29144", size = 84786, upload-time = "2026-03-01T22:06:41.988Z" }, + { url = "https://files.pythonhosted.org/packages/90/98/b85a038d65d1b92c3903ab89444f48d3cee490a883477b716d7a24b1a78c/yarl-1.23.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:21d1b7305a71a15b4794b5ff22e8eef96ff4a6d7f9657155e5aa419444b28912", size = 124455, upload-time = "2026-03-01T22:06:43.615Z" }, + { url = "https://files.pythonhosted.org/packages/39/54/bc2b45559f86543d163b6e294417a107bb87557609007c007ad889afec18/yarl-1.23.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:85610b4f27f69984932a7abbe52703688de3724d9f72bceb1cca667deff27474", size = 86752, upload-time = "2026-03-01T22:06:45.425Z" }, + { url = "https://files.pythonhosted.org/packages/24/f9/e8242b68362bffe6fb536c8db5076861466fc780f0f1b479fc4ffbebb128/yarl-1.23.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23f371bd662cf44a7630d4d113101eafc0cfa7518a2760d20760b26021454719", size = 86291, upload-time = "2026-03-01T22:06:46.974Z" }, + { url = "https://files.pythonhosted.org/packages/ea/d8/d1cb2378c81dd729e98c716582b1ccb08357e8488e4c24714658cc6630e8/yarl-1.23.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4a80f77dc1acaaa61f0934176fccca7096d9b1ff08c8ba9cddf5ae034a24319", size = 99026, upload-time = "2026-03-01T22:06:48.459Z" }, + { url = "https://files.pythonhosted.org/packages/0a/ff/7196790538f31debe3341283b5b0707e7feb947620fc5e8236ef28d44f72/yarl-1.23.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:bd654fad46d8d9e823afbb4f87c79160b5a374ed1ff5bde24e542e6ba8f41434", size = 92355, upload-time = "2026-03-01T22:06:50.306Z" }, + { url = "https://files.pythonhosted.org/packages/c1/56/25d58c3eddde825890a5fe6aa1866228377354a3c39262235234ab5f616b/yarl-1.23.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:682bae25f0a0dd23a056739f23a134db9f52a63e2afd6bfb37ddc76292bbd723", size = 106417, upload-time = "2026-03-01T22:06:52.1Z" }, + { url = "https://files.pythonhosted.org/packages/51/8a/882c0e7bc8277eb895b31bce0138f51a1ba551fc2e1ec6753ffc1e7c1377/yarl-1.23.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a82836cab5f197a0514235aaf7ffccdc886ccdaa2324bc0aafdd4ae898103039", size = 106422, upload-time = "2026-03-01T22:06:54.424Z" }, + { url = "https://files.pythonhosted.org/packages/42/2b/fef67d616931055bf3d6764885990a3ac647d68734a2d6a9e1d13de437a2/yarl-1.23.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c57676bdedc94cd3bc37724cf6f8cd2779f02f6aba48de45feca073e714fe52", size = 101915, upload-time = "2026-03-01T22:06:55.895Z" }, + { url = "https://files.pythonhosted.org/packages/18/6a/530e16aebce27c5937920f3431c628a29a4b6b430fab3fd1c117b26ff3f6/yarl-1.23.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c7f8dc16c498ff06497c015642333219871effba93e4a2e8604a06264aca5c5c", size = 100690, upload-time = "2026-03-01T22:06:58.21Z" }, + { url = "https://files.pythonhosted.org/packages/88/08/93749219179a45e27b036e03260fda05190b911de8e18225c294ac95bbc9/yarl-1.23.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:5ee586fb17ff8f90c91cf73c6108a434b02d69925f44f5f8e0d7f2f260607eae", size = 98750, upload-time = "2026-03-01T22:06:59.794Z" }, + { url = "https://files.pythonhosted.org/packages/d9/cf/ea424a004969f5d81a362110a6ac1496d79efdc6d50c2c4b2e3ea0fc2519/yarl-1.23.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:17235362f580149742739cc3828b80e24029d08cbb9c4bda0242c7b5bc610a8e", size = 94685, upload-time = "2026-03-01T22:07:01.375Z" }, + { url = "https://files.pythonhosted.org/packages/e2/b7/14341481fe568e2b0408bcf1484c652accafe06a0ade9387b5d3fd9df446/yarl-1.23.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:0793e2bd0cf14234983bbb371591e6bea9e876ddf6896cdcc93450996b0b5c85", size = 106009, upload-time = "2026-03-01T22:07:03.151Z" }, + { url = "https://files.pythonhosted.org/packages/0a/e6/5c744a9b54f4e8007ad35bce96fbc9218338e84812d36f3390cea616881a/yarl-1.23.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3650dc2480f94f7116c364096bc84b1d602f44224ef7d5c7208425915c0475dd", size = 100033, upload-time = "2026-03-01T22:07:04.701Z" }, + { url = "https://files.pythonhosted.org/packages/0c/23/e3bfc188d0b400f025bc49d99793d02c9abe15752138dcc27e4eaf0c4a9e/yarl-1.23.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f40e782d49630ad384db66d4d8b73ff4f1b8955dc12e26b09a3e3af064b3b9d6", size = 106483, upload-time = "2026-03-01T22:07:06.231Z" }, + { url = "https://files.pythonhosted.org/packages/72/42/f0505f949a90b3f8b7a363d6cbdf398f6e6c58946d85c6d3a3bc70595b26/yarl-1.23.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:94f8575fbdf81749008d980c17796097e645574a3b8c28ee313931068dad14fe", size = 102175, upload-time = "2026-03-01T22:07:08.4Z" }, + { url = "https://files.pythonhosted.org/packages/aa/65/b39290f1d892a9dd671d1c722014ca062a9c35d60885d57e5375db0404b5/yarl-1.23.0-cp314-cp314-win32.whl", hash = "sha256:c8aa34a5c864db1087d911a0b902d60d203ea3607d91f615acd3f3108ac32169", size = 83871, upload-time = "2026-03-01T22:07:09.968Z" }, + { url = "https://files.pythonhosted.org/packages/a9/5b/9b92f54c784c26e2a422e55a8d2607ab15b7ea3349e28359282f84f01d43/yarl-1.23.0-cp314-cp314-win_amd64.whl", hash = "sha256:63e92247f383c85ab00dd0091e8c3fa331a96e865459f5ee80353c70a4a42d70", size = 89093, upload-time = "2026-03-01T22:07:11.501Z" }, + { url = "https://files.pythonhosted.org/packages/e0/7d/8a84dc9381fd4412d5e7ff04926f9865f6372b4c2fd91e10092e65d29eb8/yarl-1.23.0-cp314-cp314-win_arm64.whl", hash = "sha256:70efd20be968c76ece7baa8dafe04c5be06abc57f754d6f36f3741f7aa7a208e", size = 83384, upload-time = "2026-03-01T22:07:13.069Z" }, + { url = "https://files.pythonhosted.org/packages/dd/8d/d2fad34b1c08aa161b74394183daa7d800141aaaee207317e82c790b418d/yarl-1.23.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:9a18d6f9359e45722c064c97464ec883eb0e0366d33eda61cb19a244bf222679", size = 131019, upload-time = "2026-03-01T22:07:14.903Z" }, + { url = "https://files.pythonhosted.org/packages/19/ff/33009a39d3ccf4b94d7d7880dfe17fb5816c5a4fe0096d9b56abceea9ac7/yarl-1.23.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:2803ed8b21ca47a43da80a6fd1ed3019d30061f7061daa35ac54f63933409412", size = 89894, upload-time = "2026-03-01T22:07:17.372Z" }, + { url = "https://files.pythonhosted.org/packages/0c/f1/dab7ac5e7306fb79c0190766a3c00b4cb8d09a1f390ded68c85a5934faf5/yarl-1.23.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:394906945aa8b19fc14a61cf69743a868bb8c465efe85eee687109cc540b98f4", size = 89979, upload-time = "2026-03-01T22:07:19.361Z" }, + { url = "https://files.pythonhosted.org/packages/aa/b1/08e95f3caee1fad6e65017b9f26c1d79877b502622d60e517de01e72f95d/yarl-1.23.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:71d006bee8397a4a89f469b8deb22469fe7508132d3c17fa6ed871e79832691c", size = 95943, upload-time = "2026-03-01T22:07:21.266Z" }, + { url = "https://files.pythonhosted.org/packages/c0/cc/6409f9018864a6aa186c61175b977131f373f1988e198e031236916e87e4/yarl-1.23.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:62694e275c93d54f7ccedcfef57d42761b2aad5234b6be1f3e3026cae4001cd4", size = 88786, upload-time = "2026-03-01T22:07:23.129Z" }, + { url = "https://files.pythonhosted.org/packages/76/40/cc22d1d7714b717fde2006fad2ced5efe5580606cb059ae42117542122f3/yarl-1.23.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a31de1613658308efdb21ada98cbc86a97c181aa050ba22a808120bb5be3ab94", size = 101307, upload-time = "2026-03-01T22:07:24.689Z" }, + { url = "https://files.pythonhosted.org/packages/8f/0d/476c38e85ddb4c6ec6b20b815bdd779aa386a013f3d8b85516feee55c8dc/yarl-1.23.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fb1e8b8d66c278b21d13b0a7ca22c41dd757a7c209c6b12c313e445c31dd3b28", size = 100904, upload-time = "2026-03-01T22:07:26.287Z" }, + { url = "https://files.pythonhosted.org/packages/72/32/0abe4a76d59adf2081dcb0397168553ece4616ada1c54d1c49d8936c74f8/yarl-1.23.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50f9d8d531dfb767c565f348f33dd5139a6c43f5cbdf3f67da40d54241df93f6", size = 97728, upload-time = "2026-03-01T22:07:27.906Z" }, + { url = "https://files.pythonhosted.org/packages/b7/35/7b30f4810fba112f60f5a43237545867504e15b1c7647a785fbaf588fac2/yarl-1.23.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:575aa4405a656e61a540f4a80eaa5260f2a38fff7bfdc4b5f611840d76e9e277", size = 95964, upload-time = "2026-03-01T22:07:30.198Z" }, + { url = "https://files.pythonhosted.org/packages/2d/86/ed7a73ab85ef00e8bb70b0cb5421d8a2a625b81a333941a469a6f4022828/yarl-1.23.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:041b1a4cefacf65840b4e295c6985f334ba83c30607441ae3cf206a0eed1a2e4", size = 95882, upload-time = "2026-03-01T22:07:32.132Z" }, + { url = "https://files.pythonhosted.org/packages/19/90/d56967f61a29d8498efb7afb651e0b2b422a1e9b47b0ab5f4e40a19b699b/yarl-1.23.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:d38c1e8231722c4ce40d7593f28d92b5fc72f3e9774fe73d7e800ec32299f63a", size = 90797, upload-time = "2026-03-01T22:07:34.404Z" }, + { url = "https://files.pythonhosted.org/packages/72/00/8b8f76909259f56647adb1011d7ed8b321bcf97e464515c65016a47ecdf0/yarl-1.23.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:d53834e23c015ee83a99377db6e5e37d8484f333edb03bd15b4bc312cc7254fb", size = 101023, upload-time = "2026-03-01T22:07:35.953Z" }, + { url = "https://files.pythonhosted.org/packages/ac/e2/cab11b126fb7d440281b7df8e9ddbe4851e70a4dde47a202b6642586b8d9/yarl-1.23.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:2e27c8841126e017dd2a054a95771569e6070b9ee1b133366d8b31beb5018a41", size = 96227, upload-time = "2026-03-01T22:07:37.594Z" }, + { url = "https://files.pythonhosted.org/packages/c2/9b/2c893e16bfc50e6b2edf76c1a9eb6cb0c744346197e74c65e99ad8d634d0/yarl-1.23.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:76855800ac56f878847a09ce6dba727c93ca2d89c9e9d63002d26b916810b0a2", size = 100302, upload-time = "2026-03-01T22:07:39.334Z" }, + { url = "https://files.pythonhosted.org/packages/28/ec/5498c4e3a6d5f1003beb23405671c2eb9cdbf3067d1c80f15eeafe301010/yarl-1.23.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e09fd068c2e169a7070d83d3bde728a4d48de0549f975290be3c108c02e499b4", size = 98202, upload-time = "2026-03-01T22:07:41.717Z" }, + { url = "https://files.pythonhosted.org/packages/fe/c3/cd737e2d45e70717907f83e146f6949f20cc23cd4bf7b2688727763aa458/yarl-1.23.0-cp314-cp314t-win32.whl", hash = "sha256:73309162a6a571d4cbd3b6a1dcc703c7311843ae0d1578df6f09be4e98df38d4", size = 90558, upload-time = "2026-03-01T22:07:43.433Z" }, + { url = "https://files.pythonhosted.org/packages/e1/19/3774d162f6732d1cfb0b47b4140a942a35ca82bb19b6db1f80e9e7bdc8f8/yarl-1.23.0-cp314-cp314t-win_amd64.whl", hash = "sha256:4503053d296bc6e4cbd1fad61cf3b6e33b939886c4f249ba7c78b602214fabe2", size = 97610, upload-time = "2026-03-01T22:07:45.773Z" }, + { url = "https://files.pythonhosted.org/packages/51/47/3fa2286c3cb162c71cdb34c4224d5745a1ceceb391b2bd9b19b668a8d724/yarl-1.23.0-cp314-cp314t-win_arm64.whl", hash = "sha256:44bb7bef4ea409384e3f8bc36c063d77ea1b8d4a5b2706956c0d6695f07dcc25", size = 86041, upload-time = "2026-03-01T22:07:49.026Z" }, + { url = "https://files.pythonhosted.org/packages/69/68/c8739671f5699c7dc470580a4f821ef37c32c4cb0b047ce223a7f115757f/yarl-1.23.0-py3-none-any.whl", hash = "sha256:a2df6afe50dea8ae15fa34c9f824a3ee958d785fd5d089063d960bae1daa0a3f", size = 48288, upload-time = "2026-03-01T22:07:51.388Z" }, +] + +[[package]] +name = "zipp" +version = "3.23.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/30/21/093488dfc7cc8964ded15ab726fad40f25fd3d788fd741cc1c5a17d78ee8/zipp-3.23.1.tar.gz", hash = "sha256:32120e378d32cd9714ad503c1d024619063ec28aad2248dc6672ad13edfa5110", size = 25965, upload-time = "2026-04-13T23:21:46.6Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/08/8a/0861bec20485572fbddf3dfba2910e38fe249796cb73ecdeb74e07eeb8d3/zipp-3.23.1-py3-none-any.whl", hash = "sha256:0b3596c50a5c700c9cb40ba8d86d9f2cc4807e9bedb06bcdf7fac85633e444dc", size = 10378, upload-time = "2026-04-13T23:21:45.386Z" }, +]