From 8907a7e5baaa900a319adb34a04ce8bd3feb91be Mon Sep 17 00:00:00 2001 From: Musa Jundi Date: Tue, 28 Apr 2026 14:39:46 -0500 Subject: [PATCH 1/2] chore: sync shared codegen files from staging-next --- .stats.yml | 8 +- VALIDATION_REPORT.md | 286 +++++++++++++++++++++++++++++++++++++++++++ scripts/mock | 8 +- scripts/test | 6 +- 4 files changed, 299 insertions(+), 9 deletions(-) create mode 100644 VALIDATION_REPORT.md diff --git a/.stats.yml b/.stats.yml index 1682359bc84..661ee96b590 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: 2184 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare%2Fcloudflare-95d8075980561cae9cc6ce09b5f930b84eae6f0864cb155abe47db94df2ee294.yml +openapi_spec_hash: 86610e8d69a7b3f8b83cb5f6a0a7c96e +config_hash: 95239e8fc62638979bc21e538307bbe3 diff --git a/VALIDATION_REPORT.md b/VALIDATION_REPORT.md new file mode 100644 index 00000000000..87fadc58f27 --- /dev/null +++ b/VALIDATION_REPORT.md @@ -0,0 +1,286 @@ +# Python SDK Validation Report + +**Branch:** `next` (at `9707100e1`) +**Date:** 2026-04-24 +**Checkers:** pyright 1.1.399, mypy 1.17, ruff + +--- + +## Summary + +| Check | Result | +|---------|--------| +| ruff | PASS | +| pyright | FAIL - 55 errors | +| mypy | FAIL - 12 errors | + +All failures are type-checking errors. There are **4 distinct issues** across 6 source files (+1 test file), +producing the full error count due to cascading type-unknown propagation. + +--- + +## Issue 1: Missing `Required` import in `asset_create_params.py` + +**Files:** `src/cloudflare/types/ai/finetunes/asset_create_params.py` +**Error count:** 3 (pyright) + 3 (mypy) +**Error type:** `reportUndefinedVariable` / `name-defined` + +### What's wrong + +`Required` is used on lines 13, 15, and 18 but is not imported. The import line reads: + +```python +from typing_extensions import TypedDict +``` + +It should be: + +```python +from typing_extensions import Required, TypedDict +``` + +### Change history + +| Date | Commit | What happened | +|------------|-------------|---------------| +| 2025-01-02 | `4493d6c28` | File created with `Required` import and `Required[str]` on `account_id` | +| 2026-04-19 | `3b83baa3b` | Codegen removed `Required` import AND `Required` usage (made fields optional) | +| 2026-04-23 | `988df8632` | Codegen re-added `Required` to 3 fields BUT did not restore the import | + +### Root cause + +The `988df8632` commit ("remove account_id and zone_id client options") re-promoted `account_id`, `file`, and +`file_name` back to `Required` status but the codegen output omitted the corresponding +`from typing_extensions import Required` update. This is a Stainless codegen bug -- it emitted `Required` usage +without the import. + +### Fix + +Add `Required` to the import: + +```python +from typing_extensions import Required, TypedDict +``` + +--- + +## Issue 2: `SchemaFieldStruct` and `SchemaFieldList` missing `TypedDict` base class + +**Files:** +- `src/cloudflare/types/pipelines/sink_create_params.py` (lines 293, 297) +- `src/cloudflare/types/pipelines/stream_create_params.py` (lines 201, 205) + +**Error count:** 4 (pyright) + 4 (mypy) +**Error type:** `reportGeneralTypeIssues` + `reportCallIssue` / `call-arg` + +### What's wrong + +Both classes are declared as: + +```python +class SchemaFieldStruct(total=False): + pass + +class SchemaFieldList(total=False): + pass +``` + +They should inherit from `TypedDict`: + +```python +class SchemaFieldStruct(TypedDict, total=False): + ... + +class SchemaFieldList(TypedDict, total=False): + ... +``` + +Without `TypedDict`, these are plain class definitions. `total=False` is passed to +`object.__init_subclass__()` which does not accept that keyword argument. + +### Change history + +| Date | Commit | What happened | +|------------|-------------|---------------| +| 2025-11-12 | `008556f6a` | Pipelines feature introduced these types (generated with stub bodies, had pyright ignores) | +| 2026-02-11 | `1c415a2dd` | **Manual fix**: added `TypedDict` base class, proper `type`, `name`, `fields`/`element` fields | +| 2026-04-19 | `3b83baa3b` | Codegen overwrote the manual fix, regenerating stubs without `TypedDict` base class | + +### Root cause + +Stainless codegen is emitting empty stub classes for the `struct` and `list` schema field variants. The OpenAPI +spec likely defines these as recursive types (struct has `fields: [SchemaField]`, list has `element: SchemaField`) +which the codegen can't fully resolve, so it emits empty stubs. A previous manual fix (`1c415a2dd`) was +overwritten by subsequent codegen runs. + +### Fix + +Restore the `TypedDict` base class and proper fields as done in `1c415a2dd`. For both +`sink_create_params.py` and `stream_create_params.py`: + +```python +class SchemaFieldStruct(TypedDict, total=False): + type: Required[Literal["struct"]] + metadata_key: Optional[str] + name: str + required: bool + sql_name: str + fields: Optional[List["SchemaField"]] + +class SchemaFieldList(TypedDict, total=False): + type: Required[Literal["list"]] + metadata_key: Optional[str] + name: str + required: bool + sql_name: str + element: Optional["SchemaField"] +``` + +This fix will be overwritten by the next codegen run unless the Stainless config or upstream OpenAPI spec is also +fixed to properly model these recursive types. + +--- + +## Issue 3: Missing `organization_profile_get_params` module + +**Files:** +- `src/cloudflare/resources/organizations/organization_profile.py` (line 22) +- `tests/api_resources/organizations/test_organization_profile.py` (line 12) + +**Error count:** 22 (pyright) + 1 (mypy) -- most pyright errors are cascading `Unknown` type propagation +**Error type:** `reportMissingImports` / `import-not-found` + +### What's wrong + +Both the resource module and its test file import: + +```python +from ...types.organizations.organization_profile_get_params import Result +``` + +But the file `organization_profile_get_params.py` does not exist. It was deleted by codegen. + +### Change history + +| Date | Commit | What happened | +|------------|-------------|---------------| +| 2026-02-11 | `1c415a2dd` | **Manual fix**: created `organization_profile_get_params.py` with `Result = OrganizationProfile` | +| 2026-04-19 | `3b83baa3b` | Codegen created `organization_profile.py` resource file, importing `Result` from get_params | +| 2026-04-22 | `0d6464258` | Codegen **deleted** `organization_profile_get_params.py` and removed it from `__init__.py` | +| 2026-04-23 | `988df8632` | Resource file unchanged -- still imports from deleted module | + +### Root cause + +There is a sequencing inconsistency in the codegen output. The resource file (`organization_profile.py`) was +generated expecting a `Result` type alias from a params file, but a later codegen run deleted that params file +without updating the resource file's import. The `Result` type was just an alias for `OrganizationProfile`. + +### Fix + +Option A -- Recreate the deleted file: + +Create `src/cloudflare/types/organizations/organization_profile_get_params.py`: +```python +from __future__ import annotations +from typing_extensions import TypeAlias +from .organization_profile import OrganizationProfile + +__all__ = ["Result"] + +Result: TypeAlias = OrganizationProfile +``` + +And add to `src/cloudflare/types/organizations/__init__.py`: +```python +from .organization_profile import OrganizationProfile as OrganizationProfile +``` + +Option B -- Inline the import (smaller diff): + +In `organization_profile.py` and the test file, replace: +```python +from ...types.organizations.organization_profile_get_params import Result +``` +with: +```python +from ...types.organizations.organization_profile import OrganizationProfile as Result +``` + +Option A is preferred since it matches the pattern codegen expects and is more durable. + +--- + +## Issue 4: `_get_api_list` called with unsupported `files` parameter + +**Files:** +- `src/cloudflare/resources/ai/to_markdown.py` (lines 118, 217) + +**Error count:** 4 (pyright) + 2 (mypy) (2 calls x sync/async variants) +**Error type:** `reportCallIssue` + `reportUnknownVariableType` / `call-arg` + +### What's wrong + +The `transform` method passes `files=files` to `self._get_api_list()`: + +```python +return self._get_api_list( + ..., + body=maybe_transform(body, ...), + files=files, # <-- not in get_api_list signature + options=..., + model=..., + method="post", +) +``` + +The `get_api_list` method signature in `_base_client.py` is: + +```python +def get_api_list(self, path, *, model, page, body=None, options={}, method="get") -> SyncPageT +``` + +There is no `files` parameter. The kwargs likely pass through to the underlying request options via `**options`, +but the type signature rejects it. + +### Change history + +| Date | Commit | What happened | +|------------|-------------|---------------| +| 2026-02-11 | `f280942f4` | Added `# pyright: ignore` / `# type: ignore` to the **same pattern** in `radar/ai/to_markdown.py` | +| 2026-04-19 | `3b83baa3b` | Codegen created the new `ai/to_markdown.py` with same `files=` pattern but **without** suppression comments | + +### Root cause + +This is a known Stainless codegen limitation: `_get_api_list` does not accept `files` in its typed signature, but +multipart file upload endpoints that also return paginated lists need to pass files through. The older +`radar/ai/to_markdown.py` has manual suppression comments that survive codegen. The newly generated +`ai/to_markdown.py` was created fresh and lacks them. + +### Fix + +Add type-checker suppression comments matching the pattern in `radar/ai/to_markdown.py`: + +```python +files=files, # pyright: ignore[reportCallIssue] # type: ignore[call-arg] +``` + +On both line 118 (sync) and line 217 (async) in `src/cloudflare/resources/ai/to_markdown.py`. + +--- + +## Cross-cutting observations + +1. **Manual fixes are fragile.** Issues 2, 3, and 4 all stem from manual fixes (commits `1c415a2dd` and + `f280942f4`) being overwritten by subsequent Stainless codegen runs. Any fix applied here will face the same + risk on the next codegen sync unless the upstream Stainless config or OpenAPI spec is also corrected. + +2. **Upstream Stainless bugs to track:** + - Missing `Required` import when re-promoting fields (Issue 1) + - Empty stub classes for recursive TypedDict types in pipelines (Issue 2) + - Inconsistent file deletion without updating dependents (Issue 3) + - Missing `files` parameter in `_get_api_list` signature for multipart paginated endpoints (Issue 4) + +3. **Recommended durable fixes:** + - Issues 1, 3, 4: File Stainless bug reports so codegen output is correct + - Issue 2: Fix the OpenAPI spec for pipelines to properly model recursive struct/list types, or add Stainless + config overrides to emit correct TypedDict stubs diff --git a/scripts/mock b/scripts/mock index bcf3b392b3b..01c4db59bca 100755 --- a/scripts/mock +++ b/scripts/mock @@ -4,6 +4,8 @@ set -e cd "$(dirname "$0")/.." +MOCK_PORT="${MOCK_PORT:-4012}" + if [[ -n "$1" && "$1" != '--'* ]]; then URL="$1" shift @@ -17,14 +19,14 @@ if [ -z "$URL" ]; then exit 1 fi -echo "==> Starting mock server with URL ${URL}" +echo "==> Starting mock server with URL ${URL} on port ${MOCK_PORT}" # Run prism mock on the given spec if [ "$1" == "--daemon" ]; then # Pre-install the package so the download doesn't eat into the startup timeout npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism --version - npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" &> .prism.log & + npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" -p "$MOCK_PORT" &> .prism.log & # Wait for server to come online (max 30s) echo -n "Waiting for server" @@ -48,5 +50,5 @@ if [ "$1" == "--daemon" ]; then echo else - npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" + npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" -p "$MOCK_PORT" fi diff --git a/scripts/test b/scripts/test index dbeda2d2176..c829a8cbe42 100755 --- a/scripts/test +++ b/scripts/test @@ -9,8 +9,10 @@ GREEN='\033[0;32m' YELLOW='\033[0;33m' NC='\033[0m' # No Color +MOCK_PORT="${MOCK_PORT:-4012}" + function prism_is_running() { - curl --silent "http://localhost:4010" >/dev/null 2>&1 + curl --silent "http://localhost:${MOCK_PORT}" >/dev/null 2>&1 } kill_server_on_port() { @@ -27,7 +29,7 @@ function is_overriding_api_base_url() { if ! is_overriding_api_base_url && ! prism_is_running ; then # When we exit this script, make sure to kill the background mock server process - trap 'kill_server_on_port 4010' EXIT + trap 'kill_server_on_port $MOCK_PORT' EXIT # Start the dev server ./scripts/mock --daemon From 7d08c554b16cda4db4a072e5359dfe9b7f420572 Mon Sep 17 00:00:00 2001 From: Musa Jundi Date: Tue, 28 Apr 2026 14:42:13 -0500 Subject: [PATCH 2/2] feat: sync codegen changes from staging-next Resources: aisearch, email_security, magic_transit, queues, workers, billing, pipelines Removed email_security investigate sub-resources (detections, raw, reclassify, trace) deleted by codegen --- VALIDATION_REPORT.md | 286 ------------ .../resources/aisearch/instances/instances.py | 74 ++-- .../namespaces/instances/instances.py | 74 ++-- .../aisearch/namespaces/instances/items.py | 46 +- src/cloudflare/resources/billing/usage.py | 6 +- .../resources/email_security/api.md | 91 +--- .../email_security/investigate/__init__.py | 56 --- .../email_security/investigate/detections.py | 199 --------- .../email_security/investigate/investigate.py | 396 ++--------------- .../email_security/investigate/move.py | 157 +------ .../email_security/investigate/preview.py | 143 +----- .../email_security/investigate/raw.py | 197 --------- .../email_security/investigate/reclassify.py | 238 ---------- .../email_security/investigate/release.py | 18 +- .../email_security/investigate/trace.py | 210 --------- .../email_security/phishguard/reports.py | 36 +- .../email_security/settings/allow_policies.py | 352 ++++++++++----- .../email_security/settings/block_senders.py | 220 ++++++---- .../email_security/settings/domains.py | 285 +++++------- .../settings/impersonation_registry.py | 415 +++--------------- .../settings/trusted_domains.py | 390 +++++++--------- .../resources/email_security/submissions.py | 40 +- .../magic_transit/cf_interconnects.py | 6 +- .../resources/magic_transit/gre_tunnels.py | 12 +- .../resources/magic_transit/ipsec_tunnels.py | 12 +- src/cloudflare/resources/queues/api.md | 3 +- src/cloudflare/resources/queues/queues.py | 105 +++++ .../workers/observability/telemetry.py | 120 ++--- .../types/aisearch/instance_list_params.py | 12 +- .../namespaces/instance_list_params.py | 12 +- .../instances/item_create_or_update_params.py | 9 + .../namespaces/instances/item_sync_params.py | 9 + .../instances/item_upload_params.py | 8 +- .../types/email_security/__init__.py | 2 - .../email_security/investigate/__init__.py | 8 - .../investigate/detection_get_response.py | 152 ------- .../investigate/move_bulk_params.py | 9 +- .../investigate/move_bulk_response.py | 18 +- .../investigate/move_create_params.py | 22 - .../investigate/move_create_response.py | 33 -- .../investigate/preview_create_params.py | 10 +- .../investigate/preview_get_response.py | 10 - .../investigate/raw_get_response.py | 10 - .../investigate/reclassify_create_params.py | 25 -- .../investigate/release_bulk_params.py | 3 +- .../investigate/release_bulk_response.py | 7 +- .../investigate/trace_get_params.py | 18 - .../investigate/trace_get_response.py | 42 -- .../email_security/investigate_get_params.py | 18 - .../investigate_get_response.py | 188 -------- .../email_security/investigate_list_params.py | 64 +-- .../investigate_list_response.py | 59 ++- .../phishguard/report_list_params.py | 8 +- .../phishguard/report_list_response.py | 18 +- .../types/email_security/settings/__init__.py | 7 - .../settings/allow_policy_create_params.py | 30 +- .../settings/allow_policy_create_response.py | 61 ++- .../settings/allow_policy_delete_response.py | 4 +- .../settings/allow_policy_edit_params.py | 48 +- .../settings/allow_policy_edit_response.py | 61 ++- .../settings/allow_policy_get_response.py | 61 ++- .../settings/allow_policy_list_params.py | 37 +- .../settings/allow_policy_list_response.py | 61 ++- .../settings/block_sender_create_params.py | 6 +- .../settings/block_sender_create_response.py | 25 +- .../settings/block_sender_delete_response.py | 4 +- .../settings/block_sender_edit_params.py | 12 +- .../settings/block_sender_edit_response.py | 25 +- .../settings/block_sender_get_response.py | 25 +- .../settings/block_sender_list_params.py | 16 +- .../settings/block_sender_list_response.py | 25 +- .../settings/domain_bulk_delete_response.py | 10 - .../settings/domain_delete_response.py | 4 +- .../settings/domain_edit_params.py | 10 +- .../settings/domain_edit_response.py | 71 +-- .../settings/domain_get_response.py | 71 +-- .../settings/domain_list_params.py | 25 +- .../settings/domain_list_response.py | 71 +-- .../impersonation_registry_create_params.py | 15 +- .../impersonation_registry_create_response.py | 31 +- .../impersonation_registry_delete_response.py | 9 - .../impersonation_registry_edit_params.py | 19 - .../impersonation_registry_edit_response.py | 32 -- .../impersonation_registry_get_response.py | 32 -- .../impersonation_registry_list_params.py | 14 +- .../impersonation_registry_list_response.py | 31 +- .../settings/trusted_domain_create_params.py | 40 +- .../trusted_domain_create_response.py | 54 +-- .../trusted_domain_delete_response.py | 4 +- .../settings/trusted_domain_edit_params.py | 5 +- .../settings/trusted_domain_edit_response.py | 23 +- .../settings/trusted_domain_get_response.py | 23 +- .../settings/trusted_domain_list_params.py | 22 +- .../settings/trusted_domain_list_response.py | 23 +- .../email_security/submission_list_params.py | 15 +- .../submission_list_response.py | 73 +-- .../cf_interconnect_bulk_update_response.py | 3 +- .../cf_interconnect_get_response.py | 3 +- .../cf_interconnect_list_response.py | 3 +- .../cf_interconnect_update_params.py | 3 +- .../cf_interconnect_update_response.py | 3 +- .../gre_tunnel_bulk_update_response.py | 3 +- .../magic_transit/gre_tunnel_create_params.py | 3 +- .../gre_tunnel_create_response.py | 3 +- .../gre_tunnel_delete_response.py | 3 +- .../magic_transit/gre_tunnel_get_response.py | 3 +- .../magic_transit/gre_tunnel_list_response.py | 3 +- .../magic_transit/gre_tunnel_update_params.py | 3 +- .../gre_tunnel_update_response.py | 3 +- .../ipsec_tunnel_bulk_update_response.py | 3 +- .../ipsec_tunnel_create_params.py | 3 +- .../ipsec_tunnel_create_response.py | 3 +- .../ipsec_tunnel_delete_response.py | 3 +- .../ipsec_tunnel_get_response.py | 3 +- .../ipsec_tunnel_list_response.py | 3 +- .../ipsec_tunnel_update_params.py | 3 +- .../ipsec_tunnel_update_response.py | 3 +- .../types/magic_transit/sites/dhcp_server.py | 32 +- .../magic_transit/sites/dhcp_server_param.py | 35 +- src/cloudflare/types/queues/__init__.py | 1 + .../queues/queue_get_metrics_response.py | 25 ++ .../types/workers/beta/workers/version.py | 7 + .../beta/workers/version_create_params.py | 7 + .../observability/telemetry_keys_params.py | 135 +++++- .../observability/telemetry_query_params.py | 287 +++++++++--- .../observability/telemetry_query_response.py | 289 ++++++++++-- .../observability/telemetry_values_params.py | 141 +++++- .../types/workers/script_update_params.py | 7 + .../script_and_version_setting_edit_params.py | 7 + ...cript_and_version_setting_edit_response.py | 7 + ...script_and_version_setting_get_response.py | 7 + .../workers/scripts/version_create_params.py | 7 + .../scripts/version_create_response.py | 7 + .../workers/scripts/version_get_response.py | 7 + .../namespaces/instances/test_items.py | 48 ++ .../aisearch/namespaces/test_instances.py | 4 +- .../api_resources/aisearch/test_instances.py | 4 +- .../investigate/test_detections.py | 120 ----- .../email_security/investigate/test_move.py | 135 +----- .../investigate/test_preview.py | 116 +---- .../email_security/investigate/test_raw.py | 120 ----- .../investigate/test_reclassify.py | 153 ------- .../investigate/test_release.py | 16 +- .../email_security/investigate/test_trace.py | 138 ------ .../settings/test_allow_policies.py | 182 +++++--- .../settings/test_block_senders.py | 166 ++++--- .../email_security/settings/test_domains.py | 219 ++++----- .../settings/test_impersonation_registry.py | 377 +++------------- .../settings/test_trusted_domains.py | 338 +++++--------- .../email_security/test_investigate.py | 127 +----- .../email_security/test_submissions.py | 6 +- .../magic_transit/sites/test_lans.py | 42 ++ tests/api_resources/test_queues.py | 97 ++++ .../workers/beta/test_workers.py | 20 + .../workers/observability/test_telemetry.py | 48 +- 155 files changed, 3585 insertions(+), 6158 deletions(-) delete mode 100644 VALIDATION_REPORT.md delete mode 100644 src/cloudflare/resources/email_security/investigate/detections.py delete mode 100644 src/cloudflare/resources/email_security/investigate/raw.py delete mode 100644 src/cloudflare/resources/email_security/investigate/reclassify.py delete mode 100644 src/cloudflare/resources/email_security/investigate/trace.py delete mode 100644 src/cloudflare/types/email_security/investigate/detection_get_response.py delete mode 100644 src/cloudflare/types/email_security/investigate/move_create_params.py delete mode 100644 src/cloudflare/types/email_security/investigate/move_create_response.py delete mode 100644 src/cloudflare/types/email_security/investigate/preview_get_response.py delete mode 100644 src/cloudflare/types/email_security/investigate/raw_get_response.py delete mode 100644 src/cloudflare/types/email_security/investigate/reclassify_create_params.py delete mode 100644 src/cloudflare/types/email_security/investigate/trace_get_params.py delete mode 100644 src/cloudflare/types/email_security/investigate/trace_get_response.py delete mode 100644 src/cloudflare/types/email_security/investigate_get_params.py delete mode 100644 src/cloudflare/types/email_security/investigate_get_response.py delete mode 100644 src/cloudflare/types/email_security/settings/domain_bulk_delete_response.py delete mode 100644 src/cloudflare/types/email_security/settings/impersonation_registry_delete_response.py delete mode 100644 src/cloudflare/types/email_security/settings/impersonation_registry_edit_params.py delete mode 100644 src/cloudflare/types/email_security/settings/impersonation_registry_edit_response.py delete mode 100644 src/cloudflare/types/email_security/settings/impersonation_registry_get_response.py create mode 100644 src/cloudflare/types/queues/queue_get_metrics_response.py delete mode 100644 tests/api_resources/email_security/investigate/test_detections.py delete mode 100644 tests/api_resources/email_security/investigate/test_raw.py delete mode 100644 tests/api_resources/email_security/investigate/test_reclassify.py delete mode 100644 tests/api_resources/email_security/investigate/test_trace.py diff --git a/VALIDATION_REPORT.md b/VALIDATION_REPORT.md deleted file mode 100644 index 87fadc58f27..00000000000 --- a/VALIDATION_REPORT.md +++ /dev/null @@ -1,286 +0,0 @@ -# Python SDK Validation Report - -**Branch:** `next` (at `9707100e1`) -**Date:** 2026-04-24 -**Checkers:** pyright 1.1.399, mypy 1.17, ruff - ---- - -## Summary - -| Check | Result | -|---------|--------| -| ruff | PASS | -| pyright | FAIL - 55 errors | -| mypy | FAIL - 12 errors | - -All failures are type-checking errors. There are **4 distinct issues** across 6 source files (+1 test file), -producing the full error count due to cascading type-unknown propagation. - ---- - -## Issue 1: Missing `Required` import in `asset_create_params.py` - -**Files:** `src/cloudflare/types/ai/finetunes/asset_create_params.py` -**Error count:** 3 (pyright) + 3 (mypy) -**Error type:** `reportUndefinedVariable` / `name-defined` - -### What's wrong - -`Required` is used on lines 13, 15, and 18 but is not imported. The import line reads: - -```python -from typing_extensions import TypedDict -``` - -It should be: - -```python -from typing_extensions import Required, TypedDict -``` - -### Change history - -| Date | Commit | What happened | -|------------|-------------|---------------| -| 2025-01-02 | `4493d6c28` | File created with `Required` import and `Required[str]` on `account_id` | -| 2026-04-19 | `3b83baa3b` | Codegen removed `Required` import AND `Required` usage (made fields optional) | -| 2026-04-23 | `988df8632` | Codegen re-added `Required` to 3 fields BUT did not restore the import | - -### Root cause - -The `988df8632` commit ("remove account_id and zone_id client options") re-promoted `account_id`, `file`, and -`file_name` back to `Required` status but the codegen output omitted the corresponding -`from typing_extensions import Required` update. This is a Stainless codegen bug -- it emitted `Required` usage -without the import. - -### Fix - -Add `Required` to the import: - -```python -from typing_extensions import Required, TypedDict -``` - ---- - -## Issue 2: `SchemaFieldStruct` and `SchemaFieldList` missing `TypedDict` base class - -**Files:** -- `src/cloudflare/types/pipelines/sink_create_params.py` (lines 293, 297) -- `src/cloudflare/types/pipelines/stream_create_params.py` (lines 201, 205) - -**Error count:** 4 (pyright) + 4 (mypy) -**Error type:** `reportGeneralTypeIssues` + `reportCallIssue` / `call-arg` - -### What's wrong - -Both classes are declared as: - -```python -class SchemaFieldStruct(total=False): - pass - -class SchemaFieldList(total=False): - pass -``` - -They should inherit from `TypedDict`: - -```python -class SchemaFieldStruct(TypedDict, total=False): - ... - -class SchemaFieldList(TypedDict, total=False): - ... -``` - -Without `TypedDict`, these are plain class definitions. `total=False` is passed to -`object.__init_subclass__()` which does not accept that keyword argument. - -### Change history - -| Date | Commit | What happened | -|------------|-------------|---------------| -| 2025-11-12 | `008556f6a` | Pipelines feature introduced these types (generated with stub bodies, had pyright ignores) | -| 2026-02-11 | `1c415a2dd` | **Manual fix**: added `TypedDict` base class, proper `type`, `name`, `fields`/`element` fields | -| 2026-04-19 | `3b83baa3b` | Codegen overwrote the manual fix, regenerating stubs without `TypedDict` base class | - -### Root cause - -Stainless codegen is emitting empty stub classes for the `struct` and `list` schema field variants. The OpenAPI -spec likely defines these as recursive types (struct has `fields: [SchemaField]`, list has `element: SchemaField`) -which the codegen can't fully resolve, so it emits empty stubs. A previous manual fix (`1c415a2dd`) was -overwritten by subsequent codegen runs. - -### Fix - -Restore the `TypedDict` base class and proper fields as done in `1c415a2dd`. For both -`sink_create_params.py` and `stream_create_params.py`: - -```python -class SchemaFieldStruct(TypedDict, total=False): - type: Required[Literal["struct"]] - metadata_key: Optional[str] - name: str - required: bool - sql_name: str - fields: Optional[List["SchemaField"]] - -class SchemaFieldList(TypedDict, total=False): - type: Required[Literal["list"]] - metadata_key: Optional[str] - name: str - required: bool - sql_name: str - element: Optional["SchemaField"] -``` - -This fix will be overwritten by the next codegen run unless the Stainless config or upstream OpenAPI spec is also -fixed to properly model these recursive types. - ---- - -## Issue 3: Missing `organization_profile_get_params` module - -**Files:** -- `src/cloudflare/resources/organizations/organization_profile.py` (line 22) -- `tests/api_resources/organizations/test_organization_profile.py` (line 12) - -**Error count:** 22 (pyright) + 1 (mypy) -- most pyright errors are cascading `Unknown` type propagation -**Error type:** `reportMissingImports` / `import-not-found` - -### What's wrong - -Both the resource module and its test file import: - -```python -from ...types.organizations.organization_profile_get_params import Result -``` - -But the file `organization_profile_get_params.py` does not exist. It was deleted by codegen. - -### Change history - -| Date | Commit | What happened | -|------------|-------------|---------------| -| 2026-02-11 | `1c415a2dd` | **Manual fix**: created `organization_profile_get_params.py` with `Result = OrganizationProfile` | -| 2026-04-19 | `3b83baa3b` | Codegen created `organization_profile.py` resource file, importing `Result` from get_params | -| 2026-04-22 | `0d6464258` | Codegen **deleted** `organization_profile_get_params.py` and removed it from `__init__.py` | -| 2026-04-23 | `988df8632` | Resource file unchanged -- still imports from deleted module | - -### Root cause - -There is a sequencing inconsistency in the codegen output. The resource file (`organization_profile.py`) was -generated expecting a `Result` type alias from a params file, but a later codegen run deleted that params file -without updating the resource file's import. The `Result` type was just an alias for `OrganizationProfile`. - -### Fix - -Option A -- Recreate the deleted file: - -Create `src/cloudflare/types/organizations/organization_profile_get_params.py`: -```python -from __future__ import annotations -from typing_extensions import TypeAlias -from .organization_profile import OrganizationProfile - -__all__ = ["Result"] - -Result: TypeAlias = OrganizationProfile -``` - -And add to `src/cloudflare/types/organizations/__init__.py`: -```python -from .organization_profile import OrganizationProfile as OrganizationProfile -``` - -Option B -- Inline the import (smaller diff): - -In `organization_profile.py` and the test file, replace: -```python -from ...types.organizations.organization_profile_get_params import Result -``` -with: -```python -from ...types.organizations.organization_profile import OrganizationProfile as Result -``` - -Option A is preferred since it matches the pattern codegen expects and is more durable. - ---- - -## Issue 4: `_get_api_list` called with unsupported `files` parameter - -**Files:** -- `src/cloudflare/resources/ai/to_markdown.py` (lines 118, 217) - -**Error count:** 4 (pyright) + 2 (mypy) (2 calls x sync/async variants) -**Error type:** `reportCallIssue` + `reportUnknownVariableType` / `call-arg` - -### What's wrong - -The `transform` method passes `files=files` to `self._get_api_list()`: - -```python -return self._get_api_list( - ..., - body=maybe_transform(body, ...), - files=files, # <-- not in get_api_list signature - options=..., - model=..., - method="post", -) -``` - -The `get_api_list` method signature in `_base_client.py` is: - -```python -def get_api_list(self, path, *, model, page, body=None, options={}, method="get") -> SyncPageT -``` - -There is no `files` parameter. The kwargs likely pass through to the underlying request options via `**options`, -but the type signature rejects it. - -### Change history - -| Date | Commit | What happened | -|------------|-------------|---------------| -| 2026-02-11 | `f280942f4` | Added `# pyright: ignore` / `# type: ignore` to the **same pattern** in `radar/ai/to_markdown.py` | -| 2026-04-19 | `3b83baa3b` | Codegen created the new `ai/to_markdown.py` with same `files=` pattern but **without** suppression comments | - -### Root cause - -This is a known Stainless codegen limitation: `_get_api_list` does not accept `files` in its typed signature, but -multipart file upload endpoints that also return paginated lists need to pass files through. The older -`radar/ai/to_markdown.py` has manual suppression comments that survive codegen. The newly generated -`ai/to_markdown.py` was created fresh and lacks them. - -### Fix - -Add type-checker suppression comments matching the pattern in `radar/ai/to_markdown.py`: - -```python -files=files, # pyright: ignore[reportCallIssue] # type: ignore[call-arg] -``` - -On both line 118 (sync) and line 217 (async) in `src/cloudflare/resources/ai/to_markdown.py`. - ---- - -## Cross-cutting observations - -1. **Manual fixes are fragile.** Issues 2, 3, and 4 all stem from manual fixes (commits `1c415a2dd` and - `f280942f4`) being overwritten by subsequent Stainless codegen runs. Any fix applied here will face the same - risk on the next codegen sync unless the upstream Stainless config or OpenAPI spec is also corrected. - -2. **Upstream Stainless bugs to track:** - - Missing `Required` import when re-promoting fields (Issue 1) - - Empty stub classes for recursive TypedDict types in pipelines (Issue 2) - - Inconsistent file deletion without updating dependents (Issue 3) - - Missing `files` parameter in `_get_api_list` signature for multipart paginated endpoints (Issue 4) - -3. **Recommended durable fixes:** - - Issues 1, 3, 4: File Stainless bug reports so codegen output is correct - - Issue 2: Fix the OpenAPI spec for pipelines to properly model recursive struct/list types, or add Stainless - config overrides to emit correct TypedDict stubs 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/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/email_security/api.md b/src/cloudflare/resources/email_security/api.md index 53e335ba90a..0584be64fa9 100644 --- a/src/cloudflare/resources/email_security/api.md +++ b/src/cloudflare/resources/email_security/api.md @@ -5,82 +5,37 @@ Types: ```python -from cloudflare.types.email_security import InvestigateListResponse, InvestigateGetResponse +from cloudflare.types.email_security import InvestigateListResponse ``` Methods: - client.email_security.investigate.list(\*, account_id, \*\*params) -> SyncV4PagePaginationArray[InvestigateListResponse] -- client.email_security.investigate.get(postfix_id, \*, account_id, \*\*params) -> InvestigateGetResponse - -### Detections - -Types: - -```python -from cloudflare.types.email_security.investigate import DetectionGetResponse -``` - -Methods: - -- client.email_security.investigate.detections.get(postfix_id, \*, account_id) -> DetectionGetResponse ### Preview Types: ```python -from cloudflare.types.email_security.investigate import PreviewCreateResponse, PreviewGetResponse +from cloudflare.types.email_security.investigate import PreviewCreateResponse ``` Methods: - client.email_security.investigate.preview.create(\*, account_id, \*\*params) -> PreviewCreateResponse -- client.email_security.investigate.preview.get(postfix_id, \*, account_id) -> PreviewGetResponse - -### Raw - -Types: - -```python -from cloudflare.types.email_security.investigate import RawGetResponse -``` - -Methods: - -- client.email_security.investigate.raw.get(postfix_id, \*, account_id) -> RawGetResponse - -### Trace - -Types: - -```python -from cloudflare.types.email_security.investigate import TraceGetResponse -``` - -Methods: - -- client.email_security.investigate.trace.get(postfix_id, \*, account_id, \*\*params) -> TraceGetResponse ### Move Types: ```python -from cloudflare.types.email_security.investigate import MoveCreateResponse, MoveBulkResponse +from cloudflare.types.email_security.investigate import MoveBulkResponse ``` Methods: -- client.email_security.investigate.move.create(postfix_id, \*, account_id, \*\*params) -> 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 - ### Release Types: @@ -125,11 +80,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 +102,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 +116,6 @@ Types: from cloudflare.types.email_security.settings import ( DomainListResponse, DomainDeleteResponse, - DomainBulkDeleteResponse, DomainEditResponse, DomainGetResponse, ) @@ -170,10 +124,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 @@ -183,19 +136,13 @@ Types: from cloudflare.types.email_security.settings import ( ImpersonationRegistryCreateResponse, ImpersonationRegistryListResponse, - ImpersonationRegistryDeleteResponse, - ImpersonationRegistryEditResponse, - ImpersonationRegistryGetResponse, ) ``` 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 ### TrustedDomains @@ -213,11 +160,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/__init__.py b/src/cloudflare/resources/email_security/investigate/__init__.py index 5b206205771..7de4ad936c0 100644 --- a/src/cloudflare/resources/email_security/investigate/__init__.py +++ b/src/cloudflare/resources/email_security/investigate/__init__.py @@ -1,13 +1,5 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from .raw import ( - RawResource, - AsyncRawResource, - RawResourceWithRawResponse, - AsyncRawResourceWithRawResponse, - RawResourceWithStreamingResponse, - AsyncRawResourceWithStreamingResponse, -) from .move import ( MoveResource, AsyncMoveResource, @@ -16,14 +8,6 @@ MoveResourceWithStreamingResponse, AsyncMoveResourceWithStreamingResponse, ) -from .trace import ( - TraceResource, - AsyncTraceResource, - TraceResourceWithRawResponse, - AsyncTraceResourceWithRawResponse, - TraceResourceWithStreamingResponse, - AsyncTraceResourceWithStreamingResponse, -) from .preview import ( PreviewResource, AsyncPreviewResource, @@ -40,22 +24,6 @@ ReleaseResourceWithStreamingResponse, AsyncReleaseResourceWithStreamingResponse, ) -from .detections import ( - DetectionsResource, - AsyncDetectionsResource, - DetectionsResourceWithRawResponse, - AsyncDetectionsResourceWithRawResponse, - DetectionsResourceWithStreamingResponse, - AsyncDetectionsResourceWithStreamingResponse, -) -from .reclassify import ( - ReclassifyResource, - AsyncReclassifyResource, - ReclassifyResourceWithRawResponse, - AsyncReclassifyResourceWithRawResponse, - ReclassifyResourceWithStreamingResponse, - AsyncReclassifyResourceWithStreamingResponse, -) from .investigate import ( InvestigateResource, AsyncInvestigateResource, @@ -66,42 +34,18 @@ ) __all__ = [ - "DetectionsResource", - "AsyncDetectionsResource", - "DetectionsResourceWithRawResponse", - "AsyncDetectionsResourceWithRawResponse", - "DetectionsResourceWithStreamingResponse", - "AsyncDetectionsResourceWithStreamingResponse", "PreviewResource", "AsyncPreviewResource", "PreviewResourceWithRawResponse", "AsyncPreviewResourceWithRawResponse", "PreviewResourceWithStreamingResponse", "AsyncPreviewResourceWithStreamingResponse", - "RawResource", - "AsyncRawResource", - "RawResourceWithRawResponse", - "AsyncRawResourceWithRawResponse", - "RawResourceWithStreamingResponse", - "AsyncRawResourceWithStreamingResponse", - "TraceResource", - "AsyncTraceResource", - "TraceResourceWithRawResponse", - "AsyncTraceResourceWithRawResponse", - "TraceResourceWithStreamingResponse", - "AsyncTraceResourceWithStreamingResponse", "MoveResource", "AsyncMoveResource", "MoveResourceWithRawResponse", "AsyncMoveResourceWithRawResponse", "MoveResourceWithStreamingResponse", "AsyncMoveResourceWithStreamingResponse", - "ReclassifyResource", - "AsyncReclassifyResource", - "ReclassifyResourceWithRawResponse", - "AsyncReclassifyResourceWithRawResponse", - "ReclassifyResourceWithStreamingResponse", - "AsyncReclassifyResourceWithStreamingResponse", "ReleaseResource", "AsyncReleaseResource", "ReleaseResourceWithRawResponse", diff --git a/src/cloudflare/resources/email_security/investigate/detections.py b/src/cloudflare/resources/email_security/investigate/detections.py deleted file mode 100644 index 3bf800a5931..00000000000 --- a/src/cloudflare/resources/email_security/investigate/detections.py +++ /dev/null @@ -1,199 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Type, cast - -import httpx - -from ...._types import Body, Query, Headers, NotGiven, not_given -from ...._utils import path_template -from ...._compat import cached_property -from ...._resource import SyncAPIResource, AsyncAPIResource -from ...._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) -from ...._wrappers import ResultWrapper -from ...._base_client import make_request_options -from ....types.email_security.investigate.detection_get_response import DetectionGetResponse - -__all__ = ["DetectionsResource", "AsyncDetectionsResource"] - - -class DetectionsResource(SyncAPIResource): - @cached_property - def with_raw_response(self) -> DetectionsResourceWithRawResponse: - """ - 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 DetectionsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> DetectionsResourceWithStreamingResponse: - """ - 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 DetectionsResourceWithStreamingResponse(self) - - def get( - self, - postfix_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, - ) -> DetectionGetResponse: - """ - Returns detection details such as threat categories and sender information for - non-benign messages. - - Args: - account_id: Account Identifier - - postfix_id: The identifier of the message. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - 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._get( - path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}/detections", - account_id=account_id, - postfix_id=postfix_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[DetectionGetResponse]._unwrapper, - ), - cast_to=cast(Type[DetectionGetResponse], ResultWrapper[DetectionGetResponse]), - ) - - -class AsyncDetectionsResource(AsyncAPIResource): - @cached_property - def with_raw_response(self) -> AsyncDetectionsResourceWithRawResponse: - """ - 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 AsyncDetectionsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncDetectionsResourceWithStreamingResponse: - """ - 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 AsyncDetectionsResourceWithStreamingResponse(self) - - async def get( - self, - postfix_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, - ) -> DetectionGetResponse: - """ - Returns detection details such as threat categories and sender information for - non-benign messages. - - Args: - account_id: Account Identifier - - postfix_id: The identifier of the message. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - 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._get( - path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}/detections", - account_id=account_id, - postfix_id=postfix_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[DetectionGetResponse]._unwrapper, - ), - cast_to=cast(Type[DetectionGetResponse], ResultWrapper[DetectionGetResponse]), - ) - - -class DetectionsResourceWithRawResponse: - def __init__(self, detections: DetectionsResource) -> None: - self._detections = detections - - self.get = to_raw_response_wrapper( - detections.get, - ) - - -class AsyncDetectionsResourceWithRawResponse: - def __init__(self, detections: AsyncDetectionsResource) -> None: - self._detections = detections - - self.get = async_to_raw_response_wrapper( - detections.get, - ) - - -class DetectionsResourceWithStreamingResponse: - def __init__(self, detections: DetectionsResource) -> None: - self._detections = detections - - self.get = to_streamed_response_wrapper( - detections.get, - ) - - -class AsyncDetectionsResourceWithStreamingResponse: - def __init__(self, detections: AsyncDetectionsResource) -> None: - self._detections = detections - - self.get = async_to_streamed_response_wrapper( - detections.get, - ) diff --git a/src/cloudflare/resources/email_security/investigate/investigate.py b/src/cloudflare/resources/email_security/investigate/investigate.py index c6167137eed..1b2bfa3f608 100644 --- a/src/cloudflare/resources/email_security/investigate/investigate.py +++ b/src/cloudflare/resources/email_security/investigate/investigate.py @@ -2,20 +2,12 @@ from __future__ import annotations -from typing import Type, Union, Optional, cast +from typing import Union, Optional from datetime import datetime from typing_extensions import Literal import httpx -from .raw import ( - RawResource, - AsyncRawResource, - RawResourceWithRawResponse, - AsyncRawResourceWithRawResponse, - RawResourceWithStreamingResponse, - AsyncRawResourceWithStreamingResponse, -) from .move import ( MoveResource, AsyncMoveResource, @@ -24,14 +16,6 @@ MoveResourceWithStreamingResponse, AsyncMoveResourceWithStreamingResponse, ) -from .trace import ( - TraceResource, - AsyncTraceResource, - TraceResourceWithRawResponse, - AsyncTraceResourceWithRawResponse, - TraceResourceWithStreamingResponse, - AsyncTraceResourceWithStreamingResponse, -) from .preview import ( PreviewResource, AsyncPreviewResource, @@ -49,24 +33,8 @@ AsyncReleaseResourceWithStreamingResponse, ) from ...._types import Body, Omit, Query, Headers, NotGiven, 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 .detections import ( - DetectionsResource, - AsyncDetectionsResource, - DetectionsResourceWithRawResponse, - AsyncDetectionsResourceWithRawResponse, - DetectionsResourceWithStreamingResponse, - AsyncDetectionsResourceWithStreamingResponse, -) -from .reclassify import ( - ReclassifyResource, - AsyncReclassifyResource, - ReclassifyResourceWithRawResponse, - AsyncReclassifyResourceWithRawResponse, - ReclassifyResourceWithStreamingResponse, - AsyncReclassifyResourceWithStreamingResponse, -) from ...._resource import SyncAPIResource, AsyncAPIResource from ...._response import ( to_raw_response_wrapper, @@ -74,41 +42,23 @@ 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.email_security import investigate_get_params, investigate_list_params -from ....types.email_security.investigate_get_response import InvestigateGetResponse +from ....types.email_security import investigate_list_params from ....types.email_security.investigate_list_response import InvestigateListResponse __all__ = ["InvestigateResource", "AsyncInvestigateResource"] class InvestigateResource(SyncAPIResource): - @cached_property - def detections(self) -> DetectionsResource: - return DetectionsResource(self._client) - @cached_property def preview(self) -> PreviewResource: return PreviewResource(self._client) - @cached_property - def raw(self) -> RawResource: - return RawResource(self._client) - - @cached_property - def trace(self) -> TraceResource: - return TraceResource(self._client) - @cached_property def move(self) -> MoveResource: return MoveResource(self._client) - @cached_property - def reclassify(self) -> ReclassifyResource: - return ReclassifyResource(self._client) - @cached_property def release(self) -> ReleaseResource: return ReleaseResource(self._client) @@ -142,9 +92,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 +103,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 +110,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 + account_id: Identifier. - action_log: Determines if the message action log is included in the response. + action_log: Whether to include the message action log in the response. - detections_only: Determines if the search results will include detections or not. + detections_only: Whether to include only detections in search results. - domain: Filter by a domain found in the email: sender domain, recipient domain, or a - domain in a link. + domain: Sender domains to filter by. - 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`. - exact_subject: Search for messages with an exact subject match. + final_disposition: Dispositions to filter by. - final_disposition: The dispositions the search filters by. + message_action: Message actions to filter by. - message_action: The message actions the search filters 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. + query: Space-delimited search term. Case-insensitive. - 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. - - 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 +162,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 +173,6 @@ def list( "sender": sender, "start": start, "subject": subject, - "submissions": submissions, }, investigate_list_params.InvestigateListParams, ), @@ -273,86 +180,16 @@ def list( model=InvestigateListResponse, ) - def get( - self, - postfix_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, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> InvestigateGetResponse: - """ - Retrieves detailed information about a specific email message, including - headers, metadata, and security scan results. - - Args: - account_id: Account 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. - - 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 postfix_id: - raise ValueError(f"Expected a non-empty value for `postfix_id` but received {postfix_id!r}") - return self._get( - path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}", - account_id=account_id, - postfix_id=postfix_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform({"submission": submission}, investigate_get_params.InvestigateGetParams), - post_parser=ResultWrapper[InvestigateGetResponse]._unwrapper, - ), - cast_to=cast(Type[InvestigateGetResponse], ResultWrapper[InvestigateGetResponse]), - ) - class AsyncInvestigateResource(AsyncAPIResource): - @cached_property - def detections(self) -> AsyncDetectionsResource: - return AsyncDetectionsResource(self._client) - @cached_property def preview(self) -> AsyncPreviewResource: return AsyncPreviewResource(self._client) - @cached_property - def raw(self) -> AsyncRawResource: - return AsyncRawResource(self._client) - - @cached_property - def trace(self) -> AsyncTraceResource: - return AsyncTraceResource(self._client) - @cached_property def move(self) -> AsyncMoveResource: return AsyncMoveResource(self._client) - @cached_property - def reclassify(self) -> AsyncReclassifyResource: - return AsyncReclassifyResource(self._client) - @cached_property def release(self) -> AsyncReleaseResource: return AsyncReleaseResource(self._client) @@ -386,9 +223,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 +234,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 +241,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 +293,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 +304,6 @@ def list( "sender": sender, "start": start, "subject": subject, - "submissions": submissions, }, investigate_list_params.InvestigateListParams, ), @@ -517,62 +311,6 @@ def list( model=InvestigateListResponse, ) - async def get( - self, - postfix_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, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> InvestigateGetResponse: - """ - Retrieves detailed information about a specific email message, including - headers, metadata, and security scan results. - - Args: - account_id: Account 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. - - 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 postfix_id: - raise ValueError(f"Expected a non-empty value for `postfix_id` but received {postfix_id!r}") - return await self._get( - path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}", - account_id=account_id, - postfix_id=postfix_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}, investigate_get_params.InvestigateGetParams - ), - post_parser=ResultWrapper[InvestigateGetResponse]._unwrapper, - ), - cast_to=cast(Type[InvestigateGetResponse], ResultWrapper[InvestigateGetResponse]), - ) - class InvestigateResourceWithRawResponse: def __init__(self, investigate: InvestigateResource) -> None: @@ -581,34 +319,15 @@ def __init__(self, investigate: InvestigateResource) -> None: self.list = to_raw_response_wrapper( investigate.list, ) - self.get = to_raw_response_wrapper( - investigate.get, - ) - - @cached_property - def detections(self) -> DetectionsResourceWithRawResponse: - return DetectionsResourceWithRawResponse(self._investigate.detections) @cached_property def preview(self) -> PreviewResourceWithRawResponse: return PreviewResourceWithRawResponse(self._investigate.preview) - @cached_property - def raw(self) -> RawResourceWithRawResponse: - return RawResourceWithRawResponse(self._investigate.raw) - - @cached_property - def trace(self) -> TraceResourceWithRawResponse: - return TraceResourceWithRawResponse(self._investigate.trace) - @cached_property def move(self) -> MoveResourceWithRawResponse: return MoveResourceWithRawResponse(self._investigate.move) - @cached_property - def reclassify(self) -> ReclassifyResourceWithRawResponse: - return ReclassifyResourceWithRawResponse(self._investigate.reclassify) - @cached_property def release(self) -> ReleaseResourceWithRawResponse: return ReleaseResourceWithRawResponse(self._investigate.release) @@ -621,34 +340,15 @@ def __init__(self, investigate: AsyncInvestigateResource) -> None: self.list = async_to_raw_response_wrapper( investigate.list, ) - self.get = async_to_raw_response_wrapper( - investigate.get, - ) - - @cached_property - def detections(self) -> AsyncDetectionsResourceWithRawResponse: - return AsyncDetectionsResourceWithRawResponse(self._investigate.detections) @cached_property def preview(self) -> AsyncPreviewResourceWithRawResponse: return AsyncPreviewResourceWithRawResponse(self._investigate.preview) - @cached_property - def raw(self) -> AsyncRawResourceWithRawResponse: - return AsyncRawResourceWithRawResponse(self._investigate.raw) - - @cached_property - def trace(self) -> AsyncTraceResourceWithRawResponse: - return AsyncTraceResourceWithRawResponse(self._investigate.trace) - @cached_property def move(self) -> AsyncMoveResourceWithRawResponse: return AsyncMoveResourceWithRawResponse(self._investigate.move) - @cached_property - def reclassify(self) -> AsyncReclassifyResourceWithRawResponse: - return AsyncReclassifyResourceWithRawResponse(self._investigate.reclassify) - @cached_property def release(self) -> AsyncReleaseResourceWithRawResponse: return AsyncReleaseResourceWithRawResponse(self._investigate.release) @@ -661,34 +361,15 @@ def __init__(self, investigate: InvestigateResource) -> None: self.list = to_streamed_response_wrapper( investigate.list, ) - self.get = to_streamed_response_wrapper( - investigate.get, - ) - - @cached_property - def detections(self) -> DetectionsResourceWithStreamingResponse: - return DetectionsResourceWithStreamingResponse(self._investigate.detections) @cached_property def preview(self) -> PreviewResourceWithStreamingResponse: return PreviewResourceWithStreamingResponse(self._investigate.preview) - @cached_property - def raw(self) -> RawResourceWithStreamingResponse: - return RawResourceWithStreamingResponse(self._investigate.raw) - - @cached_property - def trace(self) -> TraceResourceWithStreamingResponse: - return TraceResourceWithStreamingResponse(self._investigate.trace) - @cached_property def move(self) -> MoveResourceWithStreamingResponse: return MoveResourceWithStreamingResponse(self._investigate.move) - @cached_property - def reclassify(self) -> ReclassifyResourceWithStreamingResponse: - return ReclassifyResourceWithStreamingResponse(self._investigate.reclassify) - @cached_property def release(self) -> ReleaseResourceWithStreamingResponse: return ReleaseResourceWithStreamingResponse(self._investigate.release) @@ -701,34 +382,15 @@ def __init__(self, investigate: AsyncInvestigateResource) -> None: self.list = async_to_streamed_response_wrapper( investigate.list, ) - self.get = async_to_streamed_response_wrapper( - investigate.get, - ) - - @cached_property - def detections(self) -> AsyncDetectionsResourceWithStreamingResponse: - return AsyncDetectionsResourceWithStreamingResponse(self._investigate.detections) @cached_property def preview(self) -> AsyncPreviewResourceWithStreamingResponse: return AsyncPreviewResourceWithStreamingResponse(self._investigate.preview) - @cached_property - def raw(self) -> AsyncRawResourceWithStreamingResponse: - return AsyncRawResourceWithStreamingResponse(self._investigate.raw) - - @cached_property - def trace(self) -> AsyncTraceResourceWithStreamingResponse: - return AsyncTraceResourceWithStreamingResponse(self._investigate.trace) - @cached_property def move(self) -> AsyncMoveResourceWithStreamingResponse: return AsyncMoveResourceWithStreamingResponse(self._investigate.move) - @cached_property - def reclassify(self) -> AsyncReclassifyResourceWithStreamingResponse: - return AsyncReclassifyResourceWithStreamingResponse(self._investigate.reclassify) - @cached_property def release(self) -> AsyncReleaseResourceWithStreamingResponse: return AsyncReleaseResourceWithStreamingResponse(self._investigate.release) diff --git a/src/cloudflare/resources/email_security/investigate/move.py b/src/cloudflare/resources/email_security/investigate/move.py index ae07fced89e..52b6b073e5b 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,12 +16,10 @@ 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 +from ....types.email_security.investigate import move_bulk_params from ....types.email_security.investigate.move_bulk_response import MoveBulkResponse -from ....types.email_security.investigate.move_create_response import MoveCreateResponse __all__ = ["MoveResource", "AsyncMoveResource"] @@ -47,64 +44,6 @@ def with_streaming_response(self) -> MoveResourceWithStreamingResponse: """ return MoveResourceWithStreamingResponse(self) - def create( - self, - postfix_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: - """ - Moves a single email message to a different folder or changes its quarantine - status. - - Args: - account_id: Account 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. - - 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 postfix_id: - raise ValueError(f"Expected a non-empty value for `postfix_id` but received {postfix_id!r}") - return self._post( - path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}/move", - account_id=account_id, - postfix_id=postfix_id, - ), - 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, - ), - cast_to=cast(Type[MoveCreateResponse], ResultWrapper[MoveCreateResponse]), - ) - def bulk( self, *, @@ -122,14 +61,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,64 +122,6 @@ def with_streaming_response(self) -> AsyncMoveResourceWithStreamingResponse: """ return AsyncMoveResourceWithStreamingResponse(self) - async def create( - self, - postfix_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: - """ - Moves a single email message to a different folder or changes its quarantine - status. - - Args: - account_id: Account 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. - - 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 postfix_id: - raise ValueError(f"Expected a non-empty value for `postfix_id` but received {postfix_id!r}") - return await self._post( - path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}/move", - account_id=account_id, - postfix_id=postfix_id, - ), - body=await async_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, - ), - cast_to=cast(Type[MoveCreateResponse], ResultWrapper[MoveCreateResponse]), - ) - def bulk( self, *, @@ -255,14 +139,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 @@ -297,9 +184,6 @@ class MoveResourceWithRawResponse: def __init__(self, move: MoveResource) -> None: self._move = move - self.create = to_raw_response_wrapper( - move.create, - ) self.bulk = to_raw_response_wrapper( move.bulk, ) @@ -309,9 +193,6 @@ class AsyncMoveResourceWithRawResponse: def __init__(self, move: AsyncMoveResource) -> None: self._move = move - self.create = async_to_raw_response_wrapper( - move.create, - ) self.bulk = async_to_raw_response_wrapper( move.bulk, ) @@ -321,9 +202,6 @@ class MoveResourceWithStreamingResponse: def __init__(self, move: MoveResource) -> None: self._move = move - self.create = to_streamed_response_wrapper( - move.create, - ) self.bulk = to_streamed_response_wrapper( move.bulk, ) @@ -333,9 +211,6 @@ class AsyncMoveResourceWithStreamingResponse: def __init__(self, move: AsyncMoveResource) -> None: self._move = move - self.create = async_to_streamed_response_wrapper( - move.create, - ) self.bulk = async_to_streamed_response_wrapper( move.bulk, ) diff --git a/src/cloudflare/resources/email_security/investigate/preview.py b/src/cloudflare/resources/email_security/investigate/preview.py index 17fe835b7f4..7f582af0eb9 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 @@ -19,7 +19,6 @@ from ...._wrappers import ResultWrapper from ...._base_client import make_request_options from ....types.email_security.investigate import preview_create_params -from ....types.email_security.investigate.preview_get_response import PreviewGetResponse from ....types.email_security.investigate.preview_create_response import PreviewCreateResponse __all__ = ["PreviewResource", "AsyncPreviewResource"] @@ -50,7 +49,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 +57,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,61 +84,11 @@ 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]), ) - def get( - self, - postfix_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, - ) -> PreviewGetResponse: - """ - Returns a preview of the message body as a base64 encoded PNG image for - non-benign messages. - - Args: - account_id: Account Identifier - - postfix_id: The identifier of the message. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - 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._get( - path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}/preview", - account_id=account_id, - postfix_id=postfix_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[PreviewGetResponse]._unwrapper, - ), - cast_to=cast(Type[PreviewGetResponse], ResultWrapper[PreviewGetResponse]), - ) - class AsyncPreviewResource(AsyncAPIResource): @cached_property @@ -169,7 +115,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 +123,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,63 +150,11 @@ 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]), ) - async def get( - self, - postfix_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, - ) -> PreviewGetResponse: - """ - Returns a preview of the message body as a base64 encoded PNG image for - non-benign messages. - - Args: - account_id: Account Identifier - - postfix_id: The identifier of the message. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - 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._get( - path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}/preview", - account_id=account_id, - postfix_id=postfix_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[PreviewGetResponse]._unwrapper, - ), - cast_to=cast(Type[PreviewGetResponse], ResultWrapper[PreviewGetResponse]), - ) - class PreviewResourceWithRawResponse: def __init__(self, preview: PreviewResource) -> None: @@ -272,9 +163,6 @@ def __init__(self, preview: PreviewResource) -> None: self.create = to_raw_response_wrapper( preview.create, ) - self.get = to_raw_response_wrapper( - preview.get, - ) class AsyncPreviewResourceWithRawResponse: @@ -284,9 +172,6 @@ def __init__(self, preview: AsyncPreviewResource) -> None: self.create = async_to_raw_response_wrapper( preview.create, ) - self.get = async_to_raw_response_wrapper( - preview.get, - ) class PreviewResourceWithStreamingResponse: @@ -296,9 +181,6 @@ def __init__(self, preview: PreviewResource) -> None: self.create = to_streamed_response_wrapper( preview.create, ) - self.get = to_streamed_response_wrapper( - preview.get, - ) class AsyncPreviewResourceWithStreamingResponse: @@ -308,6 +190,3 @@ def __init__(self, preview: AsyncPreviewResource) -> None: self.create = async_to_streamed_response_wrapper( preview.create, ) - self.get = async_to_streamed_response_wrapper( - preview.get, - ) diff --git a/src/cloudflare/resources/email_security/investigate/raw.py b/src/cloudflare/resources/email_security/investigate/raw.py deleted file mode 100644 index 39a8a4b6d39..00000000000 --- a/src/cloudflare/resources/email_security/investigate/raw.py +++ /dev/null @@ -1,197 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Type, cast - -import httpx - -from ...._types import Body, Query, Headers, NotGiven, not_given -from ...._utils import path_template -from ...._compat import cached_property -from ...._resource import SyncAPIResource, AsyncAPIResource -from ...._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) -from ...._wrappers import ResultWrapper -from ...._base_client import make_request_options -from ....types.email_security.investigate.raw_get_response import RawGetResponse - -__all__ = ["RawResource", "AsyncRawResource"] - - -class RawResource(SyncAPIResource): - @cached_property - def with_raw_response(self) -> RawResourceWithRawResponse: - """ - 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 RawResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> RawResourceWithStreamingResponse: - """ - 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 RawResourceWithStreamingResponse(self) - - def get( - self, - postfix_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, - ) -> RawGetResponse: - """ - Returns the raw eml of any non-benign message. - - Args: - account_id: Account Identifier - - postfix_id: The identifier of the message. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - 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._get( - path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}/raw", - account_id=account_id, - postfix_id=postfix_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[RawGetResponse]._unwrapper, - ), - cast_to=cast(Type[RawGetResponse], ResultWrapper[RawGetResponse]), - ) - - -class AsyncRawResource(AsyncAPIResource): - @cached_property - def with_raw_response(self) -> AsyncRawResourceWithRawResponse: - """ - 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 AsyncRawResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncRawResourceWithStreamingResponse: - """ - 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 AsyncRawResourceWithStreamingResponse(self) - - async def get( - self, - postfix_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, - ) -> RawGetResponse: - """ - Returns the raw eml of any non-benign message. - - Args: - account_id: Account Identifier - - postfix_id: The identifier of the message. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - 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._get( - path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}/raw", - account_id=account_id, - postfix_id=postfix_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[RawGetResponse]._unwrapper, - ), - cast_to=cast(Type[RawGetResponse], ResultWrapper[RawGetResponse]), - ) - - -class RawResourceWithRawResponse: - def __init__(self, raw: RawResource) -> None: - self._raw = raw - - self.get = to_raw_response_wrapper( - raw.get, - ) - - -class AsyncRawResourceWithRawResponse: - def __init__(self, raw: AsyncRawResource) -> None: - self._raw = raw - - self.get = async_to_raw_response_wrapper( - raw.get, - ) - - -class RawResourceWithStreamingResponse: - def __init__(self, raw: RawResource) -> None: - self._raw = raw - - self.get = to_streamed_response_wrapper( - raw.get, - ) - - -class AsyncRawResourceWithStreamingResponse: - def __init__(self, raw: AsyncRawResource) -> None: - self._raw = raw - - self.get = async_to_streamed_response_wrapper( - raw.get, - ) diff --git a/src/cloudflare/resources/email_security/investigate/reclassify.py b/src/cloudflare/resources/email_security/investigate/reclassify.py deleted file mode 100644 index 27daa3d7260..00000000000 --- a/src/cloudflare/resources/email_security/investigate/reclassify.py +++ /dev/null @@ -1,238 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Type, cast -from typing_extensions import Literal - -import httpx - -from ...._types import Body, Omit, Query, Headers, NotGiven, 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 ...._base_client import make_request_options -from ....types.email_security.investigate import reclassify_create_params - -__all__ = ["ReclassifyResource", "AsyncReclassifyResource"] - - -class ReclassifyResource(SyncAPIResource): - @cached_property - def with_raw_response(self) -> ReclassifyResourceWithRawResponse: - """ - 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 ReclassifyResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> ReclassifyResourceWithStreamingResponse: - """ - 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 ReclassifyResourceWithStreamingResponse(self) - - def create( - self, - postfix_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. - # 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, - ) -> object: - """ - Submits an email message for reclassification, updating its threat assessment - based on new analysis. - - Args: - account_id: Account 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. - - eml_content: Base64 encoded content of the EML file - - 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 postfix_id: - raise ValueError(f"Expected a non-empty value for `postfix_id` but received {postfix_id!r}") - return self._post( - path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}/reclassify", - account_id=account_id, - postfix_id=postfix_id, - ), - body=maybe_transform( - { - "expected_disposition": expected_disposition, - "eml_content": eml_content, - "escalated_submission_id": escalated_submission_id, - }, - reclassify_create_params.ReclassifyCreateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - 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]), - ) - - -class AsyncReclassifyResource(AsyncAPIResource): - @cached_property - def with_raw_response(self) -> AsyncReclassifyResourceWithRawResponse: - """ - 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 AsyncReclassifyResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncReclassifyResourceWithStreamingResponse: - """ - 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 AsyncReclassifyResourceWithStreamingResponse(self) - - async def create( - self, - postfix_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. - # 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, - ) -> object: - """ - Submits an email message for reclassification, updating its threat assessment - based on new analysis. - - Args: - account_id: Account 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. - - eml_content: Base64 encoded content of the EML file - - 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 postfix_id: - raise ValueError(f"Expected a non-empty value for `postfix_id` but received {postfix_id!r}") - return await self._post( - path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}/reclassify", - account_id=account_id, - postfix_id=postfix_id, - ), - body=await async_maybe_transform( - { - "expected_disposition": expected_disposition, - "eml_content": eml_content, - "escalated_submission_id": escalated_submission_id, - }, - reclassify_create_params.ReclassifyCreateParams, - ), - 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}, reclassify_create_params.ReclassifyCreateParams - ), - post_parser=ResultWrapper[object]._unwrapper, - ), - cast_to=cast(Type[object], ResultWrapper[object]), - ) - - -class ReclassifyResourceWithRawResponse: - def __init__(self, reclassify: ReclassifyResource) -> None: - self._reclassify = reclassify - - self.create = to_raw_response_wrapper( - reclassify.create, - ) - - -class AsyncReclassifyResourceWithRawResponse: - def __init__(self, reclassify: AsyncReclassifyResource) -> None: - self._reclassify = reclassify - - self.create = async_to_raw_response_wrapper( - reclassify.create, - ) - - -class ReclassifyResourceWithStreamingResponse: - def __init__(self, reclassify: ReclassifyResource) -> None: - self._reclassify = reclassify - - self.create = to_streamed_response_wrapper( - reclassify.create, - ) - - -class AsyncReclassifyResourceWithStreamingResponse: - def __init__(self, reclassify: AsyncReclassifyResource) -> None: - self._reclassify = reclassify - - self.create = async_to_streamed_response_wrapper( - reclassify.create, - ) 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 deleted file mode 100644 index bcb66883386..00000000000 --- a/src/cloudflare/resources/email_security/investigate/trace.py +++ /dev/null @@ -1,210 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Type, cast - -import httpx - -from ...._types import Body, Omit, Query, Headers, NotGiven, 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 ...._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"] - - -class TraceResource(SyncAPIResource): - @cached_property - def with_raw_response(self) -> TraceResourceWithRawResponse: - """ - 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 TraceResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> TraceResourceWithStreamingResponse: - """ - 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 TraceResourceWithStreamingResponse(self) - - def get( - self, - postfix_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, - extra_query: Query | None = None, - 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. - - Args: - account_id: Account 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. - - 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 postfix_id: - raise ValueError(f"Expected a non-empty value for `postfix_id` but received {postfix_id!r}") - return self._get( - path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}/trace", - account_id=account_id, - postfix_id=postfix_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]), - ) - - -class AsyncTraceResource(AsyncAPIResource): - @cached_property - def with_raw_response(self) -> AsyncTraceResourceWithRawResponse: - """ - 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 AsyncTraceResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncTraceResourceWithStreamingResponse: - """ - 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 AsyncTraceResourceWithStreamingResponse(self) - - async def get( - self, - postfix_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, - extra_query: Query | None = None, - 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. - - Args: - account_id: Account 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. - - 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 postfix_id: - raise ValueError(f"Expected a non-empty value for `postfix_id` but received {postfix_id!r}") - return await self._get( - path_template( - "/accounts/{account_id}/email-security/investigate/{postfix_id}/trace", - account_id=account_id, - postfix_id=postfix_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]), - ) - - -class TraceResourceWithRawResponse: - def __init__(self, trace: TraceResource) -> None: - self._trace = trace - - self.get = to_raw_response_wrapper( - trace.get, - ) - - -class AsyncTraceResourceWithRawResponse: - def __init__(self, trace: AsyncTraceResource) -> None: - self._trace = trace - - self.get = async_to_raw_response_wrapper( - trace.get, - ) - - -class TraceResourceWithStreamingResponse: - def __init__(self, trace: TraceResource) -> None: - self._trace = trace - - self.get = to_streamed_response_wrapper( - trace.get, - ) - - -class AsyncTraceResourceWithStreamingResponse: - def __init__(self, trace: AsyncTraceResource) -> None: - self._trace = trace - - self.get = async_to_streamed_response_wrapper( - trace.get, - ) 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..76b24c7d633 100644 --- a/src/cloudflare/resources/email_security/settings/impersonation_registry.py +++ b/src/cloudflare/resources/email_security/settings/impersonation_registry.py @@ -20,16 +20,9 @@ from ...._wrappers import ResultWrapper from ....pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray from ...._base_client import AsyncPaginator, make_request_options -from ....types.email_security.settings import ( - impersonation_registry_edit_params, - impersonation_registry_list_params, - impersonation_registry_create_params, -) -from ....types.email_security.settings.impersonation_registry_get_response import ImpersonationRegistryGetResponse -from ....types.email_security.settings.impersonation_registry_edit_response import ImpersonationRegistryEditResponse +from ....types.email_security.settings import impersonation_registry_list_params, impersonation_registry_create_params from ....types.email_security.settings.impersonation_registry_list_response import ImpersonationRegistryListResponse from ....types.email_security.settings.impersonation_registry_create_response import ImpersonationRegistryCreateResponse -from ....types.email_security.settings.impersonation_registry_delete_response import ImpersonationRegistryDeleteResponse __all__ = ["ImpersonationRegistryResource", "AsyncImpersonationRegistryResource"] @@ -61,18 +54,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 +94,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 +107,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 +133,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 @@ -177,149 +186,6 @@ def list( model=ImpersonationRegistryListResponse, ) - def delete( - self, - display_name_id: int, - *, - 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, - ) -> ImpersonationRegistryDeleteResponse: - """ - Removes a display name from impersonation protection monitoring. - - 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._delete( - path_template( - "/accounts/{account_id}/email-security/settings/impersonation_registry/{display_name_id}", - account_id=account_id, - display_name_id=display_name_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[ImpersonationRegistryDeleteResponse]._unwrapper, - ), - cast_to=cast(Type[ImpersonationRegistryDeleteResponse], ResultWrapper[ImpersonationRegistryDeleteResponse]), - ) - - def edit( - self, - display_name_id: int, - *, - account_id: str, - email: Optional[str] | Omit = omit, - is_email_regex: Optional[bool] | Omit = omit, - name: Optional[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, - ) -> ImpersonationRegistryEditResponse: - """ - Updates a display name entry used for impersonation protection. - - 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._patch( - path_template( - "/accounts/{account_id}/email-security/settings/impersonation_registry/{display_name_id}", - account_id=account_id, - display_name_id=display_name_id, - ), - body=maybe_transform( - { - "email": email, - "is_email_regex": is_email_regex, - "name": name, - }, - impersonation_registry_edit_params.ImpersonationRegistryEditParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[ImpersonationRegistryEditResponse]._unwrapper, - ), - cast_to=cast(Type[ImpersonationRegistryEditResponse], ResultWrapper[ImpersonationRegistryEditResponse]), - ) - - def get( - self, - display_name_id: int, - *, - 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, - ) -> ImpersonationRegistryGetResponse: - """ - Retrieves a display name entry used for impersonation protection. - - 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( - path_template( - "/accounts/{account_id}/email-security/settings/impersonation_registry/{display_name_id}", - account_id=account_id, - display_name_id=display_name_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[ImpersonationRegistryGetResponse]._unwrapper, - ), - cast_to=cast(Type[ImpersonationRegistryGetResponse], ResultWrapper[ImpersonationRegistryGetResponse]), - ) - class AsyncImpersonationRegistryResource(AsyncAPIResource): @cached_property @@ -348,18 +214,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 +254,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 +267,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 +295,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 @@ -466,149 +348,6 @@ def list( model=ImpersonationRegistryListResponse, ) - async def delete( - self, - display_name_id: int, - *, - 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, - ) -> ImpersonationRegistryDeleteResponse: - """ - Removes a display name from impersonation protection monitoring. - - 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 await self._delete( - path_template( - "/accounts/{account_id}/email-security/settings/impersonation_registry/{display_name_id}", - account_id=account_id, - display_name_id=display_name_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[ImpersonationRegistryDeleteResponse]._unwrapper, - ), - cast_to=cast(Type[ImpersonationRegistryDeleteResponse], ResultWrapper[ImpersonationRegistryDeleteResponse]), - ) - - async def edit( - self, - display_name_id: int, - *, - account_id: str, - email: Optional[str] | Omit = omit, - is_email_regex: Optional[bool] | Omit = omit, - name: Optional[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, - ) -> ImpersonationRegistryEditResponse: - """ - Updates a display name entry used for impersonation protection. - - 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 await self._patch( - path_template( - "/accounts/{account_id}/email-security/settings/impersonation_registry/{display_name_id}", - account_id=account_id, - display_name_id=display_name_id, - ), - body=await async_maybe_transform( - { - "email": email, - "is_email_regex": is_email_regex, - "name": name, - }, - impersonation_registry_edit_params.ImpersonationRegistryEditParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[ImpersonationRegistryEditResponse]._unwrapper, - ), - cast_to=cast(Type[ImpersonationRegistryEditResponse], ResultWrapper[ImpersonationRegistryEditResponse]), - ) - - async def get( - self, - display_name_id: int, - *, - 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, - ) -> ImpersonationRegistryGetResponse: - """ - Retrieves a display name entry used for impersonation protection. - - 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 await self._get( - path_template( - "/accounts/{account_id}/email-security/settings/impersonation_registry/{display_name_id}", - account_id=account_id, - display_name_id=display_name_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[ImpersonationRegistryGetResponse]._unwrapper, - ), - cast_to=cast(Type[ImpersonationRegistryGetResponse], ResultWrapper[ImpersonationRegistryGetResponse]), - ) - class ImpersonationRegistryResourceWithRawResponse: def __init__(self, impersonation_registry: ImpersonationRegistryResource) -> None: @@ -620,15 +359,6 @@ def __init__(self, impersonation_registry: ImpersonationRegistryResource) -> Non self.list = to_raw_response_wrapper( impersonation_registry.list, ) - self.delete = to_raw_response_wrapper( - impersonation_registry.delete, - ) - self.edit = to_raw_response_wrapper( - impersonation_registry.edit, - ) - self.get = to_raw_response_wrapper( - impersonation_registry.get, - ) class AsyncImpersonationRegistryResourceWithRawResponse: @@ -641,15 +371,6 @@ def __init__(self, impersonation_registry: AsyncImpersonationRegistryResource) - self.list = async_to_raw_response_wrapper( impersonation_registry.list, ) - self.delete = async_to_raw_response_wrapper( - impersonation_registry.delete, - ) - self.edit = async_to_raw_response_wrapper( - impersonation_registry.edit, - ) - self.get = async_to_raw_response_wrapper( - impersonation_registry.get, - ) class ImpersonationRegistryResourceWithStreamingResponse: @@ -662,15 +383,6 @@ def __init__(self, impersonation_registry: ImpersonationRegistryResource) -> Non self.list = to_streamed_response_wrapper( impersonation_registry.list, ) - self.delete = to_streamed_response_wrapper( - impersonation_registry.delete, - ) - self.edit = to_streamed_response_wrapper( - impersonation_registry.edit, - ) - self.get = to_streamed_response_wrapper( - impersonation_registry.get, - ) class AsyncImpersonationRegistryResourceWithStreamingResponse: @@ -683,12 +395,3 @@ def __init__(self, impersonation_registry: AsyncImpersonationRegistryResource) - self.list = async_to_streamed_response_wrapper( impersonation_registry.list, ) - self.delete = async_to_streamed_response_wrapper( - impersonation_registry.delete, - ) - self.edit = async_to_streamed_response_wrapper( - impersonation_registry.edit, - ) - self.get = async_to_streamed_response_wrapper( - impersonation_registry.get, - ) 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/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/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/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/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/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/email_security/__init__.py b/src/cloudflare/types/email_security/__init__.py index 7d6d4897e12..55fad65cd27 100644 --- a/src/cloudflare/types/email_security/__init__.py +++ b/src/cloudflare/types/email_security/__init__.py @@ -2,9 +2,7 @@ from __future__ import annotations -from .investigate_get_params import InvestigateGetParams as InvestigateGetParams from .submission_list_params import SubmissionListParams as SubmissionListParams from .investigate_list_params import InvestigateListParams as InvestigateListParams -from .investigate_get_response import InvestigateGetResponse as InvestigateGetResponse from .submission_list_response import SubmissionListResponse as SubmissionListResponse from .investigate_list_response import InvestigateListResponse as InvestigateListResponse diff --git a/src/cloudflare/types/email_security/investigate/__init__.py b/src/cloudflare/types/email_security/investigate/__init__.py index a86e5ccf9aa..2657a470e2c 100644 --- a/src/cloudflare/types/email_security/investigate/__init__.py +++ b/src/cloudflare/types/email_security/investigate/__init__.py @@ -3,16 +3,8 @@ from __future__ import annotations 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 from .release_bulk_params import ReleaseBulkParams as ReleaseBulkParams -from .move_create_response import MoveCreateResponse as MoveCreateResponse -from .preview_get_response import PreviewGetResponse as PreviewGetResponse from .preview_create_params import PreviewCreateParams as PreviewCreateParams from .release_bulk_response import ReleaseBulkResponse as ReleaseBulkResponse -from .detection_get_response import DetectionGetResponse as DetectionGetResponse from .preview_create_response import PreviewCreateResponse as PreviewCreateResponse -from .reclassify_create_params import ReclassifyCreateParams as ReclassifyCreateParams diff --git a/src/cloudflare/types/email_security/investigate/detection_get_response.py b/src/cloudflare/types/email_security/investigate/detection_get_response.py deleted file mode 100644 index 444f1b45083..00000000000 --- a/src/cloudflare/types/email_security/investigate/detection_get_response.py +++ /dev/null @@ -1,152 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional -from typing_extensions import Literal - -from ...._models import BaseModel - -__all__ = [ - "DetectionGetResponse", - "Attachment", - "Finding", - "Header", - "Link", - "SenderInfo", - "ThreatCategory", - "Validation", -] - - -class Attachment(BaseModel): - size: int - - content_type: Optional[str] = None - - detection: Optional[ - Literal[ - "MALICIOUS", - "MALICIOUS-BEC", - "SUSPICIOUS", - "SPOOF", - "SPAM", - "BULK", - "ENCRYPTED", - "EXTERNAL", - "UNKNOWN", - "NONE", - ] - ] = None - - encrypted: Optional[bool] = None - - name: Optional[str] = None - - -class Finding(BaseModel): - attachment: Optional[str] = None - - detail: Optional[str] = None - - detection: Optional[ - Literal[ - "MALICIOUS", - "MALICIOUS-BEC", - "SUSPICIOUS", - "SPOOF", - "SPAM", - "BULK", - "ENCRYPTED", - "EXTERNAL", - "UNKNOWN", - "NONE", - ] - ] = None - - field: Optional[str] = None - - name: Optional[str] = None - - portion: Optional[str] = None - - reason: Optional[str] = None - - score: Optional[float] = None - - value: Optional[str] = None - - -class Header(BaseModel): - name: str - - value: str - - -class Link(BaseModel): - href: str - - text: Optional[str] = None - - -class SenderInfo(BaseModel): - as_name: Optional[str] = None - """The name of the autonomous system.""" - - as_number: Optional[int] = None - """The number of the autonomous system.""" - - geo: Optional[str] = None - - ip: Optional[str] = None - - pld: Optional[str] = None - - -class ThreatCategory(BaseModel): - id: int - - description: Optional[str] = None - - name: Optional[str] = None - - -class Validation(BaseModel): - comment: Optional[str] = None - - dkim: Optional[Literal["pass", "neutral", "fail", "error", "none"]] = None - - dmarc: Optional[Literal["pass", "neutral", "fail", "error", "none"]] = None - - spf: Optional[Literal["pass", "neutral", "fail", "error", "none"]] = None - - -class DetectionGetResponse(BaseModel): - action: str - - attachments: List[Attachment] - - findings: List[Finding] - - headers: List[Header] - - links: List[Link] - - sender_info: SenderInfo - - threat_categories: List[ThreatCategory] - - validation: Validation - - final_disposition: Optional[ - Literal[ - "MALICIOUS", - "MALICIOUS-BEC", - "SUSPICIOUS", - "SPOOF", - "SPAM", - "BULK", - "ENCRYPTED", - "EXTERNAL", - "UNKNOWN", - "NONE", - ] - ] = None 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 deleted file mode 100644 index c4c977447e5..00000000000 --- a/src/cloudflare/types/email_security/investigate/move_create_params.py +++ /dev/null @@ -1,22 +0,0 @@ -# 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__ = ["MoveCreateParams"] - - -class MoveCreateParams(TypedDict, total=False): - account_id: Required[str] - """Account 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 deleted file mode 100644 index 9dac3bddcd8..00000000000 --- a/src/cloudflare/types/email_security/investigate/move_create_response.py +++ /dev/null @@ -1,33 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional -from datetime import datetime -from typing_extensions import TypeAlias - -from ...._models import BaseModel - -__all__ = ["MoveCreateResponse", "MoveCreateResponseItem"] - - -class MoveCreateResponseItem(BaseModel): - completed_timestamp: datetime - """Deprecated, use `completed_at` instead""" - - item_count: int - - success: bool - - completed_at: Optional[datetime] = None - - destination: Optional[str] = None - - message_id: Optional[str] = None - - operation: Optional[str] = None - - recipient: Optional[str] = None - - status: Optional[str] = None - - -MoveCreateResponse: TypeAlias = List[MoveCreateResponseItem] 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/preview_get_response.py b/src/cloudflare/types/email_security/investigate/preview_get_response.py deleted file mode 100644 index a34a109ac48..00000000000 --- a/src/cloudflare/types/email_security/investigate/preview_get_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__ = ["PreviewGetResponse"] - - -class PreviewGetResponse(BaseModel): - screenshot: str - """A base64 encoded PNG image of the email.""" diff --git a/src/cloudflare/types/email_security/investigate/raw_get_response.py b/src/cloudflare/types/email_security/investigate/raw_get_response.py deleted file mode 100644 index 06544943fca..00000000000 --- a/src/cloudflare/types/email_security/investigate/raw_get_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__ = ["RawGetResponse"] - - -class RawGetResponse(BaseModel): - raw: str - """A UTF-8 encoded eml file of the email.""" diff --git a/src/cloudflare/types/email_security/investigate/reclassify_create_params.py b/src/cloudflare/types/email_security/investigate/reclassify_create_params.py deleted file mode 100644 index 9bc5a664d51..00000000000 --- a/src/cloudflare/types/email_security/investigate/reclassify_create_params.py +++ /dev/null @@ -1,25 +0,0 @@ -# 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__ = ["ReclassifyCreateParams"] - - -class ReclassifyCreateParams(TypedDict, total=False): - account_id: Required[str] - """Account 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""" - - 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 deleted file mode 100644 index 98bce7e2bd2..00000000000 --- a/src/cloudflare/types/email_security/investigate/trace_get_response.py +++ /dev/null @@ -1,42 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional -from datetime import datetime - -from ...._models import BaseModel - -__all__ = ["TraceGetResponse", "Inbound", "InboundLine", "Outbound", "OutboundLine"] - - -class InboundLine(BaseModel): - lineno: int - - message: str - - ts: datetime - - -class Inbound(BaseModel): - lines: Optional[List[InboundLine]] = None - - pending: Optional[bool] = None - - -class OutboundLine(BaseModel): - lineno: int - - message: str - - ts: datetime - - -class Outbound(BaseModel): - lines: Optional[List[OutboundLine]] = None - - pending: Optional[bool] = None - - -class TraceGetResponse(BaseModel): - inbound: Inbound - - outbound: Outbound diff --git a/src/cloudflare/types/email_security/investigate_get_params.py b/src/cloudflare/types/email_security/investigate_get_params.py deleted file mode 100644 index 083388f1cad..00000000000 --- a/src/cloudflare/types/email_security/investigate_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__ = ["InvestigateGetParams"] - - -class InvestigateGetParams(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_get_response.py b/src/cloudflare/types/email_security/investigate_get_response.py deleted file mode 100644 index 1396753de51..00000000000 --- a/src/cloudflare/types/email_security/investigate_get_response.py +++ /dev/null @@ -1,188 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional -from datetime import datetime -from typing_extensions import Literal - -from pydantic import Field as FieldInfo - -from ..._models import BaseModel - -__all__ = ["InvestigateGetResponse", "Properties", "Finding", "Validation"] - - -class Properties(BaseModel): - allowlisted_pattern: Optional[str] = None - - allowlisted_pattern_type: Optional[ - Literal[ - "quarantine_release", - "acceptable_sender", - "allowed_sender", - "allowed_recipient", - "domain_similarity", - "domain_recency", - "managed_acceptable_sender", - "outbound_ndr", - ] - ] = None - - blocklisted_message: Optional[bool] = None - - blocklisted_pattern: Optional[str] = None - - whitelisted_pattern_type: Optional[ - Literal[ - "quarantine_release", - "acceptable_sender", - "allowed_sender", - "allowed_recipient", - "domain_similarity", - "domain_recency", - "managed_acceptable_sender", - "outbound_ndr", - ] - ] = None - - -class Finding(BaseModel): - attachment: Optional[str] = None - - detail: Optional[str] = None - - detection: Optional[ - Literal[ - "MALICIOUS", - "MALICIOUS-BEC", - "SUSPICIOUS", - "SPOOF", - "SPAM", - "BULK", - "ENCRYPTED", - "EXTERNAL", - "UNKNOWN", - "NONE", - ] - ] = None - - field: Optional[str] = None - - name: Optional[str] = None - - portion: Optional[str] = None - - reason: Optional[str] = None - - score: Optional[float] = None - - value: Optional[str] = None - - -class Validation(BaseModel): - comment: Optional[str] = None - - dkim: Optional[Literal["pass", "neutral", "fail", "error", "none"]] = None - - dmarc: Optional[Literal["pass", "neutral", "fail", "error", "none"]] = None - - spf: Optional[Literal["pass", "neutral", "fail", "error", "none"]] = None - - -class InvestigateGetResponse(BaseModel): - id: str - - action_log: object - """Deprecated: use `/investigate/{id}/action_log` instead.""" - - client_recipients: List[str] - - detection_reasons: List[str] - - is_phish_submission: bool - - is_quarantined: bool - - postfix_id: str - """The identifier of the message.""" - - properties: Properties - - ts: str - """Deprecated, use `scanned_at` instead""" - - alert_id: Optional[str] = None - - delivery_mode: Optional[ - Literal[ - "DIRECT", - "BCC", - "JOURNAL", - "REVIEW_SUBMISSION", - "DMARC_UNVERIFIED", - "DMARC_FAILURE_REPORT", - "DMARC_AGGREGATE_REPORT", - "THREAT_INTEL_SUBMISSION", - "SIMULATION_SUBMISSION", - "API", - "RETRO_SCAN", - ] - ] = None - - delivery_status: Optional[ - List[Literal["delivered", "moved", "quarantined", "rejected", "deferred", "bounced", "queued"]] - ] = None - - edf_hash: Optional[str] = None - - envelope_from: Optional[str] = None - - envelope_to: Optional[List[str]] = None - - final_disposition: Optional[ - Literal[ - "MALICIOUS", - "MALICIOUS-BEC", - "SUSPICIOUS", - "SPOOF", - "SPAM", - "BULK", - "ENCRYPTED", - "EXTERNAL", - "UNKNOWN", - "NONE", - ] - ] = None - - findings: Optional[List[Finding]] = None - """Deprecated: use `/investigate/{id}/detections` instead.""" - - from_: Optional[str] = FieldInfo(alias="from", default=None) - - from_name: Optional[str] = None - - htmltext_structure_hash: Optional[str] = None - - message_id: Optional[str] = None - - post_delivery_operations: Optional[List[Literal["PREVIEW", "QUARANTINE_RELEASE", "SUBMISSION", "MOVE"]]] = None - - postfix_id_outbound: Optional[str] = None - - replyto: Optional[str] = None - - scanned_at: Optional[datetime] = None - - sent_at: Optional[datetime] = None - - sent_date: Optional[str] = None - """Deprecated, use `sent_at` instead""" - - subject: Optional[str] = None - - threat_categories: Optional[List[str]] = None - - to: Optional[List[str]] = None - - to_name: Optional[List[str]] = None - - validation: Optional[Validation] = 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..866ff04dbcc 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 @@ -33,15 +32,9 @@ from .trusted_domain_list_response import TrustedDomainListResponse as TrustedDomainListResponse from .trusted_domain_create_response import TrustedDomainCreateResponse as TrustedDomainCreateResponse from .trusted_domain_delete_response import TrustedDomainDeleteResponse as TrustedDomainDeleteResponse -from .impersonation_registry_edit_params import ImpersonationRegistryEditParams as ImpersonationRegistryEditParams from .impersonation_registry_list_params import ImpersonationRegistryListParams as ImpersonationRegistryListParams -from .impersonation_registry_get_response import ImpersonationRegistryGetResponse as ImpersonationRegistryGetResponse from .impersonation_registry_create_params import ImpersonationRegistryCreateParams as ImpersonationRegistryCreateParams -from .impersonation_registry_edit_response import ImpersonationRegistryEditResponse as ImpersonationRegistryEditResponse from .impersonation_registry_list_response import ImpersonationRegistryListResponse as ImpersonationRegistryListResponse from .impersonation_registry_create_response import ( ImpersonationRegistryCreateResponse as ImpersonationRegistryCreateResponse, ) -from .impersonation_registry_delete_response import ( - ImpersonationRegistryDeleteResponse as ImpersonationRegistryDeleteResponse, -) 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 deleted file mode 100644 index ba4913c92f1..00000000000 --- a/src/cloudflare/types/email_security/settings/impersonation_registry_delete_response.py +++ /dev/null @@ -1,9 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from ...._models import BaseModel - -__all__ = ["ImpersonationRegistryDeleteResponse"] - - -class ImpersonationRegistryDeleteResponse(BaseModel): - id: int 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 deleted file mode 100644 index 8dceb0e75f7..00000000000 --- a/src/cloudflare/types/email_security/settings/impersonation_registry_edit_params.py +++ /dev/null @@ -1,19 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Optional -from typing_extensions import Required, TypedDict - -__all__ = ["ImpersonationRegistryEditParams"] - - -class ImpersonationRegistryEditParams(TypedDict, total=False): - account_id: Required[str] - """Account Identifier""" - - email: Optional[str] - - is_email_regex: Optional[bool] - - name: Optional[str] 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 deleted file mode 100644 index 824a0946f7c..00000000000 --- a/src/cloudflare/types/email_security/settings/impersonation_registry_edit_response.py +++ /dev/null @@ -1,32 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import Optional -from datetime import datetime - -from ...._models import BaseModel - -__all__ = ["ImpersonationRegistryEditResponse"] - - -class ImpersonationRegistryEditResponse(BaseModel): - id: int - - created_at: datetime - - email: str - - is_email_regex: bool - - last_modified: datetime - - name: str - - comments: Optional[str] = None - - directory_id: Optional[int] = None - - directory_node_id: Optional[int] = None - - external_directory_node_id: Optional[str] = None - - provenance: Optional[str] = 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 deleted file mode 100644 index 85a8ab50d71..00000000000 --- a/src/cloudflare/types/email_security/settings/impersonation_registry_get_response.py +++ /dev/null @@ -1,32 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import Optional -from datetime import datetime - -from ...._models import BaseModel - -__all__ = ["ImpersonationRegistryGetResponse"] - - -class ImpersonationRegistryGetResponse(BaseModel): - id: int - - created_at: datetime - - email: str - - is_email_regex: bool - - last_modified: datetime - - name: str - - comments: Optional[str] = None - - directory_id: Optional[int] = None - - directory_node_id: Optional[int] = None - - external_directory_node_id: Optional[str] = None - - provenance: Optional[str] = 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/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/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/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/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..b9ef034cc9e 100644 --- a/tests/api_resources/aisearch/namespaces/test_instances.py +++ b/tests/api_resources/aisearch/namespaces/test_instances.py @@ -378,7 +378,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"]) @@ -1213,7 +1213,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..b80c7cb3ba2 100644 --- a/tests/api_resources/aisearch/test_instances.py +++ b/tests/api_resources/aisearch/test_instances.py @@ -351,7 +351,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"]) @@ -1082,7 +1082,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/email_security/investigate/test_detections.py b/tests/api_resources/email_security/investigate/test_detections.py deleted file mode 100644 index b9a5059538d..00000000000 --- a/tests/api_resources/email_security/investigate/test_detections.py +++ /dev/null @@ -1,120 +0,0 @@ -# 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.types.email_security.investigate import DetectionGetResponse - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestDetections: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @parametrize - def test_method_get(self, client: Cloudflare) -> None: - detection = client.email_security.investigate.detections.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - assert_matches_type(DetectionGetResponse, detection, path=["response"]) - - @parametrize - def test_raw_response_get(self, client: Cloudflare) -> None: - response = client.email_security.investigate.detections.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - detection = response.parse() - assert_matches_type(DetectionGetResponse, detection, path=["response"]) - - @parametrize - def test_streaming_response_get(self, client: Cloudflare) -> None: - with client.email_security.investigate.detections.with_streaming_response.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - detection = response.parse() - assert_matches_type(DetectionGetResponse, detection, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @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.email_security.investigate.detections.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): - client.email_security.investigate.detections.with_raw_response.get( - postfix_id="", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - -class TestAsyncDetections: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @parametrize - async def test_method_get(self, async_client: AsyncCloudflare) -> None: - detection = await async_client.email_security.investigate.detections.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - assert_matches_type(DetectionGetResponse, detection, path=["response"]) - - @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", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - detection = await response.parse() - assert_matches_type(DetectionGetResponse, detection, path=["response"]) - - @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", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - detection = await response.parse() - assert_matches_type(DetectionGetResponse, detection, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @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.email_security.investigate.detections.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): - await async_client.email_security.investigate.detections.with_raw_response.get( - postfix_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..bfdd6cc4a7a 100644 --- a/tests/api_resources/email_security/investigate/test_move.py +++ b/tests/api_resources/email_security/investigate/test_move.py @@ -10,10 +10,7 @@ from cloudflare import Cloudflare, AsyncCloudflare from tests.utils import assert_matches_type from cloudflare.pagination import SyncSinglePage, AsyncSinglePage -from cloudflare.types.email_security.investigate import ( - MoveBulkResponse, - MoveCreateResponse, -) +from cloudflare.types.email_security.investigate import MoveBulkResponse base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -21,69 +18,6 @@ class TestMove: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - @parametrize - def test_method_create(self, client: Cloudflare) -> None: - move = client.email_security.investigate.move.create( - postfix_id="4Njp3P0STMz2c02Q", - 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"]) - - @parametrize - def test_raw_response_create(self, client: Cloudflare) -> None: - response = client.email_security.investigate.move.with_raw_response.create( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - destination="Inbox", - ) - - 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"]) - - @parametrize - def test_streaming_response_create(self, client: Cloudflare) -> None: - with client.email_security.investigate.move.with_streaming_response.create( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - destination="Inbox", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - move = response.parse() - assert_matches_type(MoveCreateResponse, move, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @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.email_security.investigate.move.with_raw_response.create( - postfix_id="4Njp3P0STMz2c02Q", - account_id="", - destination="Inbox", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): - client.email_security.investigate.move.with_raw_response.create( - postfix_id="", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - destination="Inbox", - ) - @parametrize def test_method_bulk(self, client: Cloudflare) -> None: move = client.email_security.investigate.move.bulk( @@ -97,7 +31,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"]) @@ -142,69 +76,6 @@ class TestAsyncMove: "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] ) - @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", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - destination="Inbox", - submission=True, - ) - assert_matches_type(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", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - destination="Inbox", - ) - - 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"]) - - @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", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - destination="Inbox", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - move = await response.parse() - assert_matches_type(MoveCreateResponse, move, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @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.email_security.investigate.move.with_raw_response.create( - postfix_id="4Njp3P0STMz2c02Q", - account_id="", - destination="Inbox", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): - await async_client.email_security.investigate.move.with_raw_response.create( - postfix_id="", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - destination="Inbox", - ) - @parametrize async def test_method_bulk(self, async_client: AsyncCloudflare) -> None: move = await async_client.email_security.investigate.move.bulk( @@ -218,7 +89,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..81c32fc4583 100644 --- a/tests/api_resources/email_security/investigate/test_preview.py +++ b/tests/api_resources/email_security/investigate/test_preview.py @@ -9,7 +9,7 @@ from cloudflare import Cloudflare, AsyncCloudflare from tests.utils import assert_matches_type -from cloudflare.types.email_security.investigate import PreviewGetResponse, PreviewCreateResponse +from cloudflare.types.email_security.investigate import PreviewCreateResponse base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -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( @@ -68,54 +59,6 @@ def test_path_params_create(self, client: Cloudflare) -> None: postfix_id="4Njp3P0STMz2c02Q", ) - @parametrize - def test_method_get(self, client: Cloudflare) -> None: - preview = client.email_security.investigate.preview.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - assert_matches_type(PreviewGetResponse, preview, path=["response"]) - - @parametrize - def test_raw_response_get(self, client: Cloudflare) -> None: - response = client.email_security.investigate.preview.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - preview = response.parse() - assert_matches_type(PreviewGetResponse, preview, path=["response"]) - - @parametrize - def test_streaming_response_get(self, client: Cloudflare) -> None: - with client.email_security.investigate.preview.with_streaming_response.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - preview = response.parse() - assert_matches_type(PreviewGetResponse, preview, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @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.email_security.investigate.preview.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): - client.email_security.investigate.preview.with_raw_response.get( - postfix_id="", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - class TestAsyncPreview: parametrize = pytest.mark.parametrize( @@ -130,15 +73,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( @@ -172,51 +106,3 @@ async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: account_id="", postfix_id="4Njp3P0STMz2c02Q", ) - - @parametrize - async def test_method_get(self, async_client: AsyncCloudflare) -> None: - preview = await async_client.email_security.investigate.preview.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - assert_matches_type(PreviewGetResponse, preview, path=["response"]) - - @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", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - preview = await response.parse() - assert_matches_type(PreviewGetResponse, preview, path=["response"]) - - @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", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - preview = await response.parse() - assert_matches_type(PreviewGetResponse, preview, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @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.email_security.investigate.preview.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): - await async_client.email_security.investigate.preview.with_raw_response.get( - postfix_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 deleted file mode 100644 index 204fbb63f6b..00000000000 --- a/tests/api_resources/email_security/investigate/test_raw.py +++ /dev/null @@ -1,120 +0,0 @@ -# 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.types.email_security.investigate import RawGetResponse - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestRaw: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @parametrize - def test_method_get(self, client: Cloudflare) -> None: - raw = client.email_security.investigate.raw.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - assert_matches_type(RawGetResponse, raw, path=["response"]) - - @parametrize - def test_raw_response_get(self, client: Cloudflare) -> None: - response = client.email_security.investigate.raw.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - raw = response.parse() - assert_matches_type(RawGetResponse, raw, path=["response"]) - - @parametrize - def test_streaming_response_get(self, client: Cloudflare) -> None: - with client.email_security.investigate.raw.with_streaming_response.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - raw = response.parse() - assert_matches_type(RawGetResponse, raw, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @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.email_security.investigate.raw.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): - client.email_security.investigate.raw.with_raw_response.get( - postfix_id="", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - -class TestAsyncRaw: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @parametrize - async def test_method_get(self, async_client: AsyncCloudflare) -> None: - raw = await async_client.email_security.investigate.raw.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - assert_matches_type(RawGetResponse, raw, path=["response"]) - - @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", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - raw = await response.parse() - assert_matches_type(RawGetResponse, raw, path=["response"]) - - @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", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - raw = await response.parse() - assert_matches_type(RawGetResponse, raw, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @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.email_security.investigate.raw.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): - await async_client.email_security.investigate.raw.with_raw_response.get( - postfix_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 deleted file mode 100644 index 00739cafa7f..00000000000 --- a/tests/api_resources/email_security/investigate/test_reclassify.py +++ /dev/null @@ -1,153 +0,0 @@ -# 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 - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestReclassify: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @parametrize - def test_method_create(self, client: Cloudflare) -> None: - reclassify = client.email_security.investigate.reclassify.create( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - expected_disposition="NONE", - ) - assert_matches_type(object, reclassify, path=["response"]) - - @parametrize - def test_method_create_with_all_params(self, client: Cloudflare) -> None: - reclassify = client.email_security.investigate.reclassify.create( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - expected_disposition="NONE", - submission=True, - eml_content="eml_content", - escalated_submission_id="escalated_submission_id", - ) - assert_matches_type(object, reclassify, path=["response"]) - - @parametrize - def test_raw_response_create(self, client: Cloudflare) -> None: - response = client.email_security.investigate.reclassify.with_raw_response.create( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - expected_disposition="NONE", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - reclassify = response.parse() - assert_matches_type(object, reclassify, path=["response"]) - - @parametrize - def test_streaming_response_create(self, client: Cloudflare) -> None: - with client.email_security.investigate.reclassify.with_streaming_response.create( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - expected_disposition="NONE", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - reclassify = response.parse() - assert_matches_type(object, reclassify, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @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.email_security.investigate.reclassify.with_raw_response.create( - postfix_id="4Njp3P0STMz2c02Q", - account_id="", - expected_disposition="NONE", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): - client.email_security.investigate.reclassify.with_raw_response.create( - postfix_id="", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - expected_disposition="NONE", - ) - - -class TestAsyncReclassify: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @parametrize - async def test_method_create(self, async_client: AsyncCloudflare) -> None: - reclassify = await async_client.email_security.investigate.reclassify.create( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - expected_disposition="NONE", - ) - assert_matches_type(object, reclassify, path=["response"]) - - @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", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - expected_disposition="NONE", - submission=True, - eml_content="eml_content", - escalated_submission_id="escalated_submission_id", - ) - assert_matches_type(object, reclassify, path=["response"]) - - @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", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - expected_disposition="NONE", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - reclassify = await response.parse() - assert_matches_type(object, reclassify, path=["response"]) - - @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", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - expected_disposition="NONE", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - reclassify = await response.parse() - assert_matches_type(object, reclassify, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @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.email_security.investigate.reclassify.with_raw_response.create( - postfix_id="4Njp3P0STMz2c02Q", - account_id="", - expected_disposition="NONE", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): - await async_client.email_security.investigate.reclassify.with_raw_response.create( - postfix_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 deleted file mode 100644 index d674b118b10..00000000000 --- a/tests/api_resources/email_security/investigate/test_trace.py +++ /dev/null @@ -1,138 +0,0 @@ -# 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.types.email_security.investigate import TraceGetResponse - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestTrace: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @parametrize - def test_method_get(self, client: Cloudflare) -> None: - trace = client.email_security.investigate.trace.get( - postfix_id="4Njp3P0STMz2c02Q", - 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", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - trace = response.parse() - assert_matches_type(TraceGetResponse, trace, path=["response"]) - - @parametrize - def test_streaming_response_get(self, client: Cloudflare) -> None: - with client.email_security.investigate.trace.with_streaming_response.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - trace = response.parse() - assert_matches_type(TraceGetResponse, trace, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @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.email_security.investigate.trace.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): - client.email_security.investigate.trace.with_raw_response.get( - postfix_id="", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - -class TestAsyncTrace: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @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", - 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", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - trace = await response.parse() - assert_matches_type(TraceGetResponse, trace, path=["response"]) - - @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", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - trace = await response.parse() - assert_matches_type(TraceGetResponse, trace, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @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.email_security.investigate.trace.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): - await async_client.email_security.investigate.trace.with_raw_response.get( - postfix_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..7ddd322bd03 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,57 +202,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.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", + ) + @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"]) @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"]) @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"]) @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 @@ -263,41 +269,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.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 +317,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 +345,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 +363,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 +381,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 +399,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 +431,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 +476,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,57 +511,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.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", + ) + @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"]) @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"]) @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"]) @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 @@ -554,41 +578,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.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 +626,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..aa4176eef0b 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,53 +175,59 @@ 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", + ) + @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"]) @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"]) @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"]) @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 @@ -229,41 +235,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.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 +283,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 +307,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 +316,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 +332,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 +346,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 +376,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 +415,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,53 +450,59 @@ 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", + ) + @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"]) @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"]) @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"]) @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 @@ -486,41 +510,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.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 +558,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..a8b5ad03e39 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 @@ -11,11 +11,8 @@ from tests.utils import assert_matches_type from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray from cloudflare.types.email_security.settings import ( - ImpersonationRegistryGetResponse, - ImpersonationRegistryEditResponse, ImpersonationRegistryListResponse, ImpersonationRegistryCreateResponse, - ImpersonationRegistryDeleteResponse, ) base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -28,39 +25,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 +83,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 +104,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", ) @@ -133,143 +147,6 @@ def test_path_params_list(self, client: Cloudflare) -> None: account_id="", ) - @parametrize - def test_method_delete(self, client: Cloudflare) -> None: - impersonation_registry = client.email_security.settings.impersonation_registry.delete( - display_name_id=2403, - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - assert_matches_type(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, - 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"]) - - @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, - 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 cast(Any, response.is_closed) is True - - @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.email_security.settings.impersonation_registry.with_raw_response.delete( - display_name_id=2403, - account_id="", - ) - - @parametrize - def test_method_edit(self, client: Cloudflare) -> None: - impersonation_registry = client.email_security.settings.impersonation_registry.edit( - display_name_id=2403, - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - assert_matches_type(ImpersonationRegistryEditResponse, impersonation_registry, path=["response"]) - - @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", - ) - assert_matches_type(ImpersonationRegistryEditResponse, impersonation_registry, path=["response"]) - - @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, - 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"]) - - @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, - 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 cast(Any, response.is_closed) is True - - @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, - account_id="", - ) - - @parametrize - def test_method_get(self, client: Cloudflare) -> None: - impersonation_registry = client.email_security.settings.impersonation_registry.get( - display_name_id=2403, - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - assert_matches_type(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, - 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"]) - - @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, - 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 cast(Any, response.is_closed) is True - - @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.email_security.settings.impersonation_registry.with_raw_response.get( - display_name_id=2403, - account_id="", - ) - class TestAsyncImpersonationRegistry: parametrize = pytest.mark.parametrize( @@ -280,39 +157,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 +215,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 +236,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", ) @@ -384,140 +278,3 @@ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: await async_client.email_security.settings.impersonation_registry.with_raw_response.list( account_id="", ) - - @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, - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - assert_matches_type(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, - 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"]) - - @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, - 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 cast(Any, response.is_closed) is True - - @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.email_security.settings.impersonation_registry.with_raw_response.delete( - display_name_id=2403, - account_id="", - ) - - @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, - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - assert_matches_type(ImpersonationRegistryEditResponse, impersonation_registry, path=["response"]) - - @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", - ) - assert_matches_type(ImpersonationRegistryEditResponse, impersonation_registry, path=["response"]) - - @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, - 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"]) - - @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, - 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 cast(Any, response.is_closed) is True - - @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, - account_id="", - ) - - @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, - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - assert_matches_type(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, - 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"]) - - @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, - 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 cast(Any, response.is_closed) is True - - @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.email_security.settings.impersonation_registry.with_raw_response.get( - display_name_id=2403, - account_id="", - ) 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..9fef76ec686 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,54 +186,60 @@ 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", + ) + @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"]) @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"]) @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"]) @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 @@ -315,41 +247,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.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 +295,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 +313,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 +321,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 +350,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 +366,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 +382,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 +399,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 +440,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,54 +475,60 @@ 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", + ) + @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"]) @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"]) @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"]) @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 @@ -660,41 +536,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.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 +584,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..c9b051a9e22 100644 --- a/tests/api_resources/email_security/test_investigate.py +++ b/tests/api_resources/email_security/test_investigate.py @@ -11,10 +11,7 @@ from tests.utils import assert_matches_type from cloudflare._utils import parse_datetime from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray -from cloudflare.types.email_security import ( - InvestigateGetResponse, - InvestigateListResponse, -) +from cloudflare.types.email_security import InvestigateListResponse base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -39,19 +36,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"]) @@ -86,63 +81,6 @@ def test_path_params_list(self, client: Cloudflare) -> None: account_id="", ) - @parametrize - def test_method_get(self, client: Cloudflare) -> None: - investigate = client.email_security.investigate.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - assert_matches_type(InvestigateGetResponse, investigate, path=["response"]) - - @parametrize - def test_method_get_with_all_params(self, client: Cloudflare) -> None: - investigate = client.email_security.investigate.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - submission=True, - ) - assert_matches_type(InvestigateGetResponse, investigate, path=["response"]) - - @parametrize - def test_raw_response_get(self, client: Cloudflare) -> None: - response = client.email_security.investigate.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - investigate = response.parse() - assert_matches_type(InvestigateGetResponse, investigate, path=["response"]) - - @parametrize - def test_streaming_response_get(self, client: Cloudflare) -> None: - with client.email_security.investigate.with_streaming_response.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - investigate = response.parse() - assert_matches_type(InvestigateGetResponse, investigate, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @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.email_security.investigate.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): - client.email_security.investigate.with_raw_response.get( - postfix_id="", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - class TestAsyncInvestigate: parametrize = pytest.mark.parametrize( @@ -166,19 +104,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"]) @@ -212,60 +148,3 @@ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: await async_client.email_security.investigate.with_raw_response.list( account_id="", ) - - @parametrize - async def test_method_get(self, async_client: AsyncCloudflare) -> None: - investigate = await async_client.email_security.investigate.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - assert_matches_type(InvestigateGetResponse, investigate, path=["response"]) - - @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", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - submission=True, - ) - assert_matches_type(InvestigateGetResponse, investigate, path=["response"]) - - @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", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - investigate = await response.parse() - assert_matches_type(InvestigateGetResponse, investigate, path=["response"]) - - @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", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - investigate = await response.parse() - assert_matches_type(InvestigateGetResponse, investigate, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @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.email_security.investigate.with_raw_response.get( - postfix_id="4Njp3P0STMz2c02Q", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `postfix_id` but received ''"): - await async_client.email_security.investigate.with_raw_response.get( - postfix_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/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/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..f90311d998a 100644 --- a/tests/api_resources/workers/observability/test_telemetry.py +++ b/tests/api_resources/workers/observability/test_telemetry.py @@ -37,7 +37,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", } ], @@ -134,7 +140,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", } ], @@ -242,7 +254,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", } ], @@ -328,7 +346,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", } ], @@ -425,7 +449,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", } ], @@ -533,7 +563,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", } ],